mirror of
https://github.com/fergalmoran/ladybird.git
synced 2026-01-06 08:36:15 +00:00
LibJS/Bytecode: Flatten bytecode to a contiguous representation
Instead of keeping bytecode as a set of disjoint basic blocks on the
malloc heap, bytecode is now a contiguous sequence of bytes(!)
The transformation happens at the end of Bytecode::Generator::generate()
and the only really hairy part is rerouting jump labels.
This required solving a few problems:
- The interpreter execution loop had to change quite a bit, since we
were storing BasicBlock pointers all over the place, and control
transfer was done by redirecting the interpreter's current block.
- Exception handlers & finalizers are now stored per-bytecode-range
in a side table in Executable.
- The interpreter now has a plain program counter instead of a stream
iterator. This actually makes error stack generation a bit nicer
since we just have to deal with a number instead of reaching into
the iterator.
This yields a 25% performance improvement on this microbenchmark:
for (let i = 0; i < 1_000_000; ++i) { }
But basically everything gets faster. :^)
This commit is contained in:
@@ -26,6 +26,22 @@ void Instruction::destroy(Instruction& instruction)
|
||||
#undef __BYTECODE_OP
|
||||
}
|
||||
|
||||
void Instruction::visit_labels(Function<void(JS::Bytecode::Label&)> visitor)
|
||||
{
|
||||
#define __BYTECODE_OP(op) \
|
||||
case Type::op: \
|
||||
static_cast<Op::op&>(*this).visit_labels_impl(move(visitor)); \
|
||||
return;
|
||||
|
||||
switch (type()) {
|
||||
ENUMERATE_BYTECODE_OPS(__BYTECODE_OP)
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
#undef __BYTECODE_OP
|
||||
}
|
||||
|
||||
UnrealizedSourceRange InstructionStreamIterator::source_range() const
|
||||
{
|
||||
VERIFY(m_executable);
|
||||
|
||||
Reference in New Issue
Block a user