mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-22 01:08:56 +00:00
LibWasm: Avoid allocations for the label stack as much as possible
Namely, find an upper bound at validation time so we can allocate the space when entering the frame. Also drop labels at once instead of popping them off one at a time now that we're using a Vector.
This commit is contained in:
parent
191499696b
commit
f7bdc596b4
Notes:
github-actions[bot]
2025-08-26 13:22:01 +00:00
Author: https://github.com/alimpfard
Commit: f7bdc596b4
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5784
5 changed files with 19 additions and 6 deletions
|
@ -267,8 +267,7 @@ void BytecodeInterpreter::interpret_impl(Configuration& configuration, Expressio
|
|||
RUN_NEXT_INSTRUCTION(CouldHaveChangedIP::Yes);
|
||||
}
|
||||
case Instructions::return_.value(): {
|
||||
while (configuration.label_stack().size() - 1 != configuration.frame().label_index())
|
||||
configuration.label_stack().take_last();
|
||||
configuration.label_stack().shrink(configuration.frame().label_index() + 1, true);
|
||||
configuration.ip() = max_ip_value;
|
||||
RUN_NEXT_INSTRUCTION(CouldHaveChangedIP::Yes);
|
||||
}
|
||||
|
@ -2233,8 +2232,8 @@ void BytecodeInterpreter::interpret_impl(Configuration& configuration, Expressio
|
|||
void BytecodeInterpreter::branch_to_label(Configuration& configuration, LabelIndex index)
|
||||
{
|
||||
dbgln_if(WASM_TRACE_DEBUG, "Branch to label with index {}...", index.value());
|
||||
for (size_t i = 0; i < index.value(); ++i)
|
||||
configuration.label_stack().take_last();
|
||||
auto& label_stack = configuration.label_stack();
|
||||
label_stack.shrink(label_stack.size() - index.value(), true);
|
||||
auto label = configuration.label_stack().last();
|
||||
dbgln_if(WASM_TRACE_DEBUG, "...which is actually IP {}, and has {} result(s)", label.continuation().value(), label.arity());
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@ public:
|
|||
frame.label_index() = m_label_stack.size();
|
||||
if (auto hint = frame.expression().stack_usage_hint(); hint.has_value())
|
||||
m_value_stack.ensure_capacity(*hint + m_value_stack.size());
|
||||
if (auto hint = frame.expression().frame_usage_hint(); hint.has_value())
|
||||
m_label_stack.ensure_capacity(*hint + m_label_stack.size());
|
||||
m_frame_stack.append(move(frame));
|
||||
m_label_stack.append(label);
|
||||
m_locals_base = m_frame_stack.unchecked_last().locals().data();
|
||||
|
@ -120,7 +122,7 @@ public:
|
|||
private:
|
||||
Store& m_store;
|
||||
Vector<Value, 64, FastLastAccess::Yes> m_value_stack;
|
||||
DoublyLinkedList<Label, 128> m_label_stack;
|
||||
Vector<Label, 64> m_label_stack;
|
||||
DoublyLinkedList<Frame, 128> m_frame_stack;
|
||||
size_t m_depth { 0 };
|
||||
u64 m_ip { 0 };
|
||||
|
|
|
@ -271,6 +271,7 @@ ErrorOr<void, ValidationError> Validator::validate(CodeSection const& section)
|
|||
}
|
||||
|
||||
function_validator.m_frames.empend(function_type, FrameKind::Function, (size_t)0);
|
||||
function_validator.m_max_frame_size = max(function_validator.m_max_frame_size, function_validator.m_frames.size());
|
||||
|
||||
auto results = TRY(function_validator.validate(function.body(), function_type.results()));
|
||||
if (results.result_types.size() != function_type.results().size())
|
||||
|
@ -1971,6 +1972,7 @@ VALIDATE_INSTRUCTION(block)
|
|||
TRY(stack.take(parameters[parameters.size() - i]));
|
||||
|
||||
m_frames.empend(block_type, FrameKind::Block, stack.size());
|
||||
m_max_frame_size = max(m_max_frame_size, m_frames.size());
|
||||
for (auto& parameter : parameters)
|
||||
stack.append(parameter);
|
||||
|
||||
|
@ -1987,6 +1989,7 @@ VALIDATE_INSTRUCTION(loop)
|
|||
TRY(stack.take(parameters[parameters.size() - i]));
|
||||
|
||||
m_frames.empend(block_type, FrameKind::Loop, stack.size());
|
||||
m_max_frame_size = max(m_max_frame_size, m_frames.size());
|
||||
for (auto& parameter : parameters)
|
||||
stack.append(parameter);
|
||||
|
||||
|
@ -2007,6 +2010,7 @@ VALIDATE_INSTRUCTION(if_)
|
|||
TRY(stack.take(parameters[parameters.size() - i]));
|
||||
|
||||
m_frames.empend(block_type, FrameKind::If, stack.size());
|
||||
m_max_frame_size = max(m_max_frame_size, m_frames.size());
|
||||
for (auto& parameter : parameters)
|
||||
stack.append(parameter);
|
||||
|
||||
|
@ -3734,9 +3738,12 @@ ErrorOr<Validator::ExpressionTypeResult, ValidationError> Validator::validate(Ex
|
|||
for (auto& type : result_types)
|
||||
stack.append(type);
|
||||
m_frames.take_last();
|
||||
VERIFY(m_frames.is_empty());
|
||||
|
||||
expression.set_stack_usage_hint(stack.max_known_size());
|
||||
expression.set_frame_usage_hint(m_max_frame_size);
|
||||
|
||||
VERIFY(m_frames.is_empty());
|
||||
m_max_frame_size = 0;
|
||||
|
||||
// Now that we're in happy land, try to compile the expression down to a list of labels to help dispatch.
|
||||
expression.compiled_instructions = try_compile_instructions(expression, m_context.functions.span());
|
||||
|
|
|
@ -361,6 +361,7 @@ private:
|
|||
|
||||
Context m_context;
|
||||
Vector<Frame> m_frames;
|
||||
size_t m_max_frame_size { 0 };
|
||||
COWVector<GlobalType> m_globals_without_internal_globals;
|
||||
};
|
||||
|
||||
|
|
|
@ -758,11 +758,15 @@ public:
|
|||
|
||||
void set_stack_usage_hint(size_t value) const { m_stack_usage_hint = value; }
|
||||
auto stack_usage_hint() const { return m_stack_usage_hint; }
|
||||
void set_frame_usage_hint(size_t value) const { m_frame_usage_hint = value; }
|
||||
auto frame_usage_hint() const { return m_frame_usage_hint; }
|
||||
|
||||
mutable CompiledInstructions compiled_instructions;
|
||||
|
||||
private:
|
||||
Vector<Instruction> m_instructions;
|
||||
mutable Optional<size_t> m_stack_usage_hint;
|
||||
mutable Optional<size_t> m_frame_usage_hint;
|
||||
};
|
||||
|
||||
class GlobalSection {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue