Chromium Code Reviews| Index: src/debug/debug.cc |
| diff --git a/src/debug/debug.cc b/src/debug/debug.cc |
| index 13700ff0d420b09328bef971f01e3967645e4866..235c5f37734366f41e10811695acd8169d9ea1a8 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,21 @@ 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); |
| } |
|
rmcilroy
2016/02/11 12:32:03
nit - make this an else? Seems lopsided to me to m
Yang
2016/02/11 14:16:55
Done.
|
| 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 +107,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 +166,65 @@ BreakLocation BreakLocation::CodeIterator::GetBreakLocation() { |
| statement_position()); |
| } |
| +BreakLocation::BytecodeArrayIterator::BytecodeArrayIterator( |
| + Handle<DebugInfo> debug_info, BreakLocatorType type) |
| + : Iterator(debug_info), |
| + 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) iterator_.Advance(); |
| + first = false; |
| + if (Done()) return; |
| + position_ = iterator_.source_position() - start_position_; |
| + if (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_); |
|
rmcilroy
2016/02/11 12:32:03
nit - new line above
Yang
2016/02/11 14:16:55
Done.
|
| + enum DebugBreakType type = DebugBreakType(); |
| + if (type == DEBUG_BREAK_SLOT_AT_CALL || |
| + type == DEBUG_BREAK_SLOT_AT_RETURN) { |
| + break; |
| + } |
| + } |
| +} |
| + |
| +BreakLocation::DebugBreakType |
| +BreakLocation::BytecodeArrayIterator::DebugBreakType() { |
| + BytecodeArray* bytecode_array = |
| + debug_info_->abstract_code()->GetBytecodeArray(); |
| + interpreter::Bytecode bytecode = |
| + static_cast<interpreter::Bytecode>(bytecode_array->get(code_offset())); |
| + |
| + switch (bytecode) { |
| + case interpreter::Bytecode::kDebugger: |
| + return DEBUGGER_STATEMENT; |
| + case interpreter::Bytecode::kCall: |
|
rmcilroy
2016/02/11 12:32:03
You need to list KCallWide and kNewWide as well (a
Yang
2016/02/11 14:16:55
Done.
|
| + case interpreter::Bytecode::kNew: |
| + return DEBUG_BREAK_SLOT_AT_CALL; |
| + case interpreter::Bytecode::kReturn: |
| + return DEBUG_BREAK_SLOT_AT_RETURN; |
| + default: |
| + break; |
| + } |
| + return iterator_.is_statement() ? DEBUG_BREAK_SLOT : NOT_DEBUG_BREAK; |
| +} |
| + |
| +BreakLocation BreakLocation::BytecodeArrayIterator::GetBreakLocation() { |
| + return BreakLocation(debug_info_, DebugBreakType(), 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 +398,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 +415,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 +429,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 +1219,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; |