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

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: incorporated latest comments 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 ASSERT(Object::Handle(GetLocalVar(var_info.index())).IsContext());
475 return reinterpret_cast<RawContext*>(GetLocalVar(var_info.index()));
Vyacheslav Egorov (Google) 2014/10/30 15:05:35 We did not worry much in the previous code about H
Florian Schneider 2014/10/30 15:24:31 It's probably not performance critical here. I don
497 } 476 }
498 } 477 }
499 UNREACHABLE(); 478 UNREACHABLE();
500 return Context::null(); 479 return Context::null();
501 } 480 }
502 481
503 482
504 const char* DebuggerEvent::EventTypeToCString(EventType type) { 483 const char* DebuggerEvent::EventTypeToCString(EventType type) {
505 switch (type) { 484 switch (type) {
506 case kBreakpointReached: 485 case kBreakpointReached:
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 } 650 }
672 651
673 652
674 RawInstance* ActivationFrame::GetLocalInstanceVar(intptr_t slot_index) { 653 RawInstance* ActivationFrame::GetLocalInstanceVar(intptr_t slot_index) {
675 Instance& instance = Instance::Handle(); 654 Instance& instance = Instance::Handle();
676 instance ^= GetLocalVar(slot_index); 655 instance ^= GetLocalVar(slot_index);
677 return instance.raw(); 656 return instance.raw();
678 } 657 }
679 658
680 659
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( 660 void ActivationFrame::PrintContextMismatchError(
697 const String& var_name, 661 const String& var_name,
698 intptr_t ctx_slot, 662 intptr_t ctx_slot,
699 intptr_t frame_ctx_level, 663 intptr_t frame_ctx_level,
700 intptr_t var_ctx_level) { 664 intptr_t var_ctx_level) {
701 OS::PrintErr("-------------------------\n" 665 OS::PrintErr("-------------------------\n"
702 "Encountered context mismatch\n" 666 "Encountered context mismatch\n"
703 "\tvar name: %s\n" 667 "\tvar name: %s\n"
704 "\tctx_slot: %" Pd "\n" 668 "\tctx_slot: %" Pd "\n"
705 "\tframe_ctx_level: %" Pd "\n" 669 "\tframe_ctx_level: %" Pd "\n"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 ASSERT(token_pos != NULL); 718 ASSERT(token_pos != NULL);
755 *token_pos = var_info.begin_pos; 719 *token_pos = var_info.begin_pos;
756 ASSERT(end_pos != NULL); 720 ASSERT(end_pos != NULL);
757 *end_pos = var_info.end_pos; 721 *end_pos = var_info.end_pos;
758 ASSERT(value != NULL); 722 ASSERT(value != NULL);
759 const int8_t kind = var_info.kind(); 723 const int8_t kind = var_info.kind();
760 if (kind == RawLocalVarDescriptors::kStackVar) { 724 if (kind == RawLocalVarDescriptors::kStackVar) {
761 *value = GetLocalInstanceVar(var_info.index()); 725 *value = GetLocalInstanceVar(var_info.index());
762 } else { 726 } else {
763 ASSERT(kind == RawLocalVarDescriptors::kContextVar); 727 ASSERT(kind == RawLocalVarDescriptors::kContextVar);
764 if (ctx_.IsNull()) { 728 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 729
772 // The context level at the PC/token index of this activation frame. 730 // The context level at the PC/token index of this activation frame.
773 intptr_t frame_ctx_level = ContextLevel(); 731 intptr_t frame_ctx_level = ContextLevel();
774 732
775 // The context level of the variable. 733 // The context level of the variable.
776 intptr_t var_ctx_level = var_info.scope_id; 734 intptr_t var_ctx_level = var_info.scope_id;
777 intptr_t level_diff = frame_ctx_level - var_ctx_level; 735 intptr_t level_diff = frame_ctx_level - var_ctx_level;
778 intptr_t ctx_slot = var_info.index(); 736 intptr_t ctx_slot = var_info.index();
779 if (level_diff == 0) { 737 if (level_diff == 0) {
780 if ((ctx_slot < 0) || 738 if ((ctx_slot < 0) ||
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 InvokeEventHandler(&event); 1185 InvokeEventHandler(&event);
1228 } 1186 }
1229 } 1187 }
1230 1188
1231 1189
1232 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, 1190 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate,
1233 uword pc, 1191 uword pc,
1234 StackFrame* frame, 1192 StackFrame* frame,
1235 const Code& code, 1193 const Code& code,
1236 const Array& deopt_frame, 1194 const Array& deopt_frame,
1237 intptr_t deopt_frame_offset, 1195 intptr_t deopt_frame_offset) {
1238 ActivationFrame* callee_activation,
1239 const Context& entry_ctx) {
1240 ASSERT(code.ContainsInstructionAt(pc)); 1196 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 = 1197 ActivationFrame* activation =
1245 new ActivationFrame(pc, frame->fp(), frame->sp(), code, 1198 new ActivationFrame(pc, frame->fp(), frame->sp(), code,
1246 deopt_frame, deopt_frame_offset); 1199 deopt_frame, deopt_frame_offset);
1247 1200
1248 // Is there a closure call at the current PC? 1201 // 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; 1202 bool is_closure_call = false;
1253 const PcDescriptors& pc_desc = 1203 const PcDescriptors& pc_desc =
1254 PcDescriptors::Handle(isolate, code.pc_descriptors()); 1204 PcDescriptors::Handle(isolate, code.pc_descriptors());
1255 PcDescriptors::Iterator iter(pc_desc, RawPcDescriptors::kClosureCall); 1205 PcDescriptors::Iterator iter(pc_desc, RawPcDescriptors::kClosureCall);
1256 while (iter.MoveNext()) { 1206 while (iter.MoveNext()) {
1257 if (iter.Pc() == pc) { 1207 if (iter.Pc() == pc) {
1258 is_closure_call = true; 1208 is_closure_call = true;
1259 break; 1209 break;
1260 } 1210 }
1261 } 1211 }
1262 1212
1263 // Recover the context for this frame. 1213 // Recover the context for this frame.
1264 if (is_closure_call) { 1214 if (is_closure_call) {
1265 // If the callee is a closure, we should have stored the context 1215 // If the callee is a closure, we should have stored the context
1266 // in the current frame before making the call. 1216 // in the current frame before making the call.
1267 const Context& closure_call_ctx = 1217 const Context& closure_call_ctx =
1268 Context::Handle(isolate, activation->GetSavedCurrentContext()); 1218 Context::Handle(isolate, activation->GetSavedCurrentContext());
1269 ASSERT(!closure_call_ctx.IsNull()); 1219 ASSERT(!closure_call_ctx.IsNull());
1270 activation->SetContext(closure_call_ctx); 1220 activation->SetContext(closure_call_ctx);
1271 if (FLAG_trace_debugger_stacktrace) { 1221 if (FLAG_trace_debugger_stacktrace) {
1272 OS::PrintErr("\tUsing closure call ctx: %s\n", 1222 OS::PrintErr("\tUsing closure call ctx: %s\n",
1273 closure_call_ctx.ToCString()); 1223 closure_call_ctx.ToCString());
1274 } 1224 }
1275 } else if (callee_activation == NULL) { 1225 } else {
1276 // No callee available. Use incoming entry context. Could be from 1226 const Context& ctx =
1277 // isolate's top context or from an entry frame. 1227 Context::Handle(isolate, activation->GetSavedCurrentContext());
1278 ASSERT(!entry_ctx.IsNull()); 1228 ASSERT(!ctx.IsNull());
1279 activation->SetContext(entry_ctx); 1229 activation->SetContext(ctx);
1280 if (FLAG_trace_debugger_stacktrace) { 1230 if (FLAG_trace_debugger_stacktrace) {
1281 OS::PrintErr("\tUsing entry ctx: %s\n", entry_ctx.ToCString()); 1231 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 } 1232 }
1297 } 1233 }
1298 if (FLAG_trace_debugger_stacktrace) { 1234 if (FLAG_trace_debugger_stacktrace) {
1299 OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber()); 1235 OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber());
1300 } 1236 }
1301 return activation; 1237 return activation;
1302 } 1238 }
1303 1239
1304 1240
1305 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate, 1241 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate,
(...skipping 17 matching lines...) Expand all
1323 delete deopt_context; 1259 delete deopt_context;
1324 1260
1325 return dest_frame.raw(); 1261 return dest_frame.raw();
1326 } 1262 }
1327 1263
1328 1264
1329 DebuggerStackTrace* Debugger::CollectStackTrace() { 1265 DebuggerStackTrace* Debugger::CollectStackTrace() {
1330 Isolate* isolate = Isolate::Current(); 1266 Isolate* isolate = Isolate::Current();
1331 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); 1267 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8);
1332 StackFrameIterator iterator(false); 1268 StackFrameIterator iterator(false);
1333 ActivationFrame* current_activation = NULL;
1334 Context& entry_ctx = Context::Handle(isolate, isolate->top_context());
1335 Code& code = Code::Handle(isolate); 1269 Code& code = Code::Handle(isolate);
1336 Code& inlined_code = Code::Handle(isolate); 1270 Code& inlined_code = Code::Handle(isolate);
1337 Array& deopt_frame = Array::Handle(isolate); 1271 Array& deopt_frame = Array::Handle(isolate);
1338 1272
1339 for (StackFrame* frame = iterator.NextFrame(); 1273 for (StackFrame* frame = iterator.NextFrame();
1340 frame != NULL; 1274 frame != NULL;
1341 frame = iterator.NextFrame()) { 1275 frame = iterator.NextFrame()) {
1342 ASSERT(frame->IsValid()); 1276 ASSERT(frame->IsValid());
1343 if (FLAG_trace_debugger_stacktrace) { 1277 if (FLAG_trace_debugger_stacktrace) {
1344 OS::PrintErr("CollectStackTrace: visiting frame:\n\t%s\n", 1278 OS::PrintErr("CollectStackTrace: visiting frame:\n\t%s\n",
1345 frame->ToCString()); 1279 frame->ToCString());
1346 } 1280 }
1347 if (frame->IsEntryFrame()) { 1281 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(); 1282 code = frame->LookupDartCode();
1357 if (code.is_optimized()) { 1283 if (code.is_optimized()) {
1358 deopt_frame = DeoptimizeToArray(isolate, frame, code); 1284 deopt_frame = DeoptimizeToArray(isolate, frame, code);
1359 for (InlinedFunctionsIterator it(code, frame->pc()); 1285 for (InlinedFunctionsIterator it(code, frame->pc());
1360 !it.Done(); 1286 !it.Done();
1361 it.Advance()) { 1287 it.Advance()) {
1362 inlined_code = it.code(); 1288 inlined_code = it.code();
1363 if (FLAG_trace_debugger_stacktrace) { 1289 if (FLAG_trace_debugger_stacktrace) {
1364 const Function& function = 1290 const Function& function =
1365 Function::Handle(isolate, inlined_code.function()); 1291 Function::Handle(isolate, inlined_code.function());
1366 ASSERT(!function.IsNull()); 1292 ASSERT(!function.IsNull());
1367 OS::PrintErr("CollectStackTrace: visiting inlined function: %s\n", 1293 OS::PrintErr("CollectStackTrace: visiting inlined function: %s\n",
1368 function.ToFullyQualifiedCString()); 1294 function.ToFullyQualifiedCString());
1369 } 1295 }
1370 intptr_t deopt_frame_offset = it.GetDeoptFpOffset(); 1296 intptr_t deopt_frame_offset = it.GetDeoptFpOffset();
1371 current_activation = CollectDartFrame(isolate, 1297 stack_trace->AddActivation(CollectDartFrame(isolate,
1372 it.pc(), 1298 it.pc(),
1373 frame, 1299 frame,
1374 inlined_code, 1300 inlined_code,
1375 deopt_frame, 1301 deopt_frame,
1376 deopt_frame_offset, 1302 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 } 1303 }
1382 } else { 1304 } else {
1383 current_activation = CollectDartFrame(isolate, 1305 stack_trace->AddActivation(CollectDartFrame(isolate,
1384 frame->pc(), 1306 frame->pc(),
1385 frame, 1307 frame,
1386 code, 1308 code,
1387 Object::null_array(), 1309 Object::null_array(),
1388 0, 1310 0));
1389 current_activation,
1390 entry_ctx);
1391 stack_trace->AddActivation(current_activation);
1392 entry_ctx = Context::null(); // Only use entry context once.
1393 } 1311 }
1394 } 1312 }
1395 } 1313 }
1396 return stack_trace; 1314 return stack_trace;
1397 } 1315 }
1398 1316
1399 1317
1400 ActivationFrame* Debugger::TopDartFrame() const { 1318 ActivationFrame* Debugger::TopDartFrame() const {
1401 StackFrameIterator iterator(false); 1319 StackFrameIterator iterator(false);
1402 StackFrame* frame = iterator.NextFrame(); 1320 StackFrame* frame = iterator.NextFrame();
(...skipping 1189 matching lines...) Expand 10 before | Expand all | Expand 10 after
2592 } 2510 }
2593 2511
2594 2512
2595 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 2513 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
2596 ASSERT(bpt->next() == NULL); 2514 ASSERT(bpt->next() == NULL);
2597 bpt->set_next(code_breakpoints_); 2515 bpt->set_next(code_breakpoints_);
2598 code_breakpoints_ = bpt; 2516 code_breakpoints_ = bpt;
2599 } 2517 }
2600 2518
2601 } // namespace dart 2519 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698