1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 07:47:37 +00:00

LibJS/JIT: Provide source location information for JIT code

This works by walking a backtrace until the currently executing
native executable is found, and then mapping the native address
to its bytecode instruction.
This commit is contained in:
Simon Wanner 2023-10-30 22:06:27 +01:00 committed by Andreas Kling
parent 112eadc863
commit fb7b4b9c59
8 changed files with 59 additions and 6 deletions

View file

@ -8,6 +8,7 @@
#include <LibJS/Bytecode/Executable.h>
#include <LibJS/Bytecode/RegexTable.h>
#include <LibJS/JIT/Compiler.h>
#include <LibJS/JIT/NativeExecutable.h>
#include <LibJS/SourceCode.h>
namespace JS::Bytecode {

View file

@ -15,9 +15,12 @@
#include <LibJS/Bytecode/Label.h>
#include <LibJS/Bytecode/StringTable.h>
#include <LibJS/Forward.h>
#include <LibJS/JIT/NativeExecutable.h>
#include <LibJS/Runtime/EnvironmentCoordinate.h>
namespace JS::JIT {
class NativeExecutable;
}
namespace JS::Bytecode {
struct PropertyLookupCache {
@ -70,6 +73,7 @@ public:
void dump() const;
JIT::NativeExecutable const* get_or_create_native_executable();
JIT::NativeExecutable const* native_executable() const { return m_native_executable; }
private:
OwnPtr<JIT::NativeExecutable> m_native_executable;

View file

@ -157,10 +157,10 @@ private:
class InstructionStreamIterator {
public:
InstructionStreamIterator(ReadonlyBytes bytes, Executable const* executable = nullptr)
InstructionStreamIterator(ReadonlyBytes bytes, Executable const* executable = nullptr, size_t offset = 0)
: m_begin(bytes.data())
, m_end(bytes.data() + bytes.size())
, m_ptr(bytes.data())
, m_ptr(bytes.data() + offset)
, m_executable(executable)
{
}

View file

@ -16,6 +16,7 @@
#include <LibJS/Bytecode/Label.h>
#include <LibJS/Bytecode/Op.h>
#include <LibJS/JIT/Compiler.h>
#include <LibJS/JIT/NativeExecutable.h>
#include <LibJS/Runtime/AbstractOperations.h>
#include <LibJS/Runtime/Array.h>
#include <LibJS/Runtime/BigInt.h>
@ -55,6 +56,13 @@ void Interpreter::visit_edges(Cell::Visitor& visitor)
}
}
Optional<InstructionStreamIterator const&> Interpreter::instruction_stream_iterator() const
{
if (m_current_executable && m_current_executable->native_executable())
return m_current_executable->native_executable()->instruction_stream_iterator(*m_current_executable);
return m_pc;
}
// 16.1.6 ScriptEvaluation ( scriptRecord ), https://tc39.es/ecma262/#sec-runtime-semantics-scriptevaluation
ThrowCompletionOr<Value> Interpreter::run(Script& script_record, JS::GCPtr<Environment> lexical_environment_override)
{

View file

@ -6,6 +6,7 @@
#pragma once
#include <LibJS/Bytecode/Executable.h>
#include <LibJS/Bytecode/Label.h>
#include <LibJS/Bytecode/Register.h>
#include <LibJS/Forward.h>
@ -77,7 +78,7 @@ public:
Executable& current_executable() { return *m_current_executable; }
Executable const& current_executable() const { return *m_current_executable; }
BasicBlock const& current_block() const { return *m_current_block; }
auto& instruction_stream_iterator() const { return m_pc; }
Optional<InstructionStreamIterator const&> instruction_stream_iterator() const;
void visit_edges(Cell::Visitor&);