| 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 10 matching lines...) Expand all Loading... |
| 21 #include "vm/port.h" | 21 #include "vm/port.h" |
| 22 #include "vm/stack_frame.h" | 22 #include "vm/stack_frame.h" |
| 23 #include "vm/stub_code.h" | 23 #include "vm/stub_code.h" |
| 24 #include "vm/symbols.h" | 24 #include "vm/symbols.h" |
| 25 #include "vm/visitor.h" | 25 #include "vm/visitor.h" |
| 26 | 26 |
| 27 | 27 |
| 28 namespace dart { | 28 namespace dart { |
| 29 | 29 |
| 30 DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages"); | 30 DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages"); |
| 31 DEFINE_FLAG(bool, trace_debugger_stacktrace, false, |
| 32 "Trace debugger stacktrace collection"); |
| 31 | 33 |
| 32 | 34 |
| 33 Debugger::EventHandler* Debugger::event_handler_ = NULL; | 35 Debugger::EventHandler* Debugger::event_handler_ = NULL; |
| 34 | 36 |
| 35 | 37 |
| 36 class RemoteObjectCache : public ZoneAllocated { | 38 class RemoteObjectCache : public ZoneAllocated { |
| 37 public: | 39 public: |
| 38 explicit RemoteObjectCache(intptr_t initial_size); | 40 explicit RemoteObjectCache(intptr_t initial_size); |
| 39 intptr_t AddObject(const Object& obj); | 41 intptr_t AddObject(const Object& obj); |
| 40 RawObject* GetObj(intptr_t obj_id) const; | 42 RawObject* GetObj(intptr_t obj_id) const; |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 | 441 |
| 440 | 442 |
| 441 RawContext* ActivationFrame::GetSavedEntryContext() { | 443 RawContext* ActivationFrame::GetSavedEntryContext() { |
| 442 // Attempt to find a saved context. | 444 // Attempt to find a saved context. |
| 443 GetVarDescriptors(); | 445 GetVarDescriptors(); |
| 444 intptr_t var_desc_len = var_descriptors_.Length(); | 446 intptr_t var_desc_len = var_descriptors_.Length(); |
| 445 for (intptr_t i = 0; i < var_desc_len; i++) { | 447 for (intptr_t i = 0; i < var_desc_len; i++) { |
| 446 RawLocalVarDescriptors::VarInfo var_info; | 448 RawLocalVarDescriptors::VarInfo var_info; |
| 447 var_descriptors_.GetInfo(i, &var_info); | 449 var_descriptors_.GetInfo(i, &var_info); |
| 448 if (var_info.kind == RawLocalVarDescriptors::kSavedEntryContext) { | 450 if (var_info.kind == RawLocalVarDescriptors::kSavedEntryContext) { |
| 451 if (FLAG_trace_debugger_stacktrace) { |
| 452 OS::PrintErr("\tFound saved entry ctx at index %" Pd "\n", |
| 453 var_info.index); |
| 454 } |
| 449 return GetLocalContextVar(var_info.index); | 455 return GetLocalContextVar(var_info.index); |
| 450 } | 456 } |
| 451 } | 457 } |
| 452 | 458 |
| 453 // No saved context. Return the current context. | 459 // No saved context. Return the current context. |
| 454 return ctx_.raw(); | 460 return ctx_.raw(); |
| 455 } | 461 } |
| 456 | 462 |
| 457 | 463 |
| 458 // Get the saved context if the callee of this activation frame is a | 464 // Get the saved context if the callee of this activation frame is a |
| 459 // closure function. | 465 // closure function. |
| 460 RawContext* ActivationFrame::GetSavedCurrentContext() { | 466 RawContext* ActivationFrame::GetSavedCurrentContext() { |
| 461 GetVarDescriptors(); | 467 GetVarDescriptors(); |
| 462 intptr_t var_desc_len = var_descriptors_.Length(); | 468 intptr_t var_desc_len = var_descriptors_.Length(); |
| 463 for (intptr_t i = 0; i < var_desc_len; i++) { | 469 for (intptr_t i = 0; i < var_desc_len; i++) { |
| 464 RawLocalVarDescriptors::VarInfo var_info; | 470 RawLocalVarDescriptors::VarInfo var_info; |
| 465 var_descriptors_.GetInfo(i, &var_info); | 471 var_descriptors_.GetInfo(i, &var_info); |
| 466 if (var_info.kind == RawLocalVarDescriptors::kSavedCurrentContext) { | 472 if (var_info.kind == RawLocalVarDescriptors::kSavedCurrentContext) { |
| 473 if (FLAG_trace_debugger_stacktrace) { |
| 474 OS::PrintErr("\tFound saved current ctx at index %" Pd "\n", |
| 475 var_info.index); |
| 476 } |
| 467 return GetLocalContextVar(var_info.index); | 477 return GetLocalContextVar(var_info.index); |
| 468 } | 478 } |
| 469 } | 479 } |
| 470 UNREACHABLE(); | 480 UNREACHABLE(); |
| 471 return Context::null(); | 481 return Context::null(); |
| 472 } | 482 } |
| 473 | 483 |
| 474 | 484 |
| 475 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( | 485 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( |
| 476 const Instance& exc_obj) const { | 486 const Instance& exc_obj) const { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 } else if (context.raw() == Symbols::OptimizedOut().raw()) { | 628 } else if (context.raw() == Symbols::OptimizedOut().raw()) { |
| 619 // The optimizing compiler has eliminated the saved context. | 629 // The optimizing compiler has eliminated the saved context. |
| 620 return Context::null(); | 630 return Context::null(); |
| 621 } else { | 631 } else { |
| 622 UNREACHABLE(); | 632 UNREACHABLE(); |
| 623 return Context::null(); | 633 return Context::null(); |
| 624 } | 634 } |
| 625 } | 635 } |
| 626 | 636 |
| 627 | 637 |
| 638 void ActivationFrame::PrintContextMismatchError( |
| 639 const String& var_name, |
| 640 intptr_t ctx_slot, |
| 641 intptr_t frame_ctx_level, |
| 642 intptr_t var_ctx_level) { |
| 643 OS::PrintErr("-------------------------\n" |
| 644 "Encountered context mismatch\n" |
| 645 "\tvar name: %s\n" |
| 646 "\tctx_slot: %" Pd "\n" |
| 647 "\tframe_ctx_level: %" Pd "\n" |
| 648 "\tvar_ctx_level: %" Pd "\n\n", |
| 649 var_name.ToCString(), |
| 650 ctx_slot, |
| 651 frame_ctx_level, |
| 652 var_ctx_level); |
| 653 |
| 654 OS::PrintErr("-------------------------\n" |
| 655 "Current frame:\n%s\n", |
| 656 this->ToCString()); |
| 657 |
| 658 OS::PrintErr("-------------------------\n" |
| 659 "Context contents:\n"); |
| 660 ctx_.Dump(8); |
| 661 |
| 662 OS::PrintErr("-------------------------\n" |
| 663 "Debugger stack trace...\n\n"); |
| 664 DebuggerStackTrace* stack = |
| 665 Isolate::Current()->debugger()->StackTrace(); |
| 666 intptr_t num_frames = stack->Length(); |
| 667 for (intptr_t i = 0; i < num_frames; i++) { |
| 668 ActivationFrame* frame = stack->FrameAt(i); |
| 669 OS::PrintErr("#%04" Pd " %s", i, frame->ToCString()); |
| 670 } |
| 671 |
| 672 OS::PrintErr("-------------------------\n" |
| 673 "All frames...\n\n"); |
| 674 StackFrameIterator iterator(false); |
| 675 StackFrame* frame = iterator.NextFrame(); |
| 676 intptr_t num = 0; |
| 677 while ((frame != NULL)) { |
| 678 frame = iterator.NextFrame(); |
| 679 OS::PrintErr("#%04" Pd " %s\n", num++, frame->ToCString()); |
| 680 } |
| 681 } |
| 682 |
| 683 |
| 628 void ActivationFrame::VariableAt(intptr_t i, | 684 void ActivationFrame::VariableAt(intptr_t i, |
| 629 String* name, | 685 String* name, |
| 630 intptr_t* token_pos, | 686 intptr_t* token_pos, |
| 631 intptr_t* end_pos, | 687 intptr_t* end_pos, |
| 632 Instance* value) { | 688 Instance* value) { |
| 633 GetDescIndices(); | 689 GetDescIndices(); |
| 634 ASSERT(i < desc_indices_.length()); | 690 ASSERT(i < desc_indices_.length()); |
| 635 intptr_t desc_index = desc_indices_[i]; | 691 intptr_t desc_index = desc_indices_[i]; |
| 636 ASSERT(name != NULL); | 692 ASSERT(name != NULL); |
| 637 *name ^= var_descriptors_.GetName(desc_index); | 693 *name ^= var_descriptors_.GetName(desc_index); |
| 638 RawLocalVarDescriptors::VarInfo var_info; | 694 RawLocalVarDescriptors::VarInfo var_info; |
| 639 var_descriptors_.GetInfo(desc_index, &var_info); | 695 var_descriptors_.GetInfo(desc_index, &var_info); |
| 640 ASSERT(token_pos != NULL); | 696 ASSERT(token_pos != NULL); |
| 641 *token_pos = var_info.begin_pos; | 697 *token_pos = var_info.begin_pos; |
| 642 ASSERT(end_pos != NULL); | 698 ASSERT(end_pos != NULL); |
| 643 *end_pos = var_info.end_pos; | 699 *end_pos = var_info.end_pos; |
| 644 ASSERT(value != NULL); | 700 ASSERT(value != NULL); |
| 645 if (var_info.kind == RawLocalVarDescriptors::kStackVar) { | 701 if (var_info.kind == RawLocalVarDescriptors::kStackVar) { |
| 646 *value = GetLocalInstanceVar(var_info.index); | 702 *value = GetLocalInstanceVar(var_info.index); |
| 647 } else { | 703 } else { |
| 648 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); | 704 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); |
| 649 if (ctx_.IsNull()) { | 705 if (ctx_.IsNull()) { |
| 650 // The context has been removed by the optimizing compiler. | 706 // The context has been removed by the optimizing compiler. |
| 707 // |
| 708 // TODO(turnidge): This may be erroneous. Revisit. |
| 651 *value = Symbols::OptimizedOut().raw(); | 709 *value = Symbols::OptimizedOut().raw(); |
| 652 return; | 710 return; |
| 653 } | 711 } |
| 654 | 712 |
| 655 // The context level at the PC/token index of this activation frame. | 713 // The context level at the PC/token index of this activation frame. |
| 656 intptr_t frame_ctx_level = ContextLevel(); | 714 intptr_t frame_ctx_level = ContextLevel(); |
| 657 | 715 |
| 658 // The context level of the variable. | 716 // The context level of the variable. |
| 659 intptr_t var_ctx_level = var_info.scope_id; | 717 intptr_t var_ctx_level = var_info.scope_id; |
| 660 intptr_t level_diff = frame_ctx_level - var_ctx_level; | 718 intptr_t level_diff = frame_ctx_level - var_ctx_level; |
| 661 intptr_t ctx_slot = var_info.index; | 719 intptr_t ctx_slot = var_info.index; |
| 662 if (level_diff == 0) { | 720 if (level_diff == 0) { |
| 721 if ((ctx_slot < 0) || |
| 722 (ctx_slot >= ctx_.num_variables())) { |
| 723 PrintContextMismatchError(*name, ctx_slot, |
| 724 frame_ctx_level, var_ctx_level); |
| 725 } |
| 663 ASSERT((ctx_slot >= 0) && (ctx_slot < ctx_.num_variables())); | 726 ASSERT((ctx_slot >= 0) && (ctx_slot < ctx_.num_variables())); |
| 664 *value = ctx_.At(ctx_slot); | 727 *value = ctx_.At(ctx_slot); |
| 665 } else { | 728 } else { |
| 666 ASSERT(level_diff > 0); | 729 ASSERT(level_diff > 0); |
| 667 Context& var_ctx = Context::Handle(ctx_.raw()); | 730 Context& var_ctx = Context::Handle(ctx_.raw()); |
| 668 while (level_diff > 0 && !var_ctx.IsNull()) { | 731 while (level_diff > 0 && !var_ctx.IsNull()) { |
| 669 level_diff--; | 732 level_diff--; |
| 670 var_ctx = var_ctx.parent(); | 733 var_ctx = var_ctx.parent(); |
| 671 } | 734 } |
| 735 if (var_ctx.IsNull() || |
| 736 (ctx_slot < 0) || |
| 737 (ctx_slot >= var_ctx.num_variables())) { |
| 738 PrintContextMismatchError(*name, ctx_slot, |
| 739 frame_ctx_level, var_ctx_level); |
| 740 } |
| 672 ASSERT(!var_ctx.IsNull()); | 741 ASSERT(!var_ctx.IsNull()); |
| 673 ASSERT((ctx_slot >= 0) && (ctx_slot < var_ctx.num_variables())); | 742 ASSERT((ctx_slot >= 0) && (ctx_slot < var_ctx.num_variables())); |
| 674 *value = var_ctx.At(ctx_slot); | 743 *value = var_ctx.At(ctx_slot); |
| 675 } | 744 } |
| 676 } | 745 } |
| 677 } | 746 } |
| 678 | 747 |
| 679 | 748 |
| 680 RawArray* ActivationFrame::GetLocalVariables() { | 749 RawArray* ActivationFrame::GetLocalVariables() { |
| 681 GetDescIndices(); | 750 GetDescIndices(); |
| 682 intptr_t num_variables = desc_indices_.length(); | 751 intptr_t num_variables = desc_indices_.length(); |
| 683 String& var_name = String::Handle(); | 752 String& var_name = String::Handle(); |
| 684 Instance& value = Instance::Handle(); | 753 Instance& value = Instance::Handle(); |
| 685 const Array& list = Array::Handle(Array::New(2 * num_variables)); | 754 const Array& list = Array::Handle(Array::New(2 * num_variables)); |
| 686 for (intptr_t i = 0; i < num_variables; i++) { | 755 for (intptr_t i = 0; i < num_variables; i++) { |
| 687 intptr_t ignore; | 756 intptr_t ignore; |
| 688 VariableAt(i, &var_name, &ignore, &ignore, &value); | 757 VariableAt(i, &var_name, &ignore, &ignore, &value); |
| 689 list.SetAt(2 * i, var_name); | 758 list.SetAt(2 * i, var_name); |
| 690 list.SetAt((2 * i) + 1, value); | 759 list.SetAt((2 * i) + 1, value); |
| 691 } | 760 } |
| 692 return list.raw(); | 761 return list.raw(); |
| 693 } | 762 } |
| 694 | 763 |
| 695 | 764 |
| 696 const char* ActivationFrame::ToCString() { | 765 const char* ActivationFrame::ToCString() { |
| 697 const char* kFormat = "Function: '%s' url: '%s' line: %d"; | |
| 698 | |
| 699 const String& url = String::Handle(SourceUrl()); | 766 const String& url = String::Handle(SourceUrl()); |
| 700 intptr_t line = LineNumber(); | 767 intptr_t line = LineNumber(); |
| 701 const char* func_name = Debugger::QualifiedFunctionName(function()); | 768 const char* func_name = Debugger::QualifiedFunctionName(function()); |
| 702 | 769 return Isolate::Current()->current_zone()-> |
| 703 intptr_t len = | 770 PrintToString("[ Frame pc(0x%" Px ") fp(0x%" Px ") sp(0x%" Px ")\n" |
| 704 OS::SNPrint(NULL, 0, kFormat, func_name, url.ToCString(), line); | 771 "\tfunction = %s\n" |
| 705 len++; // String terminator. | 772 "\turl = %s\n" |
| 706 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 773 "\tline = %" Pd "\n" |
| 707 OS::SNPrint(chars, len, kFormat, func_name, url.ToCString(), line); | 774 "\tcontext = %s\n" |
| 708 return chars; | 775 "\tcontext level = %" Pd " ]\n", |
| 776 pc(), fp(), sp(), |
| 777 func_name, |
| 778 url.ToCString(), |
| 779 line, |
| 780 ctx_.ToCString(), |
| 781 ContextLevel()); |
| 709 } | 782 } |
| 710 | 783 |
| 711 | 784 |
| 712 void ActivationFrame::PrintToJSONObject(JSONObject* jsobj) { | 785 void ActivationFrame::PrintToJSONObject(JSONObject* jsobj) { |
| 713 const Script& script = Script::Handle(SourceScript()); | 786 const Script& script = Script::Handle(SourceScript()); |
| 714 jsobj->AddProperty("script", script); | 787 jsobj->AddProperty("script", script); |
| 715 jsobj->AddProperty("tokenPos", TokenPos()); | 788 jsobj->AddProperty("tokenPos", TokenPos()); |
| 716 jsobj->AddProperty("function", function()); | 789 jsobj->AddProperty("function", function()); |
| 717 jsobj->AddProperty("code", code()); | 790 jsobj->AddProperty("code", code()); |
| 718 { | 791 { |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1058 intptr_t deopt_frame_offset, | 1131 intptr_t deopt_frame_offset, |
| 1059 ActivationFrame* callee_activation, | 1132 ActivationFrame* callee_activation, |
| 1060 const Context& entry_ctx) { | 1133 const Context& entry_ctx) { |
| 1061 // We provide either a callee activation or an entry context. Not both. | 1134 // We provide either a callee activation or an entry context. Not both. |
| 1062 ASSERT(((callee_activation != NULL) && entry_ctx.IsNull()) || | 1135 ASSERT(((callee_activation != NULL) && entry_ctx.IsNull()) || |
| 1063 ((callee_activation == NULL) && !entry_ctx.IsNull())); | 1136 ((callee_activation == NULL) && !entry_ctx.IsNull())); |
| 1064 ActivationFrame* activation = | 1137 ActivationFrame* activation = |
| 1065 new ActivationFrame(pc, frame->fp(), frame->sp(), code, | 1138 new ActivationFrame(pc, frame->fp(), frame->sp(), code, |
| 1066 deopt_frame, deopt_frame_offset); | 1139 deopt_frame, deopt_frame_offset); |
| 1067 | 1140 |
| 1141 // Is there a closure call at the current PC? |
| 1142 // |
| 1143 // We can't just check the callee_activation to see if it is a |
| 1144 // closure function, because it may not be on the stack yet. |
| 1145 bool is_closure_call = false; |
| 1146 const PcDescriptors& pc_desc = |
| 1147 PcDescriptors::Handle(code.pc_descriptors()); |
| 1148 ASSERT(code.ContainsInstructionAt(pc)); |
| 1149 for (int i = 0; i < pc_desc.Length(); i++) { |
| 1150 if (pc_desc.PC(i) == pc && |
| 1151 pc_desc.DescriptorKind(i) == PcDescriptors::kClosureCall) { |
| 1152 is_closure_call = true; |
| 1153 break; |
| 1154 } |
| 1155 } |
| 1156 |
| 1068 // Recover the context for this frame. | 1157 // Recover the context for this frame. |
| 1069 if (callee_activation == NULL) { | 1158 if (is_closure_call) { |
| 1070 // No callee. Use incoming entry context. Could be from | |
| 1071 // isolate's top context or from an entry frame. | |
| 1072 ASSERT(!entry_ctx.IsNull()); | |
| 1073 activation->SetContext(entry_ctx); | |
| 1074 | |
| 1075 } else if (callee_activation->function().IsClosureFunction()) { | |
| 1076 // If the callee is a closure, we should have stored the context | 1159 // If the callee is a closure, we should have stored the context |
| 1077 // in the current frame before making the call. | 1160 // in the current frame before making the call. |
| 1078 const Context& closure_call_ctx = | 1161 const Context& closure_call_ctx = |
| 1079 Context::Handle(isolate, activation->GetSavedCurrentContext()); | 1162 Context::Handle(isolate, activation->GetSavedCurrentContext()); |
| 1080 ASSERT(!closure_call_ctx.IsNull()); | 1163 ASSERT(!closure_call_ctx.IsNull()); |
| 1081 activation->SetContext(closure_call_ctx); | 1164 activation->SetContext(closure_call_ctx); |
| 1082 | 1165 if (FLAG_trace_debugger_stacktrace) { |
| 1166 OS::PrintErr("\tUsing closure call ctx: %s\n", |
| 1167 closure_call_ctx.ToCString()); |
| 1168 } |
| 1169 } else if (callee_activation == NULL) { |
| 1170 // No callee available. Use incoming entry context. Could be from |
| 1171 // isolate's top context or from an entry frame. |
| 1172 ASSERT(!entry_ctx.IsNull()); |
| 1173 activation->SetContext(entry_ctx); |
| 1174 if (FLAG_trace_debugger_stacktrace) { |
| 1175 OS::PrintErr("\tUsing entry ctx: %s\n", entry_ctx.ToCString()); |
| 1176 } |
| 1083 } else { | 1177 } else { |
| 1084 // Use the context provided by our callee. This is either the | 1178 // Use the context provided by our callee. This is either the |
| 1085 // callee's context or a context that was saved in the callee's | 1179 // callee's context or a context that was saved in the callee's |
| 1086 // frame. | 1180 // frame. |
| 1087 // | 1181 // |
| 1088 // The callee's saved context may be NULL if it was eliminated by | 1182 // The callee's saved context may be NULL if it was eliminated by |
| 1089 // the optimizing compiler. | 1183 // the optimizing compiler. |
| 1090 const Context& callee_ctx = | 1184 const Context& callee_ctx = |
| 1091 Context::Handle(isolate, callee_activation->GetSavedEntryContext()); | 1185 Context::Handle(isolate, callee_activation->GetSavedEntryContext()); |
| 1092 activation->SetContext(callee_ctx); | 1186 activation->SetContext(callee_ctx); |
| 1187 if (FLAG_trace_debugger_stacktrace) { |
| 1188 OS::PrintErr("\tUsing callee call ctx: %s\n", |
| 1189 callee_ctx.ToCString()); |
| 1190 } |
| 1191 } |
| 1192 if (FLAG_trace_debugger_stacktrace) { |
| 1193 OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber()); |
| 1093 } | 1194 } |
| 1094 return activation; | 1195 return activation; |
| 1095 } | 1196 } |
| 1096 | 1197 |
| 1097 | 1198 |
| 1098 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate, | 1199 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate, |
| 1099 StackFrame* frame, | 1200 StackFrame* frame, |
| 1100 const Code& code) { | 1201 const Code& code) { |
| 1101 ASSERT(code.is_optimized()); | 1202 ASSERT(code.is_optimized()); |
| 1102 | 1203 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1125 ActivationFrame* current_activation = NULL; | 1226 ActivationFrame* current_activation = NULL; |
| 1126 Context& entry_ctx = Context::Handle(isolate->top_context()); | 1227 Context& entry_ctx = Context::Handle(isolate->top_context()); |
| 1127 Code& code = Code::Handle(isolate); | 1228 Code& code = Code::Handle(isolate); |
| 1128 Code& inlined_code = Code::Handle(isolate); | 1229 Code& inlined_code = Code::Handle(isolate); |
| 1129 Array& deopt_frame = Array::Handle(isolate); | 1230 Array& deopt_frame = Array::Handle(isolate); |
| 1130 | 1231 |
| 1131 for (StackFrame* frame = iterator.NextFrame(); | 1232 for (StackFrame* frame = iterator.NextFrame(); |
| 1132 frame != NULL; | 1233 frame != NULL; |
| 1133 frame = iterator.NextFrame()) { | 1234 frame = iterator.NextFrame()) { |
| 1134 ASSERT(frame->IsValid()); | 1235 ASSERT(frame->IsValid()); |
| 1236 if (FLAG_trace_debugger_stacktrace) { |
| 1237 OS::PrintErr("CollectStackTrace: visiting frame:\n\t%s\n", |
| 1238 frame->ToCString()); |
| 1239 } |
| 1135 if (frame->IsEntryFrame()) { | 1240 if (frame->IsEntryFrame()) { |
| 1136 current_activation = NULL; | 1241 current_activation = NULL; |
| 1137 entry_ctx = reinterpret_cast<EntryFrame*>(frame)->SavedContext(); | 1242 entry_ctx = reinterpret_cast<EntryFrame*>(frame)->SavedContext(); |
| 1243 if (FLAG_trace_debugger_stacktrace) { |
| 1244 OS::PrintErr("\tFound saved ctx in entry frame:\n\t%s\n", |
| 1245 entry_ctx.ToCString()); |
| 1246 } |
| 1138 | 1247 |
| 1139 } else if (frame->IsDartFrame()) { | 1248 } else if (frame->IsDartFrame()) { |
| 1140 code = frame->LookupDartCode(); | 1249 code = frame->LookupDartCode(); |
| 1141 if (code.is_optimized()) { | 1250 if (code.is_optimized()) { |
| 1142 deopt_frame = DeoptimizeToArray(isolate, frame, code); | 1251 deopt_frame = DeoptimizeToArray(isolate, frame, code); |
| 1143 for (InlinedFunctionsIterator it(code, frame->pc()); | 1252 for (InlinedFunctionsIterator it(code, frame->pc()); |
| 1144 !it.Done(); | 1253 !it.Done(); |
| 1145 it.Advance()) { | 1254 it.Advance()) { |
| 1146 inlined_code = it.code(); | 1255 inlined_code = it.code(); |
| 1256 if (FLAG_trace_debugger_stacktrace) { |
| 1257 const Function& function = |
| 1258 Function::Handle(inlined_code.function()); |
| 1259 ASSERT(!function.IsNull()); |
| 1260 OS::PrintErr("CollectStackTrace: visiting inlined function: %s\n", |
| 1261 function.ToFullyQualifiedCString()); |
| 1262 } |
| 1147 intptr_t deopt_frame_offset = it.GetDeoptFpOffset(); | 1263 intptr_t deopt_frame_offset = it.GetDeoptFpOffset(); |
| 1148 current_activation = CollectDartFrame(isolate, | 1264 current_activation = CollectDartFrame(isolate, |
| 1149 it.pc(), | 1265 it.pc(), |
| 1150 frame, | 1266 frame, |
| 1151 inlined_code, | 1267 inlined_code, |
| 1152 deopt_frame, | 1268 deopt_frame, |
| 1153 deopt_frame_offset, | 1269 deopt_frame_offset, |
| 1154 current_activation, | 1270 current_activation, |
| 1155 entry_ctx); | 1271 entry_ctx); |
| 1156 stack_trace->AddActivation(current_activation); | 1272 stack_trace->AddActivation(current_activation); |
| (...skipping 1157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2314 } | 2430 } |
| 2315 | 2431 |
| 2316 | 2432 |
| 2317 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2433 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 2318 ASSERT(bpt->next() == NULL); | 2434 ASSERT(bpt->next() == NULL); |
| 2319 bpt->set_next(code_breakpoints_); | 2435 bpt->set_next(code_breakpoints_); |
| 2320 code_breakpoints_ = bpt; | 2436 code_breakpoints_ = bpt; |
| 2321 } | 2437 } |
| 2322 | 2438 |
| 2323 } // namespace dart | 2439 } // namespace dart |
| OLD | NEW |