Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Unified Diff: src/wasm/wasm-interpreter.cc

Issue 2096863003: [wasm] prototype for breakpoint support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@extend-script-functionality
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/wasm/wasm-interpreter.h ('k') | src/wasm/wasm-module.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/wasm/wasm-interpreter.cc
diff --git a/src/wasm/wasm-interpreter.cc b/src/wasm/wasm-interpreter.cc
index a88fa93f06df0fc95d18d60594744981546d90f6..9eaff7492803462e82ef550667cc74ec4cd699ad 100644
--- a/src/wasm/wasm-interpreter.cc
+++ b/src/wasm/wasm-interpreter.cc
@@ -851,17 +851,29 @@ class ControlTransfers : public ZoneObject {
// Code and metadata needed to execute a function.
struct InterpreterCode {
- const WasmFunction* function; // wasm function
- AstLocalDecls locals; // local declarations
- const byte* orig_start; // start of original code
- const byte* orig_end; // end of original code
- byte* start; // start of (maybe altered) code
- byte* end; // end of (maybe altered) code
- ControlTransfers* targets; // helper for control flow.
+ const WasmFunction* function; // wasm function
+ AstLocalDecls locals; // local declarations
+ const byte* orig_start; // start of original code
+ const byte* orig_end; // end of original code
+ byte* start; // start of (maybe altered) code
+ byte* end; // end of (maybe altered) code
+ ControlTransfers* targets; // helper for control flow.
+ BoolVector instruction_offsets; // valid instruction offsets
const byte* at(pc_t pc) { return start + pc; }
};
+namespace {
+
+pc_t FindPreviousInstruction(InterpreterCode* code, pc_t pc) {
+ BoolVector& offsets = code->instruction_offsets;
+ DCHECK(offsets[pc]);
+ while (!offsets[--pc]) DCHECK_LE(0U, pc);
+ return pc;
+}
+
+} // namespace
+
// The main storage for interpreter code. It maps {WasmFunction} to the
// metadata needed to execute each function.
class CodeMap {
@@ -910,16 +922,29 @@ class CodeMap {
code->targets =
new (zone_) ControlTransfers(zone_, code->locals.decls_encoded_size,
code->orig_start, code->orig_end);
+
+ // Initialize the instruction_offsets bitset.
+ DCHECK(code->instruction_offsets.empty());
+ code->instruction_offsets.resize(code->end - code->start);
+ const byte* pc = code->orig_start + code->locals.decls_encoded_size;
+ while (pc < code->orig_end) {
+ code->instruction_offsets[pc - code->orig_start] = 1;
+ pc += OpcodeLength(pc, code->orig_end);
+ }
}
return code;
}
int AddFunction(const WasmFunction* function, const byte* code_start,
const byte* code_end) {
- InterpreterCode code = {
- function, AstLocalDecls(zone_), code_start,
- code_end, const_cast<byte*>(code_start), const_cast<byte*>(code_end),
- nullptr};
+ InterpreterCode code = {function,
+ AstLocalDecls(zone_),
+ code_start,
+ code_end,
+ const_cast<byte*>(code_start),
+ const_cast<byte*>(code_end),
+ nullptr,
+ BoolVector(zone_)};
DCHECK_EQ(interpreter_code_.size(), function->func_index);
interpreter_code_.push_back(code);
@@ -963,6 +988,7 @@ class ThreadImpl : public WasmInterpreter::Thread {
virtual void PushFrame(const WasmFunction* function, WasmVal* args) {
InterpreterCode* code = codemap()->FindCode(function);
CHECK_NOT_NULL(code);
+ codemap()->Preprocess(code);
frames_.push_back({code, 0, 0, stack_.size()});
for (size_t i = 0; i < function->sig->parameter_count(); ++i) {
stack_.push_back(args[i]);
@@ -1006,12 +1032,21 @@ class ThreadImpl : public WasmInterpreter::Thread {
virtual int GetFrameCount() { return static_cast<int>(frames_.size()); }
- virtual const WasmFrame* GetFrame(int index) {
- UNIMPLEMENTED();
- return nullptr;
- }
-
- virtual WasmFrame* GetMutableFrame(int index) {
+ virtual const WasmInterpreterFrame* GetFrame(int index) {
+ Frame* frame = &frames_[index];
+ DCHECK_LE(frame->sp, stack_.size());
+ DCHECK_LE(stack_.size(), static_cast<size_t>(kMaxInt));
+ // For all but the top frame, the pc is one behine the call instruction.
+ bool top_frame = static_cast<size_t>(index) == frames_.size() - 1;
+ pc_t pc = top_frame ? frame->ret_pc
+ : FindPreviousInstruction(frame->code, frame->ret_pc);
+ return new WasmInterpreterFrame(frame->code->function, // wasm function
+ static_cast<int>(pc), // pc
+ static_cast<int>(frame->sp), // fp
+ static_cast<int>(stack_.size())); // sp
+ }
+
+ virtual WasmInterpreterFrame* GetMutableFrame(int index) {
UNIMPLEMENTED();
return nullptr;
}
@@ -1652,6 +1687,7 @@ class ThreadImpl : public WasmInterpreter::Thread {
}
void TraceValueStack() {
+#if DEBUG
Frame* top = frames_.size() > 0 ? &frames_.back() : nullptr;
sp_t sp = top ? top->sp : 0;
sp_t plimit = top ? top->plimit() : 0;
@@ -1687,6 +1723,7 @@ class ThreadImpl : public WasmInterpreter::Thread {
}
}
}
+#endif
}
};
@@ -1716,10 +1753,9 @@ class WasmInterpreterInternals : public ZoneObject {
//============================================================================
// Implementation of the public interface of the interpreter.
//============================================================================
-WasmInterpreter::WasmInterpreter(WasmModuleInstance* instance,
- base::AccountingAllocator* allocator)
- : zone_(allocator),
- internals_(new (&zone_) WasmInterpreterInternals(&zone_, instance)) {}
+WasmInterpreter::WasmInterpreter(WasmModuleInstance* instance, Zone* zone)
+ : zone_(zone),
+ internals_(new (zone_) WasmInterpreterInternals(zone_, instance)) {}
WasmInterpreter::~WasmInterpreter() { internals_->Delete(); }
@@ -1727,34 +1763,38 @@ void WasmInterpreter::Run() { internals_->threads_[0]->Run(); }
void WasmInterpreter::Pause() { internals_->threads_[0]->Pause(); }
-bool WasmInterpreter::SetBreakpoint(const WasmFunction* function, pc_t pc,
+bool WasmInterpreter::SetBreakpoint(uint32_t function_index, pc_t pc,
bool enabled) {
- InterpreterCode* code = internals_->codemap_.FindCode(function);
- if (!code) return false;
+ auto interpreter_code = internals_->codemap_.interpreter_code_;
+ if (function_index > interpreter_code.size()) return false;
+ InterpreterCode* code = internals_->codemap_.GetCode(function_index);
size_t size = static_cast<size_t>(code->end - code->start);
// Check bounds for {pc}.
- if (pc < code->locals.decls_encoded_size || pc >= size) return false;
+ if (pc >= size) return false;
+ // Check that it's a valid instruction offset.
+ DCHECK_LE(pc, code->instruction_offsets.size());
+ if (!code->instruction_offsets[pc]) return false;
// Make a copy of the code before enabling a breakpoint.
if (enabled && code->orig_start == code->start) {
- code->start = reinterpret_cast<byte*>(zone_.New(size));
+ code->start = reinterpret_cast<byte*>(zone_->New(size));
memcpy(code->start, code->orig_start, size);
code->end = code->start + size;
}
bool prev = code->start[pc] == kInternalBreakpoint;
- if (enabled) {
- code->start[pc] = kInternalBreakpoint;
- } else {
- code->start[pc] = code->orig_start[pc];
- }
+ code->start[pc] = enabled ? kInternalBreakpoint : code->orig_start[pc];
return prev;
}
-bool WasmInterpreter::GetBreakpoint(const WasmFunction* function, pc_t pc) {
- InterpreterCode* code = internals_->codemap_.FindCode(function);
- if (!code) return false;
+bool WasmInterpreter::GetBreakpoint(uint32_t function_index, pc_t pc) {
+ auto interpreter_code = internals_->codemap_.interpreter_code_;
+ if (function_index > interpreter_code.size()) return false;
+ InterpreterCode* code = internals_->codemap_.GetCode(function_index);
size_t size = static_cast<size_t>(code->end - code->start);
// Check bounds for {pc}.
- if (pc < code->locals.decls_encoded_size || pc >= size) return false;
+ if (pc >= size) return false;
+ // Check that it's a valid instruction offset.
+ DCHECK_LE(pc, code->instruction_offsets.size());
+ if (!code->instruction_offsets[pc]) return false;
// Check if a breakpoint is present at that place in the code.
return code->start[pc] == kInternalBreakpoint;
}
@@ -1773,26 +1813,31 @@ WasmInterpreter::Thread* WasmInterpreter::GetThread(int id) {
return internals_->threads_[id];
}
-WasmVal WasmInterpreter::GetLocalVal(const WasmFrame* frame, int index) {
+WasmVal WasmInterpreter::GetLocalVal(const WasmInterpreterFrame* frame,
+ int index) {
CHECK_GE(index, 0);
UNIMPLEMENTED();
+ USE(frame->fp_);
+ USE(frame->sp_);
WasmVal none;
none.type = kAstStmt;
return none;
}
-WasmVal WasmInterpreter::GetExprVal(const WasmFrame* frame, int pc) {
+WasmVal WasmInterpreter::GetExprVal(const WasmInterpreterFrame* frame, int pc) {
UNIMPLEMENTED();
WasmVal none;
none.type = kAstStmt;
return none;
}
-void WasmInterpreter::SetLocalVal(WasmFrame* frame, int index, WasmVal val) {
+void WasmInterpreter::SetLocalVal(WasmInterpreterFrame* frame, int index,
+ WasmVal val) {
UNIMPLEMENTED();
}
-void WasmInterpreter::SetExprVal(WasmFrame* frame, int pc, WasmVal val) {
+void WasmInterpreter::SetExprVal(WasmInterpreterFrame* frame, int pc,
+ WasmVal val) {
UNIMPLEMENTED();
}
« no previous file with comments | « src/wasm/wasm-interpreter.h ('k') | src/wasm/wasm-module.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698