mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2026-06-24 18:30:23 +00:00
LibJS: Move bytecode block counting to Rust
Use the Rust bytecode dumper's basic block collection logic for the metadata block count. This removes the last C++ bytecode label walk and lets us delete the generated C++ label and operand visitor helpers.
This commit is contained in:
parent
984d3033e9
commit
e5bcffc3d5
Notes:
github-actions[bot]
2026-06-15 00:42:59 +00:00
Author: https://github.com/awesomekling
Commit: e5bcffc3d5
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/10103
8 changed files with 47 additions and 188 deletions
|
|
@ -7,7 +7,6 @@
|
|||
#include <AK/BinarySearch.h>
|
||||
#include <AK/NeverDestroyed.h>
|
||||
#include <AK/NumericLimits.h>
|
||||
#include <AK/QuickSort.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <LibGC/Heap.h>
|
||||
#include <LibGC/HeapBlock.h>
|
||||
|
|
@ -373,71 +372,6 @@ static void dump_header(StringBuilder& output, Executable const& executable)
|
|||
output.append('\n');
|
||||
}
|
||||
|
||||
static bool instruction_is_terminator(Instruction const& instruction)
|
||||
{
|
||||
#define __BYTECODE_OP(op) \
|
||||
case Instruction::Type::op: \
|
||||
return Op::op::IsTerminator;
|
||||
|
||||
switch (instruction.type()) {
|
||||
ENUMERATE_BYTECODE_OPS(__BYTECODE_OP)
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
#undef __BYTECODE_OP
|
||||
}
|
||||
|
||||
static Vector<u32> collect_basic_block_start_offsets(Executable const& executable)
|
||||
{
|
||||
Vector<u32> offsets;
|
||||
|
||||
auto append_offset = [&](size_t offset) {
|
||||
VERIFY(offset <= NumericLimits<u32>::max());
|
||||
auto offset32 = static_cast<u32>(offset);
|
||||
if (!offsets.contains_slow(offset32))
|
||||
offsets.append(offset32);
|
||||
};
|
||||
auto append_instruction_offset = [&](size_t offset) {
|
||||
if (offset < executable.bytecode.size())
|
||||
append_offset(offset);
|
||||
};
|
||||
|
||||
append_offset(0);
|
||||
|
||||
for (InstructionStreamIterator it(executable.bytecode, &executable); !it.at_end(); ++it) {
|
||||
auto const& instruction = *it;
|
||||
auto next_offset = it.offset() + instruction.length();
|
||||
|
||||
const_cast<Instruction&>(instruction).visit_labels([&](Label& label) {
|
||||
append_offset(label.address());
|
||||
});
|
||||
|
||||
if (instruction_is_terminator(instruction) && next_offset < executable.bytecode.size())
|
||||
append_offset(next_offset);
|
||||
}
|
||||
|
||||
for (auto const& handler : executable.exception_handlers) {
|
||||
append_instruction_offset(handler.start_offset);
|
||||
append_instruction_offset(handler.end_offset);
|
||||
append_instruction_offset(handler.handler_offset);
|
||||
}
|
||||
|
||||
quick_sort(offsets);
|
||||
return offsets;
|
||||
}
|
||||
|
||||
Optional<size_t> Executable::basic_block_index_for_offset(size_t offset) const
|
||||
{
|
||||
VERIFY(offset <= NumericLimits<u32>::max());
|
||||
auto basic_block_start_offsets = collect_basic_block_start_offsets(*this);
|
||||
|
||||
size_t index = 0;
|
||||
if (binary_search(basic_block_start_offsets, static_cast<u32>(offset), &index))
|
||||
return index;
|
||||
return {};
|
||||
}
|
||||
|
||||
static void dump_metadata(StringBuilder& output, Executable const& executable)
|
||||
{
|
||||
auto constexpr green = "\033[32m"sv;
|
||||
|
|
@ -447,7 +381,7 @@ static void dump_metadata(StringBuilder& output, Executable const& executable)
|
|||
auto constexpr reset = "\033[0m"sv;
|
||||
|
||||
output.appendff(" {}Registers{}: {}\n", green, reset, executable.number_of_registers);
|
||||
output.appendff(" {}Blocks{}: {}\n", green, reset, collect_basic_block_start_offsets(executable).size());
|
||||
output.appendff(" {}Blocks{}: {}\n", green, reset, RustIntegration::count_bytecode_basic_blocks(executable));
|
||||
|
||||
if (!executable.local_variable_names.is_empty()) {
|
||||
output.appendff(" {}Locals{}: ", green, reset);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue