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

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

Issue 678763004: Make CTX allocatable by the register allocator. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 1 month 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
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 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 context_level_ = var_info.index(); 451 context_level_ = var_info.index();
452 } 452 }
453 } 453 }
454 } 454 }
455 ASSERT(context_level_ >= 0); 455 ASSERT(context_level_ >= 0);
456 } 456 }
457 return context_level_; 457 return context_level_;
458 } 458 }
459 459
460 460
461 RawContext* ActivationFrame::GetSavedEntryContext() { 461 // Get the saved current context of this activation.
462 // Attempt to find a saved context.
463 GetVarDescriptors();
464 intptr_t var_desc_len = var_descriptors_.Length();
465 for (intptr_t i = 0; i < var_desc_len; i++) {
466 RawLocalVarDescriptors::VarInfo var_info;
467 var_descriptors_.GetInfo(i, &var_info);
468 const int8_t kind = var_info.kind();
469 if (kind == RawLocalVarDescriptors::kSavedEntryContext) {
470 if (FLAG_trace_debugger_stacktrace) {
471 OS::PrintErr("\tFound saved entry ctx at index %d\n", var_info.index());
472 }
473 return GetLocalContextVar(var_info.index());
474 }
475 }
476
477 // No saved context. Return the current context.
478 return ctx_.raw();
479 }
480
481
482 // Get the saved context if the callee of this activation frame is a
483 // closure function.
484 RawContext* ActivationFrame::GetSavedCurrentContext() { 462 RawContext* ActivationFrame::GetSavedCurrentContext() {
485 GetVarDescriptors(); 463 GetVarDescriptors();
486 intptr_t var_desc_len = var_descriptors_.Length(); 464 intptr_t var_desc_len = var_descriptors_.Length();
487 for (intptr_t i = 0; i < var_desc_len; i++) { 465 for (intptr_t i = 0; i < var_desc_len; i++) {
488 RawLocalVarDescriptors::VarInfo var_info; 466 RawLocalVarDescriptors::VarInfo var_info;
489 var_descriptors_.GetInfo(i, &var_info); 467 var_descriptors_.GetInfo(i, &var_info);
490 const int8_t kind = var_info.kind(); 468 const int8_t kind = var_info.kind();
491 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { 469 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) {
492 if (FLAG_trace_debugger_stacktrace) { 470 if (FLAG_trace_debugger_stacktrace) {
493 OS::PrintErr("\tFound saved current ctx at index %d\n", 471 OS::PrintErr("\tFound saved current ctx at index %d\n",
494 var_info.index()); 472 var_info.index());
495 } 473 }
496 return GetLocalContextVar(var_info.index()); 474 const Object& context = Object::Handle(GetLocalVar(var_info.index()));
hausner 2014/10/29 16:44:34 Would be nice if you could avoid the handle creati
Florian Schneider 2014/10/29 17:50:45 Done, but I still need a cast (the result of GetLo
475 ASSERT(context.IsContext());
476 return Context::Cast(context).raw();
497 } 477 }
498 } 478 }
499 UNREACHABLE(); 479 UNREACHABLE();
500 return Context::null(); 480 return Context::null();
501 } 481 }
502 482
503 483
504 const char* DebuggerEvent::EventTypeToCString(EventType type) { 484 const char* DebuggerEvent::EventTypeToCString(EventType type) {
505 switch (type) { 485 switch (type) {
506 case kBreakpointReached: 486 case kBreakpointReached:
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 } 651 }
672 652
673 653
674 RawInstance* ActivationFrame::GetLocalInstanceVar(intptr_t slot_index) { 654 RawInstance* ActivationFrame::GetLocalInstanceVar(intptr_t slot_index) {
675 Instance& instance = Instance::Handle(); 655 Instance& instance = Instance::Handle();
676 instance ^= GetLocalVar(slot_index); 656 instance ^= GetLocalVar(slot_index);
677 return instance.raw(); 657 return instance.raw();
678 } 658 }
679 659
680 660
681 RawContext* ActivationFrame::GetLocalContextVar(intptr_t slot_index) {
682 Object& context = Object::Handle(GetLocalVar(slot_index));
683 if (context.IsContext()) {
684 // We found a saved context.
685 return Context::Cast(context).raw();
686 } else if (context.raw() == Symbols::OptimizedOut().raw()) {
687 // The optimizing compiler has eliminated the saved context.
688 return Context::null();
689 } else {
690 UNREACHABLE();
691 return Context::null();
692 }
693 }
694
695
696 void ActivationFrame::PrintContextMismatchError( 661 void ActivationFrame::PrintContextMismatchError(
697 const String& var_name, 662 const String& var_name,
698 intptr_t ctx_slot, 663 intptr_t ctx_slot,
699 intptr_t frame_ctx_level, 664 intptr_t frame_ctx_level,
700 intptr_t var_ctx_level) { 665 intptr_t var_ctx_level) {
701 OS::PrintErr("-------------------------\n" 666 OS::PrintErr("-------------------------\n"
702 "Encountered context mismatch\n" 667 "Encountered context mismatch\n"
703 "\tvar name: %s\n" 668 "\tvar name: %s\n"
704 "\tctx_slot: %" Pd "\n" 669 "\tctx_slot: %" Pd "\n"
705 "\tframe_ctx_level: %" Pd "\n" 670 "\tframe_ctx_level: %" Pd "\n"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 ASSERT(token_pos != NULL); 719 ASSERT(token_pos != NULL);
755 *token_pos = var_info.begin_pos; 720 *token_pos = var_info.begin_pos;
756 ASSERT(end_pos != NULL); 721 ASSERT(end_pos != NULL);
757 *end_pos = var_info.end_pos; 722 *end_pos = var_info.end_pos;
758 ASSERT(value != NULL); 723 ASSERT(value != NULL);
759 const int8_t kind = var_info.kind(); 724 const int8_t kind = var_info.kind();
760 if (kind == RawLocalVarDescriptors::kStackVar) { 725 if (kind == RawLocalVarDescriptors::kStackVar) {
761 *value = GetLocalInstanceVar(var_info.index()); 726 *value = GetLocalInstanceVar(var_info.index());
762 } else { 727 } else {
763 ASSERT(kind == RawLocalVarDescriptors::kContextVar); 728 ASSERT(kind == RawLocalVarDescriptors::kContextVar);
764 if (ctx_.IsNull()) { 729 ASSERT(!ctx_.IsNull());
765 // The context has been removed by the optimizing compiler.
766 //
767 // TODO(turnidge): This may be erroneous. Revisit.
768 *value = Symbols::OptimizedOut().raw();
769 return;
770 }
771 730
772 // The context level at the PC/token index of this activation frame. 731 // The context level at the PC/token index of this activation frame.
773 intptr_t frame_ctx_level = ContextLevel(); 732 intptr_t frame_ctx_level = ContextLevel();
774 733
775 // The context level of the variable. 734 // The context level of the variable.
776 intptr_t var_ctx_level = var_info.scope_id; 735 intptr_t var_ctx_level = var_info.scope_id;
777 intptr_t level_diff = frame_ctx_level - var_ctx_level; 736 intptr_t level_diff = frame_ctx_level - var_ctx_level;
778 intptr_t ctx_slot = var_info.index(); 737 intptr_t ctx_slot = var_info.index();
779 if (level_diff == 0) { 738 if (level_diff == 0) {
780 if ((ctx_slot < 0) || 739 if ((ctx_slot < 0) ||
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 InvokeEventHandler(&event); 1186 InvokeEventHandler(&event);
1228 } 1187 }
1229 } 1188 }
1230 1189
1231 1190
1232 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, 1191 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate,
1233 uword pc, 1192 uword pc,
1234 StackFrame* frame, 1193 StackFrame* frame,
1235 const Code& code, 1194 const Code& code,
1236 const Array& deopt_frame, 1195 const Array& deopt_frame,
1237 intptr_t deopt_frame_offset, 1196 intptr_t deopt_frame_offset) {
1238 ActivationFrame* callee_activation,
1239 const Context& entry_ctx) {
1240 ASSERT(code.ContainsInstructionAt(pc)); 1197 ASSERT(code.ContainsInstructionAt(pc));
1241 // We provide either a callee activation or an entry context. Not both.
1242 ASSERT(((callee_activation != NULL) && entry_ctx.IsNull()) ||
1243 ((callee_activation == NULL) && !entry_ctx.IsNull()));
1244 ActivationFrame* activation = 1198 ActivationFrame* activation =
1245 new ActivationFrame(pc, frame->fp(), frame->sp(), code, 1199 new ActivationFrame(pc, frame->fp(), frame->sp(), code,
1246 deopt_frame, deopt_frame_offset); 1200 deopt_frame, deopt_frame_offset);
1247 1201
1248 // Is there a closure call at the current PC? 1202 // Is there a closure call at the current PC?
1249 //
1250 // We can't just check the callee_activation to see if it is a
1251 // closure function, because it may not be on the stack yet.
1252 bool is_closure_call = false; 1203 bool is_closure_call = false;
1253 const PcDescriptors& pc_desc = 1204 const PcDescriptors& pc_desc =
1254 PcDescriptors::Handle(isolate, code.pc_descriptors()); 1205 PcDescriptors::Handle(isolate, code.pc_descriptors());
1255 PcDescriptors::Iterator iter(pc_desc, RawPcDescriptors::kClosureCall); 1206 PcDescriptors::Iterator iter(pc_desc, RawPcDescriptors::kClosureCall);
1256 while (iter.MoveNext()) { 1207 while (iter.MoveNext()) {
1257 if (iter.Pc() == pc) { 1208 if (iter.Pc() == pc) {
1258 is_closure_call = true; 1209 is_closure_call = true;
1259 break; 1210 break;
1260 } 1211 }
1261 } 1212 }
1262 1213
1263 // Recover the context for this frame. 1214 // Recover the context for this frame.
1264 if (is_closure_call) { 1215 if (is_closure_call) {
1265 // If the callee is a closure, we should have stored the context 1216 // If the callee is a closure, we should have stored the context
1266 // in the current frame before making the call. 1217 // in the current frame before making the call.
1267 const Context& closure_call_ctx = 1218 const Context& closure_call_ctx =
1268 Context::Handle(isolate, activation->GetSavedCurrentContext()); 1219 Context::Handle(isolate, activation->GetSavedCurrentContext());
1269 ASSERT(!closure_call_ctx.IsNull()); 1220 ASSERT(!closure_call_ctx.IsNull());
1270 activation->SetContext(closure_call_ctx); 1221 activation->SetContext(closure_call_ctx);
1271 if (FLAG_trace_debugger_stacktrace) { 1222 if (FLAG_trace_debugger_stacktrace) {
1272 OS::PrintErr("\tUsing closure call ctx: %s\n", 1223 OS::PrintErr("\tUsing closure call ctx: %s\n",
1273 closure_call_ctx.ToCString()); 1224 closure_call_ctx.ToCString());
1274 } 1225 }
1275 } else if (callee_activation == NULL) { 1226 } else {
1276 // No callee available. Use incoming entry context. Could be from 1227 const Context& ctx =
1277 // isolate's top context or from an entry frame. 1228 Context::Handle(isolate, activation->GetSavedCurrentContext());
1278 ASSERT(!entry_ctx.IsNull()); 1229 ASSERT(!ctx.IsNull());
1279 activation->SetContext(entry_ctx); 1230 activation->SetContext(ctx);
1280 if (FLAG_trace_debugger_stacktrace) { 1231 if (FLAG_trace_debugger_stacktrace) {
1281 OS::PrintErr("\tUsing entry ctx: %s\n", entry_ctx.ToCString()); 1232 OS::PrintErr("\tUsing entry ctx: %s\n", ctx.ToCString());
1282 }
1283 } else {
1284 // Use the context provided by our callee. This is either the
1285 // callee's context or a context that was saved in the callee's
1286 // frame.
1287 //
1288 // The callee's saved context may be NULL if it was eliminated by
1289 // the optimizing compiler.
1290 const Context& callee_ctx =
1291 Context::Handle(isolate, callee_activation->GetSavedEntryContext());
1292 activation->SetContext(callee_ctx);
1293 if (FLAG_trace_debugger_stacktrace) {
1294 OS::PrintErr("\tUsing callee call ctx: %s\n",
1295 callee_ctx.ToCString());
1296 } 1233 }
1297 } 1234 }
1298 if (FLAG_trace_debugger_stacktrace) { 1235 if (FLAG_trace_debugger_stacktrace) {
1299 OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber()); 1236 OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber());
1300 } 1237 }
1301 return activation; 1238 return activation;
1302 } 1239 }
1303 1240
1304 1241
1305 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate, 1242 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate,
(...skipping 17 matching lines...) Expand all
1323 delete deopt_context; 1260 delete deopt_context;
1324 1261
1325 return dest_frame.raw(); 1262 return dest_frame.raw();
1326 } 1263 }
1327 1264
1328 1265
1329 DebuggerStackTrace* Debugger::CollectStackTrace() { 1266 DebuggerStackTrace* Debugger::CollectStackTrace() {
1330 Isolate* isolate = Isolate::Current(); 1267 Isolate* isolate = Isolate::Current();
1331 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); 1268 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8);
1332 StackFrameIterator iterator(false); 1269 StackFrameIterator iterator(false);
1333 ActivationFrame* current_activation = NULL;
1334 Context& entry_ctx = Context::Handle(isolate, isolate->top_context());
1335 Code& code = Code::Handle(isolate); 1270 Code& code = Code::Handle(isolate);
1336 Code& inlined_code = Code::Handle(isolate); 1271 Code& inlined_code = Code::Handle(isolate);
1337 Array& deopt_frame = Array::Handle(isolate); 1272 Array& deopt_frame = Array::Handle(isolate);
1338 1273
1339 for (StackFrame* frame = iterator.NextFrame(); 1274 for (StackFrame* frame = iterator.NextFrame();
1340 frame != NULL; 1275 frame != NULL;
1341 frame = iterator.NextFrame()) { 1276 frame = iterator.NextFrame()) {
1342 ASSERT(frame->IsValid()); 1277 ASSERT(frame->IsValid());
1343 if (FLAG_trace_debugger_stacktrace) { 1278 if (FLAG_trace_debugger_stacktrace) {
1344 OS::PrintErr("CollectStackTrace: visiting frame:\n\t%s\n", 1279 OS::PrintErr("CollectStackTrace: visiting frame:\n\t%s\n",
1345 frame->ToCString()); 1280 frame->ToCString());
1346 } 1281 }
1347 if (frame->IsEntryFrame()) { 1282 if (frame->IsDartFrame()) {
1348 current_activation = NULL;
1349 entry_ctx = reinterpret_cast<EntryFrame*>(frame)->SavedContext();
1350 if (FLAG_trace_debugger_stacktrace) {
1351 OS::PrintErr("\tFound saved ctx in entry frame:\n\t%s\n",
1352 entry_ctx.ToCString());
1353 }
1354
1355 } else if (frame->IsDartFrame()) {
1356 code = frame->LookupDartCode(); 1283 code = frame->LookupDartCode();
1357 if (code.is_optimized()) { 1284 if (code.is_optimized()) {
1358 deopt_frame = DeoptimizeToArray(isolate, frame, code); 1285 deopt_frame = DeoptimizeToArray(isolate, frame, code);
1359 for (InlinedFunctionsIterator it(code, frame->pc()); 1286 for (InlinedFunctionsIterator it(code, frame->pc());
1360 !it.Done(); 1287 !it.Done();
1361 it.Advance()) { 1288 it.Advance()) {
1362 inlined_code = it.code(); 1289 inlined_code = it.code();
1363 if (FLAG_trace_debugger_stacktrace) { 1290 if (FLAG_trace_debugger_stacktrace) {
1364 const Function& function = 1291 const Function& function =
1365 Function::Handle(isolate, inlined_code.function()); 1292 Function::Handle(isolate, inlined_code.function());
1366 ASSERT(!function.IsNull()); 1293 ASSERT(!function.IsNull());
1367 OS::PrintErr("CollectStackTrace: visiting inlined function: %s\n", 1294 OS::PrintErr("CollectStackTrace: visiting inlined function: %s\n",
1368 function.ToFullyQualifiedCString()); 1295 function.ToFullyQualifiedCString());
1369 } 1296 }
1370 intptr_t deopt_frame_offset = it.GetDeoptFpOffset(); 1297 intptr_t deopt_frame_offset = it.GetDeoptFpOffset();
1371 current_activation = CollectDartFrame(isolate, 1298 stack_trace->AddActivation(CollectDartFrame(isolate,
1372 it.pc(), 1299 it.pc(),
1373 frame, 1300 frame,
1374 inlined_code, 1301 inlined_code,
1375 deopt_frame, 1302 deopt_frame,
1376 deopt_frame_offset, 1303 deopt_frame_offset));
1377 current_activation,
1378 entry_ctx);
1379 stack_trace->AddActivation(current_activation);
1380 entry_ctx = Context::null(); // Only use entry context once.
1381 } 1304 }
1382 } else { 1305 } else {
1383 current_activation = CollectDartFrame(isolate, 1306 stack_trace->AddActivation(CollectDartFrame(isolate,
1384 frame->pc(), 1307 frame->pc(),
1385 frame, 1308 frame,
1386 code, 1309 code,
1387 Object::null_array(), 1310 Object::null_array(),
1388 0, 1311 0));
1389 current_activation,
1390 entry_ctx);
1391 stack_trace->AddActivation(current_activation);
1392 entry_ctx = Context::null(); // Only use entry context once.
1393 } 1312 }
1394 } 1313 }
1395 } 1314 }
1396 return stack_trace; 1315 return stack_trace;
1397 } 1316 }
1398 1317
1399 1318
1400 ActivationFrame* Debugger::TopDartFrame() const { 1319 ActivationFrame* Debugger::TopDartFrame() const {
1401 StackFrameIterator iterator(false); 1320 StackFrameIterator iterator(false);
1402 StackFrame* frame = iterator.NextFrame(); 1321 StackFrame* frame = iterator.NextFrame();
(...skipping 1189 matching lines...) Expand 10 before | Expand all | Expand 10 after
2592 } 2511 }
2593 2512
2594 2513
2595 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 2514 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
2596 ASSERT(bpt->next() == NULL); 2515 ASSERT(bpt->next() == NULL);
2597 bpt->set_next(code_breakpoints_); 2516 bpt->set_next(code_breakpoints_);
2598 code_breakpoints_ = bpt; 2517 code_breakpoints_ = bpt;
2599 } 2518 }
2600 2519
2601 } // namespace dart 2520 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/exceptions.cc » ('j') | runtime/vm/parser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698