mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 18:57:45 +00:00
LibJS: Devirtualize and pack the bytecode stream :^)
This patch changes the LibJS bytecode to be a stream of instructions packed one-after-the-other in contiguous memory, instead of a vector of OwnPtr<Instruction>. This should be a lot more cache-friendly. :^) Instructions are also devirtualized and instead have a type field using a new Instruction::Type enum. To iterate over a bytecode stream, one must now use Bytecode::InstructionStreamIterator.
This commit is contained in:
parent
845f2826aa
commit
e7d69c5d3c
11 changed files with 284 additions and 110 deletions
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <LibJS/Bytecode/Label.h>
|
||||
#include <LibJS/Bytecode/Register.h>
|
||||
#include <LibJS/Forward.h>
|
||||
|
||||
namespace JS::Bytecode {
|
||||
|
@ -21,10 +22,19 @@ public:
|
|||
template<typename OpType, typename... Args>
|
||||
OpType& emit(Args&&... args)
|
||||
{
|
||||
auto instruction = make<OpType>(forward<Args>(args)...);
|
||||
auto* ptr = instruction.ptr();
|
||||
append(move(instruction));
|
||||
return *ptr;
|
||||
void* slot = next_slot();
|
||||
grow(sizeof(OpType));
|
||||
new (slot) OpType(forward<Args>(args)...);
|
||||
return *static_cast<OpType*>(slot);
|
||||
}
|
||||
|
||||
template<typename OpType, typename... Args>
|
||||
OpType& emit_with_extra_register_slots(size_t extra_register_slots, Args&&... args)
|
||||
{
|
||||
void* slot = next_slot();
|
||||
grow(sizeof(OpType) + extra_register_slots * sizeof(Register));
|
||||
new (slot) OpType(forward<Args>(args)...);
|
||||
return *static_cast<OpType*>(slot);
|
||||
}
|
||||
|
||||
Label make_label() const;
|
||||
|
@ -38,7 +48,8 @@ private:
|
|||
Generator();
|
||||
~Generator();
|
||||
|
||||
void append(NonnullOwnPtr<Instruction>);
|
||||
void grow(size_t);
|
||||
void* next_slot();
|
||||
|
||||
OwnPtr<Block> m_block;
|
||||
u32 m_next_register { 1 };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue