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

Unified Diff: src/debug/debug.cc

Issue 1703453002: [interpreter, debugger] support debug breaks via bytecode array copy (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 4 years, 10 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/debug/debug.h ('k') | src/debug/debug-frames.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/debug/debug.cc
diff --git a/src/debug/debug.cc b/src/debug/debug.cc
index e6e579baaf214f2ffe528956638c0a57cf786f05..06da2f8cbe2f0ed9f32c4ab5f84dacffc077b288 100644
--- a/src/debug/debug.cc
+++ b/src/debug/debug.cc
@@ -17,6 +17,7 @@
#include "src/full-codegen/full-codegen.h"
#include "src/global-handles.h"
#include "src/interpreter/bytecodes.h"
+#include "src/interpreter/interpreter.h"
#include "src/isolate-inl.h"
#include "src/list.h"
#include "src/log.h"
@@ -193,10 +194,12 @@ void BreakLocation::BytecodeArrayIterator::Next() {
DCHECK(statement_position_ >= 0);
break_index_++;
+ enum DebugBreakType type = GetDebugBreakType();
+ if (type == NOT_DEBUG_BREAK) continue;
+
if (break_locator_type_ == ALL_BREAK_LOCATIONS) break;
DCHECK_EQ(CALLS_AND_RETURNS, break_locator_type_);
- enum DebugBreakType type = GetDebugBreakType();
if (type == DEBUG_BREAK_SLOT_AT_CALL ||
type == DEBUG_BREAK_SLOT_AT_RETURN) {
break;
@@ -206,10 +209,9 @@ void BreakLocation::BytecodeArrayIterator::Next() {
BreakLocation::DebugBreakType
BreakLocation::BytecodeArrayIterator::GetDebugBreakType() {
- BytecodeArray* bytecode_array =
- debug_info_->abstract_code()->GetBytecodeArray();
+ BytecodeArray* bytecode_array = debug_info_->original_bytecode_array();
interpreter::Bytecode bytecode =
- static_cast<interpreter::Bytecode>(bytecode_array->get(code_offset()));
+ interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset()));
if (bytecode == interpreter::Bytecode::kDebugger) {
return DEBUGGER_STATEMENT;
@@ -238,20 +240,25 @@ BreakLocation BreakLocation::FromCodeOffset(Handle<DebugInfo> debug_info,
return it->GetBreakLocation();
}
-// Move GetFirstFrameSummary Definition to here as FromFrame use it.
FrameSummary GetFirstFrameSummary(JavaScriptFrame* frame) {
List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
frame->Summarize(&frames);
return frames.first();
}
+int CallOffsetFromCodeOffset(int code_offset, bool is_interpreted) {
+ // Code offset points to the instruction after the call. Subtract 1 to
+ // exclude that instruction from the search. For bytecode, the code offset
+ // still points to the call.
+ return is_interpreted ? code_offset : code_offset - 1;
+}
+
BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info,
JavaScriptFrame* frame) {
- // Code offset to the instruction after the current one, possibly a break
- // location as well. So the "- 1" to exclude it from the search.
- // Get code offset from the unoptimized code.
FrameSummary summary = GetFirstFrameSummary(frame);
- return FromCodeOffset(debug_info, summary.code_offset() - 1);
+ int call_offset =
+ CallOffsetFromCodeOffset(summary.code_offset(), frame->is_interpreted());
+ return FromCodeOffset(debug_info, call_offset);
}
// Find the break point at the supplied address, or the closest one before
@@ -400,10 +407,16 @@ void BreakLocation::SetDebugBreak() {
: builtins->Slot_DebugBreak();
Address pc = code->instruction_start() + code_offset();
DebugCodegen::PatchDebugBreakSlot(isolate(), pc, target);
- DCHECK(IsDebugBreak());
} else {
- // TODO(yangguo): implement this once we have a way to record break points.
+ BytecodeArray* bytecode_array = abstract_code()->GetBytecodeArray();
+ interpreter::Bytecode bytecode =
+ interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset()));
+ interpreter::Bytecode debugbreak =
+ interpreter::Bytecodes::GetDebugBreak(bytecode);
+ bytecode_array->set(code_offset(),
+ interpreter::Bytecodes::ToByte(debugbreak));
}
+ DCHECK(IsDebugBreak());
}
@@ -417,10 +430,12 @@ void BreakLocation::ClearDebugBreak() {
DCHECK(code->kind() == Code::FUNCTION);
Address pc = code->instruction_start() + code_offset();
DebugCodegen::ClearDebugBreakSlot(isolate(), pc);
- DCHECK(!IsDebugBreak());
} else {
- // TODO(yangguo): implement this once we have a way to record break points.
+ BytecodeArray* bytecode_array = abstract_code()->GetBytecodeArray();
+ BytecodeArray* original = debug_info_->original_bytecode_array();
+ bytecode_array->set(code_offset(), original->get(code_offset()));
}
+ DCHECK(!IsDebugBreak());
}
@@ -433,8 +448,10 @@ bool BreakLocation::IsDebugBreak() const {
Address pc = code->instruction_start() + code_offset();
return DebugCodegen::DebugBreakSlotIsPatched(pc);
} else {
- // TODO(yangguo): implement this once we have a way to record break points.
- return false;
+ BytecodeArray* bytecode_array = abstract_code()->GetBytecodeArray();
+ interpreter::Bytecode bytecode =
+ interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset()));
+ return interpreter::Bytecodes::IsDebugBreak(bytecode);
}
}
@@ -999,10 +1016,10 @@ void Debug::PrepareStep(StepAction step_action) {
summary = GetFirstFrameSummary(frame);
}
- // PC points to the instruction after the current one, possibly a break
- // location as well. So the "- 1" to exclude it from the search.
+ int call_offset =
+ CallOffsetFromCodeOffset(summary.code_offset(), frame->is_interpreted());
BreakLocation location =
- BreakLocation::FromCodeOffset(debug_info, summary.code_offset() - 1);
+ BreakLocation::FromCodeOffset(debug_info, call_offset);
// At a return statement we will step out either way.
if (location.IsReturn()) step_action = StepOut;
@@ -1523,7 +1540,7 @@ void Debug::RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info) {
prev->set_next(current->next());
}
delete current;
- shared->set_debug_info(isolate_->heap()->undefined_value());
+ shared->set_debug_info(DebugInfo::uninitialized());
return;
}
// Move to next in list.
@@ -1534,14 +1551,25 @@ void Debug::RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info) {
UNREACHABLE();
}
-
-void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
- after_break_target_ = NULL;
-
- if (LiveEdit::SetAfterBreakTarget(this)) return; // LiveEdit did the job.
-
- // Continue just after the slot.
- after_break_target_ = frame->pc();
+Object* Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
+ if (frame->is_interpreted()) {
+ // Find the handler from the original bytecode array.
+ InterpretedFrame* interpreted_frame =
+ reinterpret_cast<InterpretedFrame*>(frame);
+ SharedFunctionInfo* shared = interpreted_frame->function()->shared();
+ BytecodeArray* bytecode_array = shared->bytecode_array();
+ int bytecode_offset = interpreted_frame->GetBytecodeOffset();
+ interpreter::Bytecode bytecode =
+ interpreter::Bytecodes::FromByte(bytecode_array->get(bytecode_offset));
+ return isolate_->interpreter()->GetBytecodeHandler(bytecode);
+ } else {
+ after_break_target_ = NULL;
+ if (!LiveEdit::SetAfterBreakTarget(this)) {
+ // Continue just after the slot.
+ after_break_target_ = frame->pc();
+ }
+ return isolate_->heap()->undefined_value();
+ }
}
@@ -1623,10 +1651,8 @@ void Debug::GetStepinPositions(JavaScriptFrame* frame, StackFrame::Id frame_id,
summary = GetFirstFrameSummary(frame);
}
- // Find range of break points starting from the break point where execution
- // has stopped. The code offset points to the instruction after the current
- // possibly a break location, too. Subtract one to exclude it from the search.
- int call_offset = summary.code_offset() - 1;
+ int call_offset =
+ CallOffsetFromCodeOffset(summary.code_offset(), frame->is_interpreted());
List<BreakLocation> locations;
BreakLocation::FromCodeOffsetSameStatement(debug_info, call_offset,
&locations);
« no previous file with comments | « src/debug/debug.h ('k') | src/debug/debug-frames.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698