| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/debugger.h" | 5 #include "vm/debugger.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 | 8 |
| 9 #include "platform/address_sanitizer.h" | 9 #include "platform/address_sanitizer.h" |
| 10 | 10 |
| (...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 if (iter.TryIndex() != CatchClauseNode::kInvalidTryIndex) { | 902 if (iter.TryIndex() != CatchClauseNode::kInvalidTryIndex) { |
| 903 if ((try_index_ == -1) || (iter.TryIndex() < try_index_)) { | 903 if ((try_index_ == -1) || (iter.TryIndex() < try_index_)) { |
| 904 try_index_ = iter.TryIndex(); | 904 try_index_ = iter.TryIndex(); |
| 905 } | 905 } |
| 906 } | 906 } |
| 907 } | 907 } |
| 908 } | 908 } |
| 909 } | 909 } |
| 910 | 910 |
| 911 | 911 |
| 912 bool ActivationFrame::IsAsyncMachinery() const { |
| 913 Isolate* isolate = Isolate::Current(); |
| 914 if (function_.raw() == isolate->object_store()->complete_on_async_return()) { |
| 915 // We are completing an async function's completer. |
| 916 return true; |
| 917 } |
| 918 if (function_.Owner() == |
| 919 isolate->object_store()->async_star_stream_controller()) { |
| 920 // We are inside the async* stream controller code. |
| 921 return true; |
| 922 } |
| 923 return false; |
| 924 } |
| 925 |
| 926 |
| 912 // Get the saved current context of this activation. | 927 // Get the saved current context of this activation. |
| 913 const Context& ActivationFrame::GetSavedCurrentContext() { | 928 const Context& ActivationFrame::GetSavedCurrentContext() { |
| 914 if (!ctx_.IsNull()) return ctx_; | 929 if (!ctx_.IsNull()) return ctx_; |
| 915 GetVarDescriptors(); | 930 GetVarDescriptors(); |
| 916 intptr_t var_desc_len = var_descriptors_.Length(); | 931 intptr_t var_desc_len = var_descriptors_.Length(); |
| 917 for (intptr_t i = 0; i < var_desc_len; i++) { | 932 for (intptr_t i = 0; i < var_desc_len; i++) { |
| 918 RawLocalVarDescriptors::VarInfo var_info; | 933 RawLocalVarDescriptors::VarInfo var_info; |
| 919 var_descriptors_.GetInfo(i, &var_info); | 934 var_descriptors_.GetInfo(i, &var_info); |
| 920 const int8_t kind = var_info.kind(); | 935 const int8_t kind = var_info.kind(); |
| 921 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { | 936 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1568 resume_action_(kContinue), | 1583 resume_action_(kContinue), |
| 1569 resume_frame_index_(-1), | 1584 resume_frame_index_(-1), |
| 1570 post_deopt_frame_index_(-1), | 1585 post_deopt_frame_index_(-1), |
| 1571 ignore_breakpoints_(false), | 1586 ignore_breakpoints_(false), |
| 1572 pause_event_(NULL), | 1587 pause_event_(NULL), |
| 1573 obj_cache_(NULL), | 1588 obj_cache_(NULL), |
| 1574 stack_trace_(NULL), | 1589 stack_trace_(NULL), |
| 1575 async_causal_stack_trace_(NULL), | 1590 async_causal_stack_trace_(NULL), |
| 1576 awaiter_stack_trace_(NULL), | 1591 awaiter_stack_trace_(NULL), |
| 1577 stepping_fp_(0), | 1592 stepping_fp_(0), |
| 1593 async_stepping_fp_(0), |
| 1594 top_frame_awaiter_(Object::null()), |
| 1578 skip_next_step_(false), | 1595 skip_next_step_(false), |
| 1579 needs_breakpoint_cleanup_(false), | 1596 needs_breakpoint_cleanup_(false), |
| 1580 synthetic_async_breakpoint_(NULL), | 1597 synthetic_async_breakpoint_(NULL), |
| 1581 exc_pause_info_(kNoPauseOnExceptions) {} | 1598 exc_pause_info_(kNoPauseOnExceptions) {} |
| 1582 | 1599 |
| 1583 | 1600 |
| 1584 Debugger::~Debugger() { | 1601 Debugger::~Debugger() { |
| 1585 isolate_id_ = ILLEGAL_ISOLATE_ID; | 1602 isolate_id_ = ILLEGAL_ISOLATE_ID; |
| 1586 ASSERT(!IsPaused()); | 1603 ASSERT(!IsPaused()); |
| 1587 ASSERT(latent_locations_ == NULL); | 1604 ASSERT(latent_locations_ == NULL); |
| (...skipping 1542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3130 bpt = latent_locations_; | 3147 bpt = latent_locations_; |
| 3131 while (bpt != NULL) { | 3148 while (bpt != NULL) { |
| 3132 bpt->VisitObjectPointers(visitor); | 3149 bpt->VisitObjectPointers(visitor); |
| 3133 bpt = bpt->next(); | 3150 bpt = bpt->next(); |
| 3134 } | 3151 } |
| 3135 CodeBreakpoint* cbpt = code_breakpoints_; | 3152 CodeBreakpoint* cbpt = code_breakpoints_; |
| 3136 while (cbpt != NULL) { | 3153 while (cbpt != NULL) { |
| 3137 cbpt->VisitObjectPointers(visitor); | 3154 cbpt->VisitObjectPointers(visitor); |
| 3138 cbpt = cbpt->next(); | 3155 cbpt = cbpt->next(); |
| 3139 } | 3156 } |
| 3157 visitor->VisitPointer(reinterpret_cast<RawObject**>(&top_frame_awaiter_)); |
| 3140 } | 3158 } |
| 3141 | 3159 |
| 3142 | 3160 |
| 3143 // static | 3161 // static |
| 3144 void Debugger::SetEventHandler(EventHandler* handler) { | 3162 void Debugger::SetEventHandler(EventHandler* handler) { |
| 3145 event_handler_ = handler; | 3163 event_handler_ = handler; |
| 3146 } | 3164 } |
| 3147 | 3165 |
| 3148 | 3166 |
| 3149 void Debugger::Pause(ServiceEvent* event) { | 3167 void Debugger::Pause(ServiceEvent* event) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3193 | 3211 |
| 3194 if (needs_breakpoint_cleanup_) { | 3212 if (needs_breakpoint_cleanup_) { |
| 3195 RemoveUnlinkedCodeBreakpoints(); | 3213 RemoveUnlinkedCodeBreakpoints(); |
| 3196 } | 3214 } |
| 3197 pause_event_ = NULL; | 3215 pause_event_ = NULL; |
| 3198 obj_cache_ = NULL; // Zone allocated | 3216 obj_cache_ = NULL; // Zone allocated |
| 3199 } | 3217 } |
| 3200 | 3218 |
| 3201 | 3219 |
| 3202 void Debugger::EnterSingleStepMode() { | 3220 void Debugger::EnterSingleStepMode() { |
| 3203 stepping_fp_ = 0; | 3221 ResetSteppingFramePointers(); |
| 3204 DeoptimizeWorld(); | 3222 DeoptimizeWorld(); |
| 3205 isolate_->set_single_step(true); | 3223 isolate_->set_single_step(true); |
| 3206 } | 3224 } |
| 3207 | 3225 |
| 3208 | 3226 |
| 3227 void Debugger::ResetSteppingFramePointers() { |
| 3228 stepping_fp_ = 0; |
| 3229 async_stepping_fp_ = 0; |
| 3230 } |
| 3231 |
| 3232 |
| 3233 bool Debugger::SteppedForSyntheticAsyncBreakpoint() const { |
| 3234 return synthetic_async_breakpoint_ != NULL; |
| 3235 } |
| 3236 |
| 3237 |
| 3238 void Debugger::CleanupSyntheticAsyncBreakpoint() { |
| 3239 if (synthetic_async_breakpoint_ != NULL) { |
| 3240 RemoveBreakpoint(synthetic_async_breakpoint_->id()); |
| 3241 synthetic_async_breakpoint_ = NULL; |
| 3242 } |
| 3243 } |
| 3244 |
| 3245 |
| 3246 void Debugger::RememberTopFrameAwaiter() { |
| 3247 if (!FLAG_async_debugger_stepping) { |
| 3248 return; |
| 3249 } |
| 3250 if (stack_trace_->Length() > 0) { |
| 3251 top_frame_awaiter_ = stack_trace_->FrameAt(0)->GetAsyncAwaiter(); |
| 3252 } else { |
| 3253 top_frame_awaiter_ = Object::null(); |
| 3254 } |
| 3255 } |
| 3256 |
| 3257 |
| 3258 void Debugger::SetAsyncSteppingFramePointer() { |
| 3259 if (!FLAG_async_debugger_stepping) { |
| 3260 return; |
| 3261 } |
| 3262 if (stack_trace_->FrameAt(0)->function().IsAsyncClosure() || |
| 3263 stack_trace_->FrameAt(0)->function().IsAsyncGenClosure()) { |
| 3264 async_stepping_fp_ = stack_trace_->FrameAt(0)->fp(); |
| 3265 } else { |
| 3266 async_stepping_fp_ = 0; |
| 3267 } |
| 3268 } |
| 3269 |
| 3270 |
| 3209 void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace, | 3271 void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace, |
| 3210 bool skip_next_step) { | 3272 bool skip_next_step) { |
| 3211 stepping_fp_ = 0; | 3273 ResetSteppingFramePointers(); |
| 3274 RememberTopFrameAwaiter(); |
| 3212 if (resume_action_ == kStepInto) { | 3275 if (resume_action_ == kStepInto) { |
| 3213 // When single stepping, we need to deoptimize because we might be | 3276 // When single stepping, we need to deoptimize because we might be |
| 3214 // stepping into optimized code. This happens in particular if | 3277 // stepping into optimized code. This happens in particular if |
| 3215 // the isolate has been interrupted, but can happen in other cases | 3278 // the isolate has been interrupted, but can happen in other cases |
| 3216 // as well. We need to deoptimize the world in case we are about | 3279 // as well. We need to deoptimize the world in case we are about |
| 3217 // to call an optimized function. | 3280 // to call an optimized function. |
| 3218 DeoptimizeWorld(); | 3281 DeoptimizeWorld(); |
| 3219 isolate_->set_single_step(true); | 3282 isolate_->set_single_step(true); |
| 3220 skip_next_step_ = skip_next_step; | 3283 skip_next_step_ = skip_next_step; |
| 3284 SetAsyncSteppingFramePointer(); |
| 3221 if (FLAG_verbose_debug) { | 3285 if (FLAG_verbose_debug) { |
| 3222 OS::Print("HandleSteppingRequest- kStepInto\n"); | 3286 OS::Print("HandleSteppingRequest- kStepInto\n"); |
| 3223 } | 3287 } |
| 3224 } else if (resume_action_ == kStepOver) { | 3288 } else if (resume_action_ == kStepOver) { |
| 3225 DeoptimizeWorld(); | 3289 DeoptimizeWorld(); |
| 3226 isolate_->set_single_step(true); | 3290 isolate_->set_single_step(true); |
| 3227 skip_next_step_ = skip_next_step; | 3291 skip_next_step_ = skip_next_step; |
| 3228 ASSERT(stack_trace->Length() > 0); | 3292 ASSERT(stack_trace->Length() > 0); |
| 3229 stepping_fp_ = stack_trace->FrameAt(0)->fp(); | 3293 stepping_fp_ = stack_trace->FrameAt(0)->fp(); |
| 3294 SetAsyncSteppingFramePointer(); |
| 3230 if (FLAG_verbose_debug) { | 3295 if (FLAG_verbose_debug) { |
| 3231 OS::Print("HandleSteppingRequest- kStepOver %" Px "\n", stepping_fp_); | 3296 OS::Print("HandleSteppingRequest- kStepOver %" Px "\n", stepping_fp_); |
| 3232 } | 3297 } |
| 3233 } else if (resume_action_ == kStepOut) { | 3298 } else if (resume_action_ == kStepOut) { |
| 3234 if (FLAG_async_debugger_stepping) { | 3299 if (FLAG_async_debugger_stepping) { |
| 3235 if (stack_trace->FrameAt(0)->function().IsAsyncClosure() || | 3300 if (stack_trace->FrameAt(0)->function().IsAsyncClosure() || |
| 3236 stack_trace->FrameAt(0)->function().IsAsyncGenClosure()) { | 3301 stack_trace->FrameAt(0)->function().IsAsyncGenClosure()) { |
| 3237 // Request to step out of an async/async* closure. | 3302 // Request to step out of an async/async* closure. |
| 3238 const Object& async_op = | 3303 const Object& async_op = |
| 3239 Object::Handle(stack_trace->FrameAt(0)->GetAsyncAwaiter()); | 3304 Object::Handle(stack_trace->FrameAt(0)->GetAsyncAwaiter()); |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3526 return false; | 3591 return false; |
| 3527 } | 3592 } |
| 3528 const Class& cls = Class::Handle(func.Owner()); | 3593 const Class& cls = Class::Handle(func.Owner()); |
| 3529 const Library& lib = Library::Handle(cls.library()); | 3594 const Library& lib = Library::Handle(cls.library()); |
| 3530 return lib.IsDebuggable(); | 3595 return lib.IsDebuggable(); |
| 3531 } | 3596 } |
| 3532 | 3597 |
| 3533 | 3598 |
| 3534 void Debugger::SignalPausedEvent(ActivationFrame* top_frame, Breakpoint* bpt) { | 3599 void Debugger::SignalPausedEvent(ActivationFrame* top_frame, Breakpoint* bpt) { |
| 3535 resume_action_ = kContinue; | 3600 resume_action_ = kContinue; |
| 3536 stepping_fp_ = 0; | 3601 ResetSteppingFramePointers(); |
| 3537 isolate_->set_single_step(false); | 3602 isolate_->set_single_step(false); |
| 3538 ASSERT(!IsPaused()); | 3603 ASSERT(!IsPaused()); |
| 3539 ASSERT(obj_cache_ == NULL); | 3604 ASSERT(obj_cache_ == NULL); |
| 3540 if ((bpt != NULL) && bpt->IsSingleShot()) { | 3605 if ((bpt != NULL) && bpt->IsSingleShot()) { |
| 3541 RemoveBreakpoint(bpt->id()); | 3606 RemoveBreakpoint(bpt->id()); |
| 3542 bpt = NULL; | 3607 bpt = NULL; |
| 3543 } | 3608 } |
| 3544 | 3609 |
| 3545 ServiceEvent event(isolate_, ServiceEvent::kPauseBreakpoint); | 3610 ServiceEvent event(isolate_, ServiceEvent::kPauseBreakpoint); |
| 3546 event.set_top_frame(top_frame); | 3611 event.set_top_frame(top_frame); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3592 } | 3657 } |
| 3593 | 3658 |
| 3594 // Check whether we are in a Dart function that the user is | 3659 // Check whether we are in a Dart function that the user is |
| 3595 // interested in. If we saved the frame pointer of a stack frame | 3660 // interested in. If we saved the frame pointer of a stack frame |
| 3596 // the user is interested in, we ignore the single step if we are | 3661 // the user is interested in, we ignore the single step if we are |
| 3597 // in a callee of that frame. Note that we assume that the stack | 3662 // in a callee of that frame. Note that we assume that the stack |
| 3598 // grows towards lower addresses. | 3663 // grows towards lower addresses. |
| 3599 ActivationFrame* frame = TopDartFrame(); | 3664 ActivationFrame* frame = TopDartFrame(); |
| 3600 ASSERT(frame != NULL); | 3665 ASSERT(frame != NULL); |
| 3601 | 3666 |
| 3667 if (FLAG_async_debugger_stepping) { |
| 3668 if ((async_stepping_fp_ != 0) && (top_frame_awaiter_ != Object::null())) { |
| 3669 // Check if the user has single stepped out of an async function with |
| 3670 // an awaiter. The first check handles the case of calling into the |
| 3671 // async machinery as we finish the async function. The second check |
| 3672 // handles the case of returning from an async function. |
| 3673 const bool exited_async_function = |
| 3674 (IsCalleeFrameOf(async_stepping_fp_, frame->fp()) && |
| 3675 frame->IsAsyncMachinery()) || |
| 3676 IsCalleeFrameOf(frame->fp(), async_stepping_fp_); |
| 3677 if (exited_async_function) { |
| 3678 // Step to the top frame awaiter. |
| 3679 const Object& async_op = Object::Handle(top_frame_awaiter_); |
| 3680 top_frame_awaiter_ = Object::null(); |
| 3681 AsyncStepInto(Closure::Cast(async_op)); |
| 3682 return Error::null(); |
| 3683 } |
| 3684 } |
| 3685 } |
| 3686 |
| 3602 if (stepping_fp_ != 0) { | 3687 if (stepping_fp_ != 0) { |
| 3603 // There is an "interesting frame" set. Only pause at appropriate | 3688 // There is an "interesting frame" set. Only pause at appropriate |
| 3604 // locations in this frame. | 3689 // locations in this frame. |
| 3605 if (IsCalleeFrameOf(stepping_fp_, frame->fp())) { | 3690 if (IsCalleeFrameOf(stepping_fp_, frame->fp())) { |
| 3606 // We are in a callee of the frame we're interested in. | 3691 // We are in a callee of the frame we're interested in. |
| 3607 // Ignore this stepping break. | 3692 // Ignore this stepping break. |
| 3608 return Error::null(); | 3693 return Error::null(); |
| 3609 } else if (IsCalleeFrameOf(frame->fp(), stepping_fp_)) { | 3694 } else if (IsCalleeFrameOf(frame->fp(), stepping_fp_)) { |
| 3610 // We returned from the "interesting frame", there can be no more | 3695 // We returned from the "interesting frame", there can be no more |
| 3611 // stepping breaks for it. Pause at the next appropriate location | 3696 // stepping breaks for it. Pause at the next appropriate location |
| 3612 // and let the user set the "interesting" frame again. | 3697 // and let the user set the "interesting" frame again. |
| 3613 stepping_fp_ = 0; | 3698 ResetSteppingFramePointers(); |
| 3614 } | 3699 } |
| 3615 } | 3700 } |
| 3616 | 3701 |
| 3617 if (!frame->IsDebuggable()) { | 3702 if (!frame->IsDebuggable()) { |
| 3618 return Error::null(); | 3703 return Error::null(); |
| 3619 } | 3704 } |
| 3620 if (!frame->TokenPos().IsDebugPause()) { | 3705 if (!frame->TokenPos().IsDebugPause()) { |
| 3621 return Error::null(); | 3706 return Error::null(); |
| 3622 } | 3707 } |
| 3623 | 3708 |
| 3624 // If there is an active breakpoint at this pc, then we should have | 3709 // If there is an active breakpoint at this pc, then we should have |
| 3625 // already bailed out of this function in the skip_next_step_ test | 3710 // already bailed out of this function in the skip_next_step_ test |
| 3626 // above. | 3711 // above. |
| 3627 ASSERT(!HasActiveBreakpoint(frame->pc())); | 3712 ASSERT(!HasActiveBreakpoint(frame->pc())); |
| 3628 | 3713 |
| 3629 if (FLAG_verbose_debug) { | 3714 if (FLAG_verbose_debug) { |
| 3630 OS::Print(">>> single step break at %s:%" Pd " (func %s token %s)\n", | 3715 OS::Print(">>> single step break at %s:%" Pd " (func %s token %s)\n", |
| 3631 String::Handle(frame->SourceUrl()).ToCString(), | 3716 String::Handle(frame->SourceUrl()).ToCString(), |
| 3632 frame->LineNumber(), | 3717 frame->LineNumber(), |
| 3633 String::Handle(frame->QualifiedFunctionName()).ToCString(), | 3718 String::Handle(frame->QualifiedFunctionName()).ToCString(), |
| 3634 frame->TokenPos().ToCString()); | 3719 frame->TokenPos().ToCString()); |
| 3635 } | 3720 } |
| 3636 | 3721 |
| 3637 | 3722 |
| 3638 CacheStackTraces(CollectStackTrace(), CollectAsyncCausalStackTrace(), | 3723 CacheStackTraces(CollectStackTrace(), CollectAsyncCausalStackTrace(), |
| 3639 CollectAwaiterReturnStackTrace()); | 3724 CollectAwaiterReturnStackTrace()); |
| 3640 // If this step callback is part of stepping over an await statement, | 3725 if (SteppedForSyntheticAsyncBreakpoint()) { |
| 3641 // we saved the synthetic async breakpoint in PauseBreakpoint. We report | 3726 CleanupSyntheticAsyncBreakpoint(); |
| 3642 // that we are paused at that breakpoint and then delete it after continuing. | |
| 3643 SignalPausedEvent(frame, synthetic_async_breakpoint_); | |
| 3644 if (synthetic_async_breakpoint_ != NULL) { | |
| 3645 RemoveBreakpoint(synthetic_async_breakpoint_->id()); | |
| 3646 synthetic_async_breakpoint_ = NULL; | |
| 3647 } | 3727 } |
| 3728 SignalPausedEvent(frame, NULL); |
| 3648 HandleSteppingRequest(stack_trace_); | 3729 HandleSteppingRequest(stack_trace_); |
| 3649 ClearCachedStackTraces(); | 3730 ClearCachedStackTraces(); |
| 3650 | 3731 |
| 3651 // If any error occurred while in the debug message loop, return it here. | 3732 // If any error occurred while in the debug message loop, return it here. |
| 3652 const Error& error = Error::Handle(Thread::Current()->sticky_error()); | 3733 const Error& error = Error::Handle(Thread::Current()->sticky_error()); |
| 3653 Thread::Current()->clear_sticky_error(); | 3734 Thread::Current()->clear_sticky_error(); |
| 3654 return error.raw(); | 3735 return error.raw(); |
| 3655 } | 3736 } |
| 3656 | 3737 |
| 3657 | 3738 |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4230 | 4311 |
| 4231 void Debugger::AsyncStepInto(const Closure& async_op) { | 4312 void Debugger::AsyncStepInto(const Closure& async_op) { |
| 4232 SetBreakpointAtActivation(async_op, true); | 4313 SetBreakpointAtActivation(async_op, true); |
| 4233 Continue(); | 4314 Continue(); |
| 4234 } | 4315 } |
| 4235 | 4316 |
| 4236 | 4317 |
| 4237 void Debugger::Continue() { | 4318 void Debugger::Continue() { |
| 4238 SetResumeAction(kContinue); | 4319 SetResumeAction(kContinue); |
| 4239 stepping_fp_ = 0; | 4320 stepping_fp_ = 0; |
| 4321 async_stepping_fp_ = 0; |
| 4240 isolate_->set_single_step(false); | 4322 isolate_->set_single_step(false); |
| 4241 } | 4323 } |
| 4242 | 4324 |
| 4243 | 4325 |
| 4244 BreakpointLocation* Debugger::GetLatentBreakpoint(const String& url, | 4326 BreakpointLocation* Debugger::GetLatentBreakpoint(const String& url, |
| 4245 intptr_t line, | 4327 intptr_t line, |
| 4246 intptr_t column) { | 4328 intptr_t column) { |
| 4247 BreakpointLocation* bpt = latent_locations_; | 4329 BreakpointLocation* bpt = latent_locations_; |
| 4248 String& bpt_url = String::Handle(); | 4330 String& bpt_url = String::Handle(); |
| 4249 while (bpt != NULL) { | 4331 while (bpt != NULL) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 4271 | 4353 |
| 4272 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 4354 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 4273 ASSERT(bpt->next() == NULL); | 4355 ASSERT(bpt->next() == NULL); |
| 4274 bpt->set_next(code_breakpoints_); | 4356 bpt->set_next(code_breakpoints_); |
| 4275 code_breakpoints_ = bpt; | 4357 code_breakpoints_ = bpt; |
| 4276 } | 4358 } |
| 4277 | 4359 |
| 4278 #endif // !PRODUCT | 4360 #endif // !PRODUCT |
| 4279 | 4361 |
| 4280 } // namespace dart | 4362 } // namespace dart |
| OLD | NEW |