Chromium Code Reviews| Index: runtime/vm/debugger.cc |
| =================================================================== |
| --- runtime/vm/debugger.cc (revision 22584) |
| +++ runtime/vm/debugger.cc (working copy) |
| @@ -603,6 +603,7 @@ |
| breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); |
| ASSERT((breakpoint_kind_ == PcDescriptors::kIcCall) || |
| (breakpoint_kind_ == PcDescriptors::kFuncCall) || |
| + (breakpoint_kind_ == PcDescriptors::kClosureCall) || |
| (breakpoint_kind_ == PcDescriptors::kReturn)); |
| } |
| @@ -665,6 +666,15 @@ |
| StubCode::BreakpointStaticEntryPoint()); |
| break; |
| } |
| + case PcDescriptors::kClosureCall: { |
| + const Code& code = |
| + Code::Handle(Function::Handle(function_).unoptimized_code()); |
| + saved_bytes_.target_address_ = |
| + CodePatcher::GetStaticCallTargetAt(pc_, code); |
| + CodePatcher::PatchStaticCallAt(pc_, code, |
| + StubCode::BreakpointClosureEntryPoint()); |
| + break; |
| + } |
| case PcDescriptors::kReturn: |
| PatchFunctionReturn(); |
| break; |
| @@ -685,7 +695,8 @@ |
| saved_bytes_.target_address_); |
| break; |
| } |
| - case PcDescriptors::kFuncCall: { |
| + case PcDescriptors::kFuncCall: |
| + case PcDescriptors::kClosureCall: { |
| const Code& code = |
| Code::Handle(Function::Handle(function_).unoptimized_code()); |
| CodePatcher::PatchStaticCallAt(pc_, code, |
| @@ -874,6 +885,7 @@ |
| PcDescriptors::Kind kind = desc.DescriptorKind(i); |
| if ((kind == PcDescriptors::kIcCall) || |
| (kind == PcDescriptors::kFuncCall) || |
| + (kind == PcDescriptors::kClosureCall) || |
| (kind == PcDescriptors::kReturn)) { |
| bpt = new CodeBreakpoint(target_function, i); |
| RegisterCodeBreakpoint(bpt); |
| @@ -1041,6 +1053,7 @@ |
| PcDescriptors::Kind kind = desc.DescriptorKind(i); |
| if ((kind == PcDescriptors::kIcCall) || |
| (kind == PcDescriptors::kFuncCall) || |
| + (kind == PcDescriptors::kClosureCall) || |
| (kind == PcDescriptors::kReturn)) { |
| if ((desc_token_pos - first_token_pos) < best_fit) { |
| best_fit = desc_token_pos - first_token_pos; |
| @@ -1573,6 +1586,25 @@ |
| if (IsDebuggable(callee)) { |
| func_to_instrument = callee.raw(); |
| } |
| + } else if (bpt->breakpoint_kind_ == PcDescriptors::kClosureCall) { |
| + func_to_instrument = bpt->function(); |
| + const Code& code = Code::Handle(func_to_instrument.CurrentCode()); |
| + ArgumentsDescriptor args_desc(Array::Handle( |
| + CodePatcher::GetClosureArgDescAt(bpt->pc_, code))); |
| + ActivationFrame* top_frame = stack_trace->ActivationFrameAt(0); |
| + const Object& call_target = |
| + Object::Handle(top_frame->GetClosureObject(args_desc.Count())); |
| + if (!call_target.IsNull()) { |
|
srdjan
2013/05/10 18:56:23
Add comment when the call_target can be NULL and i
hausner
2013/05/15 23:46:14
Done.
|
| + // Verify that the class of call_target is a closure class |
| + // by checking that signature_function() is not null. |
| + const Class& targ_class = Class::Handle(call_target.clazz()); |
| + if (targ_class.signature_function() != Function::null()) { |
|
srdjan
2013/05/10 18:56:23
Use targ_class.IsSignatureClass()
hausner
2013/05/15 23:46:14
Done.
|
| + func_to_instrument = Closure::function(Instance::Cast(call_target)); |
| + } |
| + // If call_target is not a closure, then the runtime will attempt |
| + // to invoke the "call" method on the object if one exists. |
| + // TODO(hausner): find call method and intrument it for stepping. |
| + } |
| } else { |
| ASSERT(bpt->breakpoint_kind_ == PcDescriptors::kReturn); |
| // Treat like stepping out to caller. |