mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-07 00:19:27 +00:00
LibJS/Bytecode: Store labels as basic block index during compilation
Instead of storing a BasicBlock* and forcing the size of Label to be sizeof(BasicBlock*), we now store the basic block index as a u32. This means the final version of the bytecode is able to keep labels at sizeof(u32), shrinking the size of many instructions. :^)
This commit is contained in:
parent
5a08544138
commit
3a73eb99ac
|
@ -10,13 +10,14 @@
|
|||
|
||||
namespace JS::Bytecode {
|
||||
|
||||
NonnullOwnPtr<BasicBlock> BasicBlock::create(String name)
|
||||
NonnullOwnPtr<BasicBlock> BasicBlock::create(u32 index, String name)
|
||||
{
|
||||
return adopt_own(*new BasicBlock(move(name)));
|
||||
return adopt_own(*new BasicBlock(index, move(name)));
|
||||
}
|
||||
|
||||
BasicBlock::BasicBlock(String name)
|
||||
: m_name(move(name))
|
||||
BasicBlock::BasicBlock(u32 index, String name)
|
||||
: m_index(index)
|
||||
, m_name(move(name))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -25,9 +25,11 @@ class BasicBlock {
|
|||
AK_MAKE_NONCOPYABLE(BasicBlock);
|
||||
|
||||
public:
|
||||
static NonnullOwnPtr<BasicBlock> create(String name);
|
||||
static NonnullOwnPtr<BasicBlock> create(u32 index, String name);
|
||||
~BasicBlock();
|
||||
|
||||
u32 index() const { return m_index; }
|
||||
|
||||
ReadonlyBytes instruction_stream() const { return m_buffer.span(); }
|
||||
u8* data() { return m_buffer.data(); }
|
||||
u8 const* data() const { return m_buffer.data(); }
|
||||
|
@ -50,8 +52,9 @@ public:
|
|||
void add_source_map_entry(size_t bytecode_offset, SourceRecord const& source_record) { m_source_map.set(bytecode_offset, source_record); }
|
||||
|
||||
private:
|
||||
explicit BasicBlock(String name);
|
||||
explicit BasicBlock(u32 index, String name);
|
||||
|
||||
u32 m_index { 0 };
|
||||
Vector<u8> m_buffer;
|
||||
BasicBlock const* m_handler { nullptr };
|
||||
BasicBlock const* m_finalizer { nullptr };
|
||||
|
|
|
@ -135,7 +135,7 @@ CodeGenerationErrorOr<NonnullGCPtr<Executable>> Generator::generate(VM& vm, ASTN
|
|||
}
|
||||
for (auto label_offset : label_offsets) {
|
||||
auto& label = *reinterpret_cast<Label*>(bytecode.data() + label_offset);
|
||||
auto* block = &label.block();
|
||||
auto* block = generator.m_root_basic_blocks[label.basic_block_index()].ptr();
|
||||
label.set_address(block_offsets.get(block).value());
|
||||
}
|
||||
|
||||
|
|
|
@ -150,12 +150,12 @@ public:
|
|||
{
|
||||
if (name.is_empty())
|
||||
name = MUST(String::number(m_next_block++));
|
||||
auto block = BasicBlock::create(name);
|
||||
auto block = BasicBlock::create(m_root_basic_blocks.size(), name);
|
||||
if (auto const* context = m_current_unwind_context) {
|
||||
if (context->handler().has_value())
|
||||
block->set_handler(context->handler().value().block());
|
||||
block->set_handler(*m_root_basic_blocks[context->handler().value().basic_block_index()]);
|
||||
if (m_current_unwind_context->finalizer().has_value())
|
||||
block->set_finalizer(context->finalizer().value().block());
|
||||
block->set_finalizer(*m_root_basic_blocks[context->finalizer().value().basic_block_index()]);
|
||||
}
|
||||
m_root_basic_blocks.append(move(block));
|
||||
return *m_root_basic_blocks.last();
|
||||
|
|
17
Userland/Libraries/LibJS/Bytecode/Label.cpp
Normal file
17
Userland/Libraries/LibJS/Bytecode/Label.cpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Bytecode/BasicBlock.h>
|
||||
#include <LibJS/Bytecode/Label.h>
|
||||
|
||||
namespace JS::Bytecode {
|
||||
|
||||
Label::Label(Bytecode::BasicBlock const& basic_block)
|
||||
: m_address_or_basic_block_index(basic_block.index())
|
||||
{
|
||||
}
|
||||
|
||||
}
|
|
@ -14,27 +14,23 @@ class BasicBlock;
|
|||
|
||||
class Label {
|
||||
public:
|
||||
explicit Label(BasicBlock const& block)
|
||||
: m_block(&block)
|
||||
explicit Label(BasicBlock const&);
|
||||
|
||||
explicit Label(u32 basic_block_index)
|
||||
: m_address_or_basic_block_index(basic_block_index)
|
||||
{
|
||||
}
|
||||
|
||||
// Used while compiling.
|
||||
BasicBlock const& block() const { return *m_block; }
|
||||
size_t basic_block_index() const { return m_address_or_basic_block_index; }
|
||||
|
||||
// Used after compiling.
|
||||
size_t address() const { return m_address; }
|
||||
size_t address() const { return m_address_or_basic_block_index; }
|
||||
|
||||
void set_address(size_t address) { m_address = address; }
|
||||
void set_address(size_t address) { m_address_or_basic_block_index = address; }
|
||||
|
||||
private:
|
||||
union {
|
||||
// Relevant while compiling.
|
||||
BasicBlock const* m_block { nullptr };
|
||||
|
||||
// Relevant after compiling.
|
||||
size_t m_address;
|
||||
};
|
||||
u32 m_address_or_basic_block_index { 0 };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ set(SOURCES
|
|||
Bytecode/IdentifierTable.cpp
|
||||
Bytecode/Instruction.cpp
|
||||
Bytecode/Interpreter.cpp
|
||||
Bytecode/Label.cpp
|
||||
Bytecode/RegexTable.cpp
|
||||
Bytecode/StringTable.cpp
|
||||
Console.cpp
|
||||
|
|
Loading…
Reference in a new issue