mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 08:58:11 +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
|
@ -11,6 +11,40 @@
|
|||
#include <LibJS/Runtime/ScriptFunction.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS::Bytecode {
|
||||
|
||||
void Instruction::execute(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
#define __BYTECODE_OP(op) \
|
||||
case Instruction::Type::op: \
|
||||
return static_cast<Bytecode::Op::op const&>(*this).execute(interpreter);
|
||||
|
||||
switch (type()) {
|
||||
ENUMERATE_BYTECODE_OPS(__BYTECODE_OP)
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
#undef __BYTECODE_OP
|
||||
}
|
||||
|
||||
String Instruction::to_string() const
|
||||
{
|
||||
#define __BYTECODE_OP(op) \
|
||||
case Instruction::Type::op: \
|
||||
return static_cast<Bytecode::Op::op const&>(*this).to_string();
|
||||
|
||||
switch (type()) {
|
||||
ENUMERATE_BYTECODE_OPS(__BYTECODE_OP)
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
#undef __BYTECODE_OP
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace JS::Bytecode::Op {
|
||||
|
||||
void Load::execute(Bytecode::Interpreter& interpreter) const
|
||||
|
@ -108,12 +142,12 @@ void Call::execute(Bytecode::Interpreter& interpreter) const
|
|||
|
||||
Value return_value;
|
||||
|
||||
if (m_arguments.is_empty()) {
|
||||
if (m_argument_count == 0) {
|
||||
return_value = interpreter.vm().call(function, this_value);
|
||||
} else {
|
||||
MarkedValueList argument_values { interpreter.vm().heap() };
|
||||
for (auto& arg : m_arguments) {
|
||||
argument_values.append(interpreter.reg(arg));
|
||||
for (size_t i = 0; i < m_argument_count; ++i) {
|
||||
argument_values.append(interpreter.reg(m_arguments[i]));
|
||||
}
|
||||
return_value = interpreter.vm().call(function, this_value, move(argument_values));
|
||||
}
|
||||
|
@ -227,11 +261,11 @@ String Call::to_string() const
|
|||
{
|
||||
StringBuilder builder;
|
||||
builder.appendff("Call dst:{}, callee:{}, this:{}", m_dst, m_callee, m_this_value);
|
||||
if (!m_arguments.is_empty()) {
|
||||
if (m_argument_count != 0) {
|
||||
builder.append(", arguments:[");
|
||||
for (size_t i = 0; i < m_arguments.size(); ++i) {
|
||||
for (size_t i = 0; i < m_argument_count; ++i) {
|
||||
builder.appendff("{}", m_arguments[i]);
|
||||
if (i != m_arguments.size() - 1)
|
||||
if (i != m_argument_count - 1)
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append(']');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue