mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-08 17:19:13 +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
Notes:
sideshowbarker
2024-07-16 21:42:29 +09:00
Author: https://github.com/awesomekling
Commit: 3a73eb99ac
Pull-request: https://github.com/SerenityOS/serenity/pull/24240
Reviewed-by: https://github.com/Hendiadyoin1
Reviewed-by: https://github.com/trflynn89 ✅
7 changed files with 40 additions and 22 deletions
|
@ -10,13 +10,14 @@
|
||||||
|
|
||||||
namespace JS::Bytecode {
|
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)
|
BasicBlock::BasicBlock(u32 index, String name)
|
||||||
: m_name(move(name))
|
: m_index(index)
|
||||||
|
, m_name(move(name))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,11 @@ class BasicBlock {
|
||||||
AK_MAKE_NONCOPYABLE(BasicBlock);
|
AK_MAKE_NONCOPYABLE(BasicBlock);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static NonnullOwnPtr<BasicBlock> create(String name);
|
static NonnullOwnPtr<BasicBlock> create(u32 index, String name);
|
||||||
~BasicBlock();
|
~BasicBlock();
|
||||||
|
|
||||||
|
u32 index() const { return m_index; }
|
||||||
|
|
||||||
ReadonlyBytes instruction_stream() const { return m_buffer.span(); }
|
ReadonlyBytes instruction_stream() const { return m_buffer.span(); }
|
||||||
u8* data() { return m_buffer.data(); }
|
u8* data() { return m_buffer.data(); }
|
||||||
u8 const* data() const { 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); }
|
void add_source_map_entry(size_t bytecode_offset, SourceRecord const& source_record) { m_source_map.set(bytecode_offset, source_record); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit BasicBlock(String name);
|
explicit BasicBlock(u32 index, String name);
|
||||||
|
|
||||||
|
u32 m_index { 0 };
|
||||||
Vector<u8> m_buffer;
|
Vector<u8> m_buffer;
|
||||||
BasicBlock const* m_handler { nullptr };
|
BasicBlock const* m_handler { nullptr };
|
||||||
BasicBlock const* m_finalizer { nullptr };
|
BasicBlock const* m_finalizer { nullptr };
|
||||||
|
|
|
@ -135,7 +135,7 @@ CodeGenerationErrorOr<NonnullGCPtr<Executable>> Generator::generate(VM& vm, ASTN
|
||||||
}
|
}
|
||||||
for (auto label_offset : label_offsets) {
|
for (auto label_offset : label_offsets) {
|
||||||
auto& label = *reinterpret_cast<Label*>(bytecode.data() + label_offset);
|
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());
|
label.set_address(block_offsets.get(block).value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,12 +150,12 @@ public:
|
||||||
{
|
{
|
||||||
if (name.is_empty())
|
if (name.is_empty())
|
||||||
name = MUST(String::number(m_next_block++));
|
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 (auto const* context = m_current_unwind_context) {
|
||||||
if (context->handler().has_value())
|
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())
|
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));
|
m_root_basic_blocks.append(move(block));
|
||||||
return *m_root_basic_blocks.last();
|
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 {
|
class Label {
|
||||||
public:
|
public:
|
||||||
explicit Label(BasicBlock const& block)
|
explicit Label(BasicBlock const&);
|
||||||
: m_block(&block)
|
|
||||||
|
explicit Label(u32 basic_block_index)
|
||||||
|
: m_address_or_basic_block_index(basic_block_index)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used while compiling.
|
// 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.
|
// 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:
|
private:
|
||||||
union {
|
u32 m_address_or_basic_block_index { 0 };
|
||||||
// Relevant while compiling.
|
|
||||||
BasicBlock const* m_block { nullptr };
|
|
||||||
|
|
||||||
// Relevant after compiling.
|
|
||||||
size_t m_address;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ set(SOURCES
|
||||||
Bytecode/IdentifierTable.cpp
|
Bytecode/IdentifierTable.cpp
|
||||||
Bytecode/Instruction.cpp
|
Bytecode/Instruction.cpp
|
||||||
Bytecode/Interpreter.cpp
|
Bytecode/Interpreter.cpp
|
||||||
|
Bytecode/Label.cpp
|
||||||
Bytecode/RegexTable.cpp
|
Bytecode/RegexTable.cpp
|
||||||
Bytecode/StringTable.cpp
|
Bytecode/StringTable.cpp
|
||||||
Console.cpp
|
Console.cpp
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue