Index: src/debug/debug.cc |
diff --git a/src/debug/debug.cc b/src/debug/debug.cc |
index 13700ff0d420b09328bef971f01e3967645e4866..1ea420fefe8e1eda7a9f3bf57fc02c13383d8e1f 100644 |
--- a/src/debug/debug.cc |
+++ b/src/debug/debug.cc |
@@ -16,6 +16,7 @@ |
#include "src/frames-inl.h" |
#include "src/full-codegen/full-codegen.h" |
#include "src/global-handles.h" |
+#include "src/interpreter/bytecodes.h" |
#include "src/isolate-inl.h" |
#include "src/list.h" |
#include "src/log.h" |
@@ -69,24 +70,22 @@ BreakLocation::BreakLocation(Handle<DebugInfo> debug_info, DebugBreakType type, |
BreakLocation::Iterator* BreakLocation::GetIterator( |
Handle<DebugInfo> debug_info, BreakLocatorType type) { |
- if (debug_info->shared()->HasBytecodeArray()) { |
- UNIMPLEMENTED(); |
- return nullptr; |
+ if (debug_info->abstract_code()->IsBytecodeArray()) { |
+ return new BytecodeArrayIterator(debug_info, type); |
+ } else { |
+ return new CodeIterator(debug_info, type); |
} |
- return new CodeIterator(debug_info, type); |
} |
-BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info, |
- BreakLocatorType type) |
+BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info) |
: debug_info_(debug_info), |
break_index_(-1), |
position_(1), |
- statement_position_(1) { |
-} |
+ statement_position_(1) {} |
BreakLocation::CodeIterator::CodeIterator(Handle<DebugInfo> debug_info, |
BreakLocatorType type) |
- : Iterator(debug_info, type), |
+ : Iterator(debug_info), |
reloc_iterator_(debug_info->abstract_code()->GetCode(), |
GetModeMask(type)) { |
if (!Done()) Next(); |
@@ -109,8 +108,7 @@ void BreakLocation::CodeIterator::Next() { |
DisallowHeapAllocation no_gc; |
DCHECK(!Done()); |
- // Iterate through reloc info for code and original code stopping at each |
- // breakable code target. |
+ // Iterate through reloc info stopping at each breakable code target. |
bool first = break_index_ == -1; |
while (!Done()) { |
if (!first) reloc_iterator_.next(); |
@@ -169,6 +167,68 @@ BreakLocation BreakLocation::CodeIterator::GetBreakLocation() { |
statement_position()); |
} |
+BreakLocation::BytecodeArrayIterator::BytecodeArrayIterator( |
+ Handle<DebugInfo> debug_info, BreakLocatorType type) |
+ : Iterator(debug_info), |
+ source_position_iterator_( |
+ debug_info->abstract_code()->GetBytecodeArray()), |
+ break_locator_type_(type), |
+ start_position_(debug_info->shared()->start_position()) { |
+ if (!Done()) Next(); |
+} |
+ |
+void BreakLocation::BytecodeArrayIterator::Next() { |
+ DisallowHeapAllocation no_gc; |
+ DCHECK(!Done()); |
+ bool first = break_index_ == -1; |
+ while (!Done()) { |
+ if (!first) source_position_iterator_.Advance(); |
+ first = false; |
+ if (Done()) return; |
+ position_ = source_position_iterator_.source_position() - start_position_; |
+ if (source_position_iterator_.is_statement()) { |
+ statement_position_ = position_; |
+ } |
+ DCHECK(position_ >= 0); |
+ DCHECK(statement_position_ >= 0); |
+ break_index_++; |
+ |
+ 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; |
+ } |
+ } |
+} |
+ |
+BreakLocation::DebugBreakType |
+BreakLocation::BytecodeArrayIterator::GetDebugBreakType() { |
+ BytecodeArray* bytecode_array = |
+ debug_info_->abstract_code()->GetBytecodeArray(); |
+ interpreter::Bytecode bytecode = |
+ static_cast<interpreter::Bytecode>(bytecode_array->get(code_offset())); |
+ |
+ if (bytecode == interpreter::Bytecode::kDebugger) { |
+ return DEBUGGER_STATEMENT; |
+ } else if (bytecode == interpreter::Bytecode::kReturn) { |
+ return DEBUG_BREAK_SLOT_AT_RETURN; |
+ } else if (interpreter::Bytecodes::IsCallOrNew(bytecode)) { |
+ return DEBUG_BREAK_SLOT_AT_CALL; |
+ } else if (source_position_iterator_.is_statement()) { |
+ return DEBUG_BREAK_SLOT; |
+ } else { |
+ return NOT_DEBUG_BREAK; |
+ } |
+} |
+ |
+BreakLocation BreakLocation::BytecodeArrayIterator::GetBreakLocation() { |
+ return BreakLocation(debug_info_, GetDebugBreakType(), code_offset(), |
+ position(), statement_position()); |
+} |
+ |
// Find the break point at the supplied address, or the closest one before |
// the address. |
BreakLocation BreakLocation::FromCodeOffset(Handle<DebugInfo> debug_info, |
@@ -342,7 +402,7 @@ void BreakLocation::SetDebugBreak() { |
DebugCodegen::PatchDebugBreakSlot(isolate(), pc, target); |
DCHECK(IsDebugBreak()); |
} else { |
- UNIMPLEMENTED(); |
+ // TODO(yangguo): implement this once we have a way to record break points. |
} |
} |
@@ -359,7 +419,7 @@ void BreakLocation::ClearDebugBreak() { |
DebugCodegen::ClearDebugBreakSlot(isolate(), pc); |
DCHECK(!IsDebugBreak()); |
} else { |
- UNIMPLEMENTED(); |
+ // TODO(yangguo): implement this once we have a way to record break points. |
} |
} |
@@ -373,7 +433,7 @@ bool BreakLocation::IsDebugBreak() const { |
Address pc = code->instruction_start() + code_offset(); |
return DebugCodegen::DebugBreakSlotIsPatched(pc); |
} else { |
- UNIMPLEMENTED(); |
+ // TODO(yangguo): implement this once we have a way to record break points. |
return false; |
} |
} |
@@ -1163,6 +1223,10 @@ class RedirectActiveFunctions : public ThreadVisitor { |
for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) { |
JavaScriptFrame* frame = it.frame(); |
JSFunction* function = frame->function(); |
+ if (frame->is_interpreted()) { |
+ // TODO(yangguo): replace dispatch table for activated frames. |
+ continue; |
+ } |
if (frame->is_optimized()) continue; |
if (!function->Inlines(shared_)) continue; |