diff options
Diffstat (limited to 'V8Binding/v8/src/debug.cc')
-rw-r--r-- | V8Binding/v8/src/debug.cc | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/V8Binding/v8/src/debug.cc b/V8Binding/v8/src/debug.cc index 52be930..64f98c7 100644 --- a/V8Binding/v8/src/debug.cc +++ b/V8Binding/v8/src/debug.cc @@ -334,8 +334,11 @@ void BreakLocationIterator::PrepareStepIn() { rinfo()->set_target_address(stub->entry()); } } else { - // Step in through constructs call requires no changes to the running code. - ASSERT(RelocInfo::IsConstructCall(rmode())); + // Step in through construct call requires no changes to the running code. + // Step in through getters/setters should already be prepared as well + // because caller of this function (Debug::PrepareStep) is expected to + // flood the top frame's function with one shot breakpoints. + ASSERT(RelocInfo::IsConstructCall(rmode()) || code->is_inline_cache_stub()); } } @@ -1087,10 +1090,18 @@ void Debug::PrepareStep(StepAction step_action, int step_count) { // Compute whether or not the target is a call target. bool is_call_target = false; + bool is_load_or_store = false; + bool is_inline_cache_stub = false; if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) { Address target = it.rinfo()->target_address(); Code* code = Code::GetCodeFromTargetAddress(target); - if (code->is_call_stub()) is_call_target = true; + if (code->is_call_stub()) { + is_call_target = true; + } + if (code->is_inline_cache_stub()) { + is_inline_cache_stub = true; + is_load_or_store = !is_call_target; + } } // If this is the last break code target step out is the only possibility. @@ -1103,8 +1114,8 @@ void Debug::PrepareStep(StepAction step_action, int step_count) { JSFunction* function = JSFunction::cast(frames_it.frame()->function()); FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared())); } - } else if (!(is_call_target || RelocInfo::IsConstructCall(it.rmode())) || - step_action == StepNext || step_action == StepMin) { + } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode())) + || step_action == StepNext || step_action == StepMin) { // Step next or step min. // Fill the current function with one-shot break points. @@ -1117,9 +1128,20 @@ void Debug::PrepareStep(StepAction step_action, int step_count) { } else { // Fill the current function with one-shot break points even for step in on // a call target as the function called might be a native function for - // which step in will not stop. + // which step in will not stop. It also prepares for stepping in + // getters/setters. FloodWithOneShot(shared); + if (is_load_or_store) { + // Remember source position and frame to handle step in getter/setter. If + // there is a custom getter/setter it will be handled in + // Object::Get/SetPropertyWithCallback, otherwise the step action will be + // propagated on the next Debug::Break. + thread_local_.last_statement_position_ = + debug_info->code()->SourceStatementPosition(frame->pc()); + thread_local_.last_fp_ = frame->fp(); + } + // Step in or Step in min it.PrepareStepIn(); ActivateStepIn(frame); |