| 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 "vm/code_generator.h" | 9 #include "vm/code_generator.h" | 
| 10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" | 
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 453     } else { | 453     } else { | 
| 454       column_number_ = -1; | 454       column_number_ = -1; | 
| 455     } | 455     } | 
| 456   } | 456   } | 
| 457   return column_number_; | 457   return column_number_; | 
| 458 } | 458 } | 
| 459 | 459 | 
| 460 | 460 | 
| 461 void ActivationFrame::GetVarDescriptors() { | 461 void ActivationFrame::GetVarDescriptors() { | 
| 462   if (var_descriptors_.IsNull()) { | 462   if (var_descriptors_.IsNull()) { | 
| 463     var_descriptors_ = code().var_descriptors(); | 463     if (code().is_optimized()) { | 
|  | 464       Compiler::EnsureUnoptimizedCode(Thread::Current(), function()); | 
|  | 465     } | 
|  | 466     var_descriptors_ = | 
|  | 467         Code::Handle(function().unoptimized_code()).var_descriptors(); | 
| 464     ASSERT(!var_descriptors_.IsNull()); | 468     ASSERT(!var_descriptors_.IsNull()); | 
| 465   } | 469   } | 
| 466 } | 470 } | 
| 467 | 471 | 
| 468 | 472 | 
| 469 bool ActivationFrame::IsDebuggable() const { | 473 bool ActivationFrame::IsDebuggable() const { | 
| 470   return Debugger::IsDebuggable(function()); | 474   return Debugger::IsDebuggable(function()); | 
| 471 } | 475 } | 
| 472 | 476 | 
| 473 | 477 | 
| 474 // Calculate the context level at the current token index of the frame. | 478 // Calculate the context level at the current token index of the frame. | 
| 475 intptr_t ActivationFrame::ContextLevel() { | 479 intptr_t ActivationFrame::ContextLevel() { | 
| 476   if (context_level_ < 0 && !ctx_.IsNull()) { | 480   const Context& ctx = GetSavedCurrentContext(); | 
|  | 481   if (context_level_ < 0 && !ctx.IsNull()) { | 
| 477     ASSERT(!code_.is_optimized()); | 482     ASSERT(!code_.is_optimized()); | 
| 478     context_level_ = 0; | 483     context_level_ = 0; | 
| 479     // TODO(hausner): What to do if there is no descriptor entry | 484     // TODO(hausner): What to do if there is no descriptor entry | 
| 480     // for the code position of the frame? For now say we are at context | 485     // for the code position of the frame? For now say we are at context | 
| 481     // level 0. | 486     // level 0. | 
| 482     TokenPos(); | 487     TokenPos(); | 
| 483     if (token_pos_ == -1) { | 488     if (token_pos_ == -1) { | 
| 484       // No PcDescriptor. | 489       // No PcDescriptor. | 
| 485       return context_level_; | 490       return context_level_; | 
| 486     } | 491     } | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 506         } | 511         } | 
| 507       } | 512       } | 
| 508     } | 513     } | 
| 509     ASSERT(context_level_ >= 0); | 514     ASSERT(context_level_ >= 0); | 
| 510   } | 515   } | 
| 511   return context_level_; | 516   return context_level_; | 
| 512 } | 517 } | 
| 513 | 518 | 
| 514 | 519 | 
| 515 // Get the saved current context of this activation. | 520 // Get the saved current context of this activation. | 
| 516 RawContext* ActivationFrame::GetSavedCurrentContext() { | 521 const Context& ActivationFrame::GetSavedCurrentContext() { | 
|  | 522   if (!ctx_.IsNull()) return ctx_; | 
| 517   GetVarDescriptors(); | 523   GetVarDescriptors(); | 
| 518   intptr_t var_desc_len = var_descriptors_.Length(); | 524   intptr_t var_desc_len = var_descriptors_.Length(); | 
| 519   for (intptr_t i = 0; i < var_desc_len; i++) { | 525   for (intptr_t i = 0; i < var_desc_len; i++) { | 
| 520     RawLocalVarDescriptors::VarInfo var_info; | 526     RawLocalVarDescriptors::VarInfo var_info; | 
| 521     var_descriptors_.GetInfo(i, &var_info); | 527     var_descriptors_.GetInfo(i, &var_info); | 
| 522     const int8_t kind = var_info.kind(); | 528     const int8_t kind = var_info.kind(); | 
| 523     if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { | 529     if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { | 
| 524       if (FLAG_trace_debugger_stacktrace) { | 530       if (FLAG_trace_debugger_stacktrace) { | 
| 525         OS::PrintErr("\tFound saved current ctx at index %d\n", | 531         OS::PrintErr("\tFound saved current ctx at index %d\n", | 
| 526             var_info.index()); | 532             var_info.index()); | 
| 527       } | 533       } | 
| 528       ASSERT(Object::Handle(GetLocalVar(var_info.index())).IsContext()); | 534       ctx_ ^= GetLocalVar(var_info.index()); | 
| 529       return Context::RawCast(GetLocalVar(var_info.index())); | 535       return ctx_; | 
| 530     } | 536     } | 
| 531   } | 537   } | 
| 532   UNREACHABLE(); | 538   UNREACHABLE(); | 
| 533   return Context::null(); | 539   return Context::ZoneHandle(Context::null()); | 
| 534 } | 540 } | 
| 535 | 541 | 
| 536 | 542 | 
| 537 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( | 543 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( | 
| 538     const Instance& exc_obj) const { | 544     const Instance& exc_obj) const { | 
| 539   ExceptionHandlers& handlers = ExceptionHandlers::Handle(); | 545   ExceptionHandlers& handlers = ExceptionHandlers::Handle(); | 
| 540   Array& handled_types = Array::Handle(); | 546   Array& handled_types = Array::Handle(); | 
| 541   AbstractType& type = Type::Handle(); | 547   AbstractType& type = Type::Handle(); | 
| 542   const TypeArguments& no_instantiator = TypeArguments::Handle(); | 548   const TypeArguments& no_instantiator = TypeArguments::Handle(); | 
| 543   for (intptr_t frame_index = 0; | 549   for (intptr_t frame_index = 0; | 
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 647   } | 653   } | 
| 648   vars_initialized_ = true; | 654   vars_initialized_ = true; | 
| 649 } | 655 } | 
| 650 | 656 | 
| 651 | 657 | 
| 652 intptr_t ActivationFrame::NumLocalVariables() { | 658 intptr_t ActivationFrame::NumLocalVariables() { | 
| 653   GetDescIndices(); | 659   GetDescIndices(); | 
| 654   return desc_indices_.length(); | 660   return desc_indices_.length(); | 
| 655 } | 661 } | 
| 656 | 662 | 
| 657 // TODO(hausner): Handle captured variables. | 663 | 
| 658 RawObject* ActivationFrame::GetLocalVar(intptr_t slot_index) { | 664 RawObject* ActivationFrame::GetLocalVar(intptr_t slot_index) { | 
| 659   if (deopt_frame_.IsNull()) { | 665   if (deopt_frame_.IsNull()) { | 
| 660     uword var_address = fp() + slot_index * kWordSize; | 666     uword var_address = fp() + slot_index * kWordSize; | 
| 661     return reinterpret_cast<RawObject*>( | 667     return reinterpret_cast<RawObject*>( | 
| 662         *reinterpret_cast<uword*>(var_address)); | 668         *reinterpret_cast<uword*>(var_address)); | 
| 663   } else { | 669   } else { | 
| 664     return deopt_frame_.At(deopt_frame_offset_ + slot_index); | 670     return deopt_frame_.At(deopt_frame_offset_ + slot_index); | 
| 665   } | 671   } | 
| 666 } | 672 } | 
| 667 | 673 | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 688                ctx_slot, | 694                ctx_slot, | 
| 689                frame_ctx_level, | 695                frame_ctx_level, | 
| 690                var_ctx_level); | 696                var_ctx_level); | 
| 691 | 697 | 
| 692   OS::PrintErr("-------------------------\n" | 698   OS::PrintErr("-------------------------\n" | 
| 693                "Current frame:\n%s\n", | 699                "Current frame:\n%s\n", | 
| 694                this->ToCString()); | 700                this->ToCString()); | 
| 695 | 701 | 
| 696   OS::PrintErr("-------------------------\n" | 702   OS::PrintErr("-------------------------\n" | 
| 697                "Context contents:\n"); | 703                "Context contents:\n"); | 
| 698   ctx_.Dump(8); | 704   const Context& ctx = GetSavedCurrentContext(); | 
|  | 705   ctx.Dump(8); | 
| 699 | 706 | 
| 700   OS::PrintErr("-------------------------\n" | 707   OS::PrintErr("-------------------------\n" | 
| 701                "Debugger stack trace...\n\n"); | 708                "Debugger stack trace...\n\n"); | 
| 702   DebuggerStackTrace* stack = | 709   DebuggerStackTrace* stack = | 
| 703       Isolate::Current()->debugger()->StackTrace(); | 710       Isolate::Current()->debugger()->StackTrace(); | 
| 704   intptr_t num_frames = stack->Length(); | 711   intptr_t num_frames = stack->Length(); | 
| 705   for (intptr_t i = 0; i < num_frames; i++) { | 712   for (intptr_t i = 0; i < num_frames; i++) { | 
| 706     ActivationFrame* frame = stack->FrameAt(i); | 713     ActivationFrame* frame = stack->FrameAt(i); | 
| 707     OS::PrintErr("#%04" Pd " %s", i, frame->ToCString()); | 714     OS::PrintErr("#%04" Pd " %s", i, frame->ToCString()); | 
| 708   } | 715   } | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 737   ASSERT(token_pos != NULL); | 744   ASSERT(token_pos != NULL); | 
| 738   *token_pos = var_info.begin_pos; | 745   *token_pos = var_info.begin_pos; | 
| 739   ASSERT(end_pos != NULL); | 746   ASSERT(end_pos != NULL); | 
| 740   *end_pos = var_info.end_pos; | 747   *end_pos = var_info.end_pos; | 
| 741   ASSERT(value != NULL); | 748   ASSERT(value != NULL); | 
| 742   const int8_t kind = var_info.kind(); | 749   const int8_t kind = var_info.kind(); | 
| 743   if (kind == RawLocalVarDescriptors::kStackVar) { | 750   if (kind == RawLocalVarDescriptors::kStackVar) { | 
| 744     *value = GetLocalInstanceVar(var_info.index()); | 751     *value = GetLocalInstanceVar(var_info.index()); | 
| 745   } else { | 752   } else { | 
| 746     ASSERT(kind == RawLocalVarDescriptors::kContextVar); | 753     ASSERT(kind == RawLocalVarDescriptors::kContextVar); | 
| 747     ASSERT(!ctx_.IsNull()); | 754     const Context& ctx = GetSavedCurrentContext(); | 
|  | 755     ASSERT(!ctx.IsNull()); | 
| 748 | 756 | 
| 749     // The context level at the PC/token index of this activation frame. | 757     // The context level at the PC/token index of this activation frame. | 
| 750     intptr_t frame_ctx_level = ContextLevel(); | 758     intptr_t frame_ctx_level = ContextLevel(); | 
| 751 | 759 | 
| 752     // The context level of the variable. | 760     // The context level of the variable. | 
| 753     intptr_t var_ctx_level = var_info.scope_id; | 761     intptr_t var_ctx_level = var_info.scope_id; | 
| 754     intptr_t level_diff = frame_ctx_level - var_ctx_level; | 762     intptr_t level_diff = frame_ctx_level - var_ctx_level; | 
| 755     intptr_t ctx_slot = var_info.index(); | 763     intptr_t ctx_slot = var_info.index(); | 
| 756     if (level_diff == 0) { | 764     if (level_diff == 0) { | 
| 757       if ((ctx_slot < 0) || | 765       if ((ctx_slot < 0) || | 
| 758           (ctx_slot >= ctx_.num_variables())) { | 766           (ctx_slot >= ctx.num_variables())) { | 
| 759         PrintContextMismatchError(*name, ctx_slot, | 767         PrintContextMismatchError(*name, ctx_slot, | 
| 760                                   frame_ctx_level, var_ctx_level); | 768                                   frame_ctx_level, var_ctx_level); | 
| 761       } | 769       } | 
| 762       ASSERT((ctx_slot >= 0) && (ctx_slot < ctx_.num_variables())); | 770       ASSERT((ctx_slot >= 0) && (ctx_slot < ctx.num_variables())); | 
| 763       *value = ctx_.At(ctx_slot); | 771       *value = ctx.At(ctx_slot); | 
| 764     } else { | 772     } else { | 
| 765       ASSERT(level_diff > 0); | 773       ASSERT(level_diff > 0); | 
| 766       Context& var_ctx = Context::Handle(ctx_.raw()); | 774       Context& var_ctx = Context::Handle(ctx.raw()); | 
| 767       while (level_diff > 0 && !var_ctx.IsNull()) { | 775       while (level_diff > 0 && !var_ctx.IsNull()) { | 
| 768         level_diff--; | 776         level_diff--; | 
| 769         var_ctx = var_ctx.parent(); | 777         var_ctx = var_ctx.parent(); | 
| 770       } | 778       } | 
| 771       if (var_ctx.IsNull() || | 779       if (var_ctx.IsNull() || | 
| 772           (ctx_slot < 0) || | 780           (ctx_slot < 0) || | 
| 773           (ctx_slot >= var_ctx.num_variables())) { | 781           (ctx_slot >= var_ctx.num_variables())) { | 
| 774         PrintContextMismatchError(*name, ctx_slot, | 782         PrintContextMismatchError(*name, ctx_slot, | 
| 775                                   frame_ctx_level, var_ctx_level); | 783                                   frame_ctx_level, var_ctx_level); | 
| 776       } | 784       } | 
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1178 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, | 1186 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, | 
| 1179                                             uword pc, | 1187                                             uword pc, | 
| 1180                                             StackFrame* frame, | 1188                                             StackFrame* frame, | 
| 1181                                             const Code& code, | 1189                                             const Code& code, | 
| 1182                                             const Array& deopt_frame, | 1190                                             const Array& deopt_frame, | 
| 1183                                             intptr_t deopt_frame_offset) { | 1191                                             intptr_t deopt_frame_offset) { | 
| 1184   ASSERT(code.ContainsInstructionAt(pc)); | 1192   ASSERT(code.ContainsInstructionAt(pc)); | 
| 1185   ActivationFrame* activation = | 1193   ActivationFrame* activation = | 
| 1186       new ActivationFrame(pc, frame->fp(), frame->sp(), code, | 1194       new ActivationFrame(pc, frame->fp(), frame->sp(), code, | 
| 1187                           deopt_frame, deopt_frame_offset); | 1195                           deopt_frame, deopt_frame_offset); | 
| 1188 |  | 
| 1189   // Recover the context for this frame. |  | 
| 1190   const Context& ctx = |  | 
| 1191       Context::Handle(isolate, activation->GetSavedCurrentContext()); |  | 
| 1192   ASSERT(!ctx.IsNull()); |  | 
| 1193   activation->SetContext(ctx); |  | 
| 1194   if (FLAG_trace_debugger_stacktrace) { | 1196   if (FLAG_trace_debugger_stacktrace) { | 
|  | 1197     const Context& ctx = activation->GetSavedCurrentContext(); | 
| 1195     OS::PrintErr("\tUsing saved context: %s\n", ctx.ToCString()); | 1198     OS::PrintErr("\tUsing saved context: %s\n", ctx.ToCString()); | 
| 1196   } | 1199   } | 
| 1197   if (FLAG_trace_debugger_stacktrace) { | 1200   if (FLAG_trace_debugger_stacktrace) { | 
| 1198     OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber()); | 1201     OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber()); | 
| 1199   } | 1202   } | 
| 1200   return activation; | 1203   return activation; | 
| 1201 } | 1204 } | 
| 1202 | 1205 | 
| 1203 | 1206 | 
| 1204 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate, | 1207 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate, | 
| (...skipping 1431 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2636 } | 2639 } | 
| 2637 | 2640 | 
| 2638 | 2641 | 
| 2639 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2642 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 
| 2640   ASSERT(bpt->next() == NULL); | 2643   ASSERT(bpt->next() == NULL); | 
| 2641   bpt->set_next(code_breakpoints_); | 2644   bpt->set_next(code_breakpoints_); | 
| 2642   code_breakpoints_ = bpt; | 2645   code_breakpoints_ = bpt; | 
| 2643 } | 2646 } | 
| 2644 | 2647 | 
| 2645 }  // namespace dart | 2648 }  // namespace dart | 
| OLD | NEW | 
|---|