| Index: src/debug.cc
|
| ===================================================================
|
| --- src/debug.cc (revision 2457)
|
| +++ src/debug.cc (working copy)
|
| @@ -334,8 +334,11 @@
|
| 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 @@
|
|
|
| // 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 @@
|
| 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 @@
|
| } 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);
|
|
|