Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(404)

Side by Side Diff: runtime/vm/debugger.cc

Issue 27226004: Allow access to context variables in optimized/inlined frames. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 void SourceBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { 119 void SourceBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) {
120 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); 120 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_));
121 } 121 }
122 122
123 123
124 124
125 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { 125 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) {
126 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); 126 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_));
127 } 127 }
128 128
129 129 ActivationFrame::ActivationFrame(
130 ActivationFrame::ActivationFrame(uword pc, uword fp, uword sp, const Code& code) 130 uword pc,
131 uword fp,
132 uword sp,
133 const Code& code,
134 const Array& deopt_frame,
135 intptr_t deopt_frame_offset)
131 : pc_(pc), fp_(fp), sp_(sp), 136 : pc_(pc), fp_(fp), sp_(sp),
132 ctx_(Context::ZoneHandle()), 137 ctx_(Context::ZoneHandle()),
133 code_(Code::ZoneHandle(code.raw())), 138 code_(Code::ZoneHandle(code.raw())),
134 function_(Function::ZoneHandle(code.function())), 139 function_(Function::ZoneHandle(code.function())),
135 token_pos_(-1), 140 token_pos_(-1),
136 pc_desc_index_(-1), 141 pc_desc_index_(-1),
137 line_number_(-1), 142 line_number_(-1),
138 context_level_(-1), 143 context_level_(-1),
139 deopt_frame_(Array::ZoneHandle()), 144 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())),
140 deopt_frame_offset_(0), 145 deopt_frame_offset_(deopt_frame_offset),
141 vars_initialized_(false), 146 vars_initialized_(false),
142 var_descriptors_(LocalVarDescriptors::ZoneHandle()), 147 var_descriptors_(LocalVarDescriptors::ZoneHandle()),
143 desc_indices_(8), 148 desc_indices_(8),
144 pc_desc_(PcDescriptors::ZoneHandle()) { 149 pc_desc_(PcDescriptors::ZoneHandle()) {
145 } 150 }
146 151
147 152
148 void Debugger::SignalIsolateEvent(EventType type) { 153 void Debugger::SignalIsolateEvent(EventType type) {
149 if (event_handler_ != NULL) { 154 if (event_handler_ != NULL) {
150 Debugger* debugger = Isolate::Current()->debugger(); 155 Debugger* debugger = Isolate::Current()->debugger();
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 ASSERT(end_pos != NULL); 578 ASSERT(end_pos != NULL);
574 *end_pos = var_info.end_pos; 579 *end_pos = var_info.end_pos;
575 ASSERT(value != NULL); 580 ASSERT(value != NULL);
576 if (var_info.kind == RawLocalVarDescriptors::kStackVar) { 581 if (var_info.kind == RawLocalVarDescriptors::kStackVar) {
577 *value = GetLocalInstanceVar(var_info.index); 582 *value = GetLocalInstanceVar(var_info.index);
578 } else { 583 } else {
579 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); 584 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar);
580 // The context level at the PC/token index of this activation frame. 585 // The context level at the PC/token index of this activation frame.
581 intptr_t frame_ctx_level = ContextLevel(); 586 intptr_t frame_ctx_level = ContextLevel();
582 if (ctx_.IsNull()) { 587 if (ctx_.IsNull()) {
588 if (FLAG_use_new_stacktrace) {
589 UNREACHABLE(); // ctx_ should never be null.
590 }
583 *value = Symbols::New("<unknown>"); 591 *value = Symbols::New("<unknown>");
584 return; 592 return;
585 } 593 }
586 // The context level of the variable. 594 // The context level of the variable.
587 intptr_t var_ctx_level = var_info.scope_id; 595 intptr_t var_ctx_level = var_info.scope_id;
588 intptr_t level_diff = frame_ctx_level - var_ctx_level; 596 intptr_t level_diff = frame_ctx_level - var_ctx_level;
589 intptr_t ctx_slot = var_info.index; 597 intptr_t ctx_slot = var_info.index;
590 if (level_diff == 0) { 598 if (level_diff == 0) {
591 // TODO(12767) : Need to ensure that we end up with the correct context 599 // TODO(12767) : Need to ensure that we end up with the correct context
592 // here so that this check can be an assert. 600 // here so that this check can be an assert.
593 if ((ctx_slot < ctx_.num_variables()) && (ctx_slot >= 0)) { 601 if ((ctx_slot < ctx_.num_variables()) && (ctx_slot >= 0)) {
594 *value = ctx_.At(ctx_slot); 602 *value = ctx_.At(ctx_slot);
595 } else { 603 } else {
604 if (FLAG_use_new_stacktrace) {
605 UNREACHABLE(); // ctx_ should be correct.
606 }
596 *value = Symbols::New("<unknown>"); 607 *value = Symbols::New("<unknown>");
597 } 608 }
598 } else { 609 } else {
599 ASSERT(level_diff > 0); 610 ASSERT(level_diff > 0);
600 Context& var_ctx = Context::Handle(ctx_.raw()); 611 Context& var_ctx = Context::Handle(ctx_.raw());
601 while (level_diff > 0 && !var_ctx.IsNull()) { 612 while (level_diff > 0 && !var_ctx.IsNull()) {
602 level_diff--; 613 level_diff--;
603 var_ctx = var_ctx.parent(); 614 var_ctx = var_ctx.parent();
604 } 615 }
605 // TODO(12767) : Need to ensure that we end up with the correct context 616 // TODO(12767) : Need to ensure that we end up with the correct context
606 // here so that this check can be assert. 617 // here so that this check can be assert.
607 if (!var_ctx.IsNull() && 618 if (!var_ctx.IsNull() &&
608 ((ctx_slot < var_ctx.num_variables()) && (ctx_slot >= 0))) { 619 ((ctx_slot < var_ctx.num_variables()) && (ctx_slot >= 0))) {
609 *value = var_ctx.At(ctx_slot); 620 *value = var_ctx.At(ctx_slot);
610 } else { 621 } else {
622 if (FLAG_use_new_stacktrace) {
623 UNREACHABLE(); // var_ctx should be correct.
624 }
611 *value = Symbols::New("<unknown>"); 625 *value = Symbols::New("<unknown>");
612 } 626 }
613 } 627 }
614 } 628 }
615 } 629 }
616 630
617 631
618 RawArray* ActivationFrame::GetLocalVariables() { 632 RawArray* ActivationFrame::GetLocalVariables() {
619 GetDescIndices(); 633 GetDescIndices();
620 intptr_t num_variables = desc_indices_.length(); 634 intptr_t num_variables = desc_indices_.length();
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 current.ToFullyQualifiedCString(), 1030 current.ToFullyQualifiedCString(),
1017 callee.ToFullyQualifiedCString(), 1031 callee.ToFullyQualifiedCString(),
1018 line, col); 1032 line, col);
1019 } 1033 }
1020 1034
1021 1035
1022 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, 1036 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate,
1023 uword pc, 1037 uword pc,
1024 StackFrame* frame, 1038 StackFrame* frame,
1025 const Code& code, 1039 const Code& code,
1026 bool optimized, 1040 const Array& deopt_frame,
1041 intptr_t deopt_frame_offset,
1027 ActivationFrame* callee_activation, 1042 ActivationFrame* callee_activation,
1028 const Context& entry_ctx) { 1043 const Context& entry_ctx) {
1029 // We never provide both a callee activation and an entry context. 1044 // We provide either a callee activation or an entry context. Not both.
1030 ASSERT((callee_activation == NULL) || entry_ctx.IsNull()); 1045 ASSERT((callee_activation == NULL) || entry_ctx.IsNull());
1046 ASSERT((callee_activation != NULL) || !entry_ctx.IsNull());
siva 2013/10/15 17:39:12 The two asserts seem hard to read together, I am w
turnidge 2013/10/15 18:07:28 Done.
1031 ActivationFrame* activation = 1047 ActivationFrame* activation =
1032 new ActivationFrame(pc, frame->fp(), frame->sp(), code); 1048 new ActivationFrame(pc, frame->fp(), frame->sp(), code,
1049 deopt_frame, deopt_frame_offset);
1033 1050
1034 // Recover the context for this frame. 1051 // Recover the context for this frame.
1035 if (optimized) { 1052 if (callee_activation == NULL) {
1036 // Bail out for optimized frames for now.
1037 activation->SetContext(Context::Handle(isolate));
1038
1039 } else if (callee_activation == NULL) {
1040 // No callee. Use incoming entry context. Could be from 1053 // No callee. Use incoming entry context. Could be from
1041 // isolate's top context or from an entry frame. 1054 // isolate's top context or from an entry frame.
1042 activation->SetContext(entry_ctx); 1055 activation->SetContext(entry_ctx);
1043 1056
1044 } else if (callee_activation->function().IsClosureFunction()) { 1057 } else if (callee_activation->function().IsClosureFunction()) {
1045 // If the callee is a closure, we should have stored the context 1058 // If the callee is a closure, we should have stored the context
1046 // in the current frame before making the call. 1059 // in the current frame before making the call.
1047 const Context& closure_call_ctx = 1060 const Context& closure_call_ctx =
1048 Context::Handle(isolate, activation->GetSavedCurrentContext()); 1061 Context::Handle(isolate, activation->GetSavedCurrentContext());
1049 activation->SetContext(closure_call_ctx); 1062 activation->SetContext(closure_call_ctx);
1050 1063
1051 // Sometimes there is no saved context. This is a bug. 1064 // Sometimes there is no saved context. This is a bug.
1052 // https://code.google.com/p/dart/issues/detail?id=12767 1065 // https://code.google.com/p/dart/issues/detail?id=12767
1053 if (FLAG_verbose_debug && closure_call_ctx.IsNull()) { 1066 if ((FLAG_verbose_debug || FLAG_use_new_stacktrace) &&
1067 closure_call_ctx.IsNull()) {
1054 PrintStackTraceError( 1068 PrintStackTraceError(
1055 "Expected to find saved context for call to closure function", 1069 "Expected to find saved context for call to closure function",
1056 activation, callee_activation); 1070 activation, callee_activation);
1071 if (FLAG_use_new_stacktrace) {
1072 UNREACHABLE(); // This bug should be fixed with new stack collection.
1073 }
1057 } 1074 }
1058 1075
1059 } else { 1076 } else {
1060 // Use the context provided by our callee. This is either the 1077 // Use the context provided by our callee. This is either the
1061 // callee's context or a context that was saved in the callee's 1078 // callee's context or a context that was saved in the callee's
1062 // frame. 1079 // frame.
1063 const Context& callee_ctx = 1080 const Context& callee_ctx =
1064 Context::Handle(isolate, callee_activation->GetSavedEntryContextNew()); 1081 Context::Handle(isolate, callee_activation->GetSavedEntryContextNew());
1065 activation->SetContext(callee_ctx); 1082 activation->SetContext(callee_ctx);
1066 } 1083 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1115 deopt_frame = DeoptimizeToArray(isolate, frame, code); 1132 deopt_frame = DeoptimizeToArray(isolate, frame, code);
1116 for (InlinedFunctionsIterator it(code, frame->pc()); 1133 for (InlinedFunctionsIterator it(code, frame->pc());
1117 !it.Done(); 1134 !it.Done();
1118 it.Advance()) { 1135 it.Advance()) {
1119 inlined_code = it.code(); 1136 inlined_code = it.code();
1120 intptr_t deopt_frame_offset = it.GetDeoptFpOffset(); 1137 intptr_t deopt_frame_offset = it.GetDeoptFpOffset();
1121 current_activation = CollectDartFrame(isolate, 1138 current_activation = CollectDartFrame(isolate,
1122 it.pc(), 1139 it.pc(),
1123 frame, 1140 frame,
1124 inlined_code, 1141 inlined_code,
1125 true, 1142 deopt_frame,
1143 deopt_frame_offset,
1126 current_activation, 1144 current_activation,
1127 entry_ctx); 1145 entry_ctx);
1128 current_activation->SetDeoptFrame(deopt_frame, deopt_frame_offset);
1129 stack_trace->AddActivation(current_activation); 1146 stack_trace->AddActivation(current_activation);
1130 entry_ctx = Context::null(); // Only use entry context once. 1147 entry_ctx = Context::null(); // Only use entry context once.
1131 } 1148 }
1132 } else { 1149 } else {
1133 current_activation = CollectDartFrame(isolate, 1150 current_activation = CollectDartFrame(isolate,
1134 frame->pc(), 1151 frame->pc(),
1135 frame, 1152 frame,
1136 code, 1153 code,
1137 false, 1154 Object::null_array(),
1155 0,
1138 current_activation, 1156 current_activation,
1139 entry_ctx); 1157 entry_ctx);
1140 stack_trace->AddActivation(current_activation); 1158 stack_trace->AddActivation(current_activation);
1141 entry_ctx = Context::null(); // Only use entry context once. 1159 entry_ctx = Context::null(); // Only use entry context once.
1142 } 1160 }
1143 } 1161 }
1144 } 1162 }
1145 return stack_trace; 1163 return stack_trace;
1146 } 1164 }
1147 1165
(...skipping 12 matching lines...) Expand all
1160 StackFrameIterator iterator(false); 1178 StackFrameIterator iterator(false);
1161 ActivationFrame* callee_activation = NULL; 1179 ActivationFrame* callee_activation = NULL;
1162 bool optimized_frame_found = false; 1180 bool optimized_frame_found = false;
1163 for (StackFrame* frame = iterator.NextFrame(); 1181 for (StackFrame* frame = iterator.NextFrame();
1164 frame != NULL; 1182 frame != NULL;
1165 frame = iterator.NextFrame()) { 1183 frame = iterator.NextFrame()) {
1166 ASSERT(frame->IsValid()); 1184 ASSERT(frame->IsValid());
1167 if (frame->IsDartFrame()) { 1185 if (frame->IsDartFrame()) {
1168 code = frame->LookupDartCode(); 1186 code = frame->LookupDartCode();
1169 ActivationFrame* activation = 1187 ActivationFrame* activation =
1170 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code); 1188 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code,
1189 Object::null_array(), 0);
1171 // If this activation frame called a closure, the function has 1190 // If this activation frame called a closure, the function has
1172 // saved its context before the call. 1191 // saved its context before the call.
1173 if ((callee_activation != NULL) && 1192 if ((callee_activation != NULL) &&
1174 (callee_activation->function().IsClosureFunction())) { 1193 (callee_activation->function().IsClosureFunction())) {
1175 ctx = activation->GetSavedCurrentContext(); 1194 ctx = activation->GetSavedCurrentContext();
1176 if (FLAG_verbose_debug && ctx.IsNull()) { 1195 if (FLAG_verbose_debug && ctx.IsNull()) {
1177 const Function& caller = activation->function(); 1196 const Function& caller = activation->function();
1178 const Function& callee = callee_activation->function(); 1197 const Function& callee = callee_activation->function();
1179 const Script& script = 1198 const Script& script =
1180 Script::Handle(Class::Handle(caller.Owner()).script()); 1199 Script::Handle(Class::Handle(caller.Owner()).script());
(...skipping 29 matching lines...) Expand all
1210 1229
1211 1230
1212 ActivationFrame* Debugger::TopDartFrame() const { 1231 ActivationFrame* Debugger::TopDartFrame() const {
1213 StackFrameIterator iterator(false); 1232 StackFrameIterator iterator(false);
1214 StackFrame* frame = iterator.NextFrame(); 1233 StackFrame* frame = iterator.NextFrame();
1215 while ((frame != NULL) && !frame->IsDartFrame()) { 1234 while ((frame != NULL) && !frame->IsDartFrame()) {
1216 frame = iterator.NextFrame(); 1235 frame = iterator.NextFrame();
1217 } 1236 }
1218 Code& code = Code::Handle(isolate_, frame->LookupDartCode()); 1237 Code& code = Code::Handle(isolate_, frame->LookupDartCode());
1219 ActivationFrame* activation = 1238 ActivationFrame* activation =
1220 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code); 1239 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code,
1240 Object::null_array(), 0);
1221 return activation; 1241 return activation;
1222 } 1242 }
1223 1243
1224 1244
1225 DebuggerStackTrace* Debugger::StackTrace() { 1245 DebuggerStackTrace* Debugger::StackTrace() {
1226 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace(); 1246 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace();
1227 } 1247 }
1228 1248
1229 1249
1230 void Debugger::SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info) { 1250 void Debugger::SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info) {
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after
2084 } 2104 }
2085 2105
2086 2106
2087 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 2107 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
2088 ASSERT(bpt->next() == NULL); 2108 ASSERT(bpt->next() == NULL);
2089 bpt->set_next(code_breakpoints_); 2109 bpt->set_next(code_breakpoints_);
2090 code_breakpoints_ = bpt; 2110 code_breakpoints_ = bpt;
2091 } 2111 }
2092 2112
2093 } // namespace dart 2113 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698