Chromium Code Reviews| 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 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 425 } | 425 } |
| 426 } | 426 } |
| 427 } | 427 } |
| 428 ASSERT(context_level_ >= 0); | 428 ASSERT(context_level_ >= 0); |
| 429 } | 429 } |
| 430 return context_level_; | 430 return context_level_; |
| 431 } | 431 } |
| 432 | 432 |
| 433 | 433 |
| 434 RawContext* ActivationFrame::GetSavedEntryContext() { | 434 RawContext* ActivationFrame::GetSavedEntryContext() { |
| 435 if (ctx_.IsNull()) { | |
| 436 // We have bailed on providing a context for this frame. Bail for | |
| 437 // the caller as well. | |
| 438 return Context::null(); | |
| 439 } | |
| 440 | |
| 441 // Attempt to find a saved context. | 435 // Attempt to find a saved context. |
| 442 GetVarDescriptors(); | 436 GetVarDescriptors(); |
| 443 intptr_t var_desc_len = var_descriptors_.Length(); | 437 intptr_t var_desc_len = var_descriptors_.Length(); |
| 444 for (intptr_t i = 0; i < var_desc_len; i++) { | 438 for (intptr_t i = 0; i < var_desc_len; i++) { |
| 445 RawLocalVarDescriptors::VarInfo var_info; | 439 RawLocalVarDescriptors::VarInfo var_info; |
| 446 var_descriptors_.GetInfo(i, &var_info); | 440 var_descriptors_.GetInfo(i, &var_info); |
| 447 if (var_info.kind == RawLocalVarDescriptors::kSavedEntryContext) { | 441 if (var_info.kind == RawLocalVarDescriptors::kSavedEntryContext) { |
| 448 return GetLocalContextVar(var_info.index); | 442 return GetLocalContextVar(var_info.index); |
| 449 } | 443 } |
| 450 } | 444 } |
| 451 | 445 |
| 452 // No saved context. Return the current context. | 446 // No saved context. Return the current context. |
| 453 return ctx_.raw(); | 447 return ctx_.raw(); |
| 454 } | 448 } |
| 455 | 449 |
| 456 | 450 |
| 457 // Get the saved context if the callee of this activation frame is a | 451 // Get the saved context if the callee of this activation frame is a |
| 458 // closure function. | 452 // closure function. |
| 459 RawContext* ActivationFrame::GetSavedCurrentContext() { | 453 RawContext* ActivationFrame::GetSavedCurrentContext() { |
| 460 GetVarDescriptors(); | 454 GetVarDescriptors(); |
| 461 intptr_t var_desc_len = var_descriptors_.Length(); | 455 intptr_t var_desc_len = var_descriptors_.Length(); |
| 462 for (intptr_t i = 0; i < var_desc_len; i++) { | 456 for (intptr_t i = 0; i < var_desc_len; i++) { |
| 463 RawLocalVarDescriptors::VarInfo var_info; | 457 RawLocalVarDescriptors::VarInfo var_info; |
| 464 var_descriptors_.GetInfo(i, &var_info); | 458 var_descriptors_.GetInfo(i, &var_info); |
| 465 if (var_info.kind == RawLocalVarDescriptors::kSavedCurrentContext) { | 459 if (var_info.kind == RawLocalVarDescriptors::kSavedCurrentContext) { |
| 466 return GetLocalContextVar(var_info.index); | 460 return GetLocalContextVar(var_info.index); |
| 467 } | 461 } |
| 468 } | 462 } |
| 463 UNREACHABLE(); | |
| 469 return Context::null(); | 464 return Context::null(); |
| 470 } | 465 } |
| 471 | 466 |
| 472 | 467 |
| 473 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( | 468 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( |
| 474 const Instance& exc_obj) const { | 469 const Instance& exc_obj) const { |
| 475 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); | 470 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); |
| 476 Array& handled_types = Array::Handle(); | 471 Array& handled_types = Array::Handle(); |
| 477 AbstractType& type = Type::Handle(); | 472 AbstractType& type = Type::Handle(); |
| 478 const TypeArguments& no_instantiator = TypeArguments::Handle(); | 473 const TypeArguments& no_instantiator = TypeArguments::Handle(); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 604 RawInstance* ActivationFrame::GetLocalInstanceVar(intptr_t slot_index) { | 599 RawInstance* ActivationFrame::GetLocalInstanceVar(intptr_t slot_index) { |
| 605 Instance& instance = Instance::Handle(); | 600 Instance& instance = Instance::Handle(); |
| 606 instance ^= GetLocalVar(slot_index); | 601 instance ^= GetLocalVar(slot_index); |
| 607 return instance.raw(); | 602 return instance.raw(); |
| 608 } | 603 } |
| 609 | 604 |
| 610 | 605 |
| 611 RawContext* ActivationFrame::GetLocalContextVar(intptr_t slot_index) { | 606 RawContext* ActivationFrame::GetLocalContextVar(intptr_t slot_index) { |
| 612 Object& context = Object::Handle(GetLocalVar(slot_index)); | 607 Object& context = Object::Handle(GetLocalVar(slot_index)); |
| 613 if (context.IsContext()) { | 608 if (context.IsContext()) { |
| 609 // We found a saved context. | |
| 614 return Context::Cast(context).raw(); | 610 return Context::Cast(context).raw(); |
| 611 } else if (context.raw() == Symbols::OptimizedOut().raw()) { | |
| 612 // The optimizing compiler has eliminated the saved context. | |
| 613 return Context::null(); | |
|
turnidge
2014/02/13 18:55:49
I decided to use Context::null() to represent an o
| |
| 614 } else { | |
| 615 UNREACHABLE(); | |
| 616 return Context::null(); | |
| 615 } | 617 } |
| 616 return Context::null(); | |
| 617 } | 618 } |
| 618 | 619 |
| 619 | 620 |
| 620 void ActivationFrame::VariableAt(intptr_t i, | 621 void ActivationFrame::VariableAt(intptr_t i, |
| 621 String* name, | 622 String* name, |
| 622 intptr_t* token_pos, | 623 intptr_t* token_pos, |
| 623 intptr_t* end_pos, | 624 intptr_t* end_pos, |
| 624 Instance* value) { | 625 Instance* value) { |
| 625 GetDescIndices(); | 626 GetDescIndices(); |
| 626 ASSERT(i < desc_indices_.length()); | 627 ASSERT(i < desc_indices_.length()); |
| 627 intptr_t desc_index = desc_indices_[i]; | 628 intptr_t desc_index = desc_indices_[i]; |
| 628 ASSERT(name != NULL); | 629 ASSERT(name != NULL); |
| 629 *name ^= var_descriptors_.GetName(desc_index); | 630 *name ^= var_descriptors_.GetName(desc_index); |
| 630 RawLocalVarDescriptors::VarInfo var_info; | 631 RawLocalVarDescriptors::VarInfo var_info; |
| 631 var_descriptors_.GetInfo(desc_index, &var_info); | 632 var_descriptors_.GetInfo(desc_index, &var_info); |
| 632 ASSERT(token_pos != NULL); | 633 ASSERT(token_pos != NULL); |
| 633 *token_pos = var_info.begin_pos; | 634 *token_pos = var_info.begin_pos; |
| 634 ASSERT(end_pos != NULL); | 635 ASSERT(end_pos != NULL); |
| 635 *end_pos = var_info.end_pos; | 636 *end_pos = var_info.end_pos; |
| 636 ASSERT(value != NULL); | 637 ASSERT(value != NULL); |
| 637 if (var_info.kind == RawLocalVarDescriptors::kStackVar) { | 638 if (var_info.kind == RawLocalVarDescriptors::kStackVar) { |
| 638 *value = GetLocalInstanceVar(var_info.index); | 639 *value = GetLocalInstanceVar(var_info.index); |
| 639 } else { | 640 } else { |
| 640 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); | 641 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); |
| 642 if (ctx_.IsNull()) { | |
| 643 // The context has been removed by the optimizing compiler. | |
| 644 *value = Symbols::OptimizedOut().raw(); | |
| 645 return; | |
| 646 } | |
| 647 | |
| 641 // The context level at the PC/token index of this activation frame. | 648 // The context level at the PC/token index of this activation frame. |
| 642 intptr_t frame_ctx_level = ContextLevel(); | 649 intptr_t frame_ctx_level = ContextLevel(); |
| 643 ASSERT(!ctx_.IsNull()); | |
| 644 | 650 |
| 645 // The context level of the variable. | 651 // The context level of the variable. |
| 646 intptr_t var_ctx_level = var_info.scope_id; | 652 intptr_t var_ctx_level = var_info.scope_id; |
| 647 intptr_t level_diff = frame_ctx_level - var_ctx_level; | 653 intptr_t level_diff = frame_ctx_level - var_ctx_level; |
| 648 intptr_t ctx_slot = var_info.index; | 654 intptr_t ctx_slot = var_info.index; |
| 649 if (level_diff == 0) { | 655 if (level_diff == 0) { |
| 650 ASSERT((ctx_slot >= 0) && (ctx_slot < ctx_.num_variables())); | 656 ASSERT((ctx_slot >= 0) && (ctx_slot < ctx_.num_variables())); |
| 651 *value = ctx_.At(ctx_slot); | 657 *value = ctx_.At(ctx_slot); |
| 652 } else { | 658 } else { |
| 653 ASSERT(level_diff > 0); | 659 ASSERT(level_diff > 0); |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1056 ASSERT(((callee_activation != NULL) && entry_ctx.IsNull()) || | 1062 ASSERT(((callee_activation != NULL) && entry_ctx.IsNull()) || |
| 1057 ((callee_activation == NULL) && !entry_ctx.IsNull())); | 1063 ((callee_activation == NULL) && !entry_ctx.IsNull())); |
| 1058 ActivationFrame* activation = | 1064 ActivationFrame* activation = |
| 1059 new ActivationFrame(pc, frame->fp(), frame->sp(), code, | 1065 new ActivationFrame(pc, frame->fp(), frame->sp(), code, |
| 1060 deopt_frame, deopt_frame_offset); | 1066 deopt_frame, deopt_frame_offset); |
| 1061 | 1067 |
| 1062 // Recover the context for this frame. | 1068 // Recover the context for this frame. |
| 1063 if (callee_activation == NULL) { | 1069 if (callee_activation == NULL) { |
| 1064 // No callee. Use incoming entry context. Could be from | 1070 // No callee. Use incoming entry context. Could be from |
| 1065 // isolate's top context or from an entry frame. | 1071 // isolate's top context or from an entry frame. |
| 1072 ASSERT(!entry_ctx.IsNull()); | |
| 1066 activation->SetContext(entry_ctx); | 1073 activation->SetContext(entry_ctx); |
| 1067 | 1074 |
| 1068 } else if (callee_activation->function().IsClosureFunction()) { | 1075 } else if (callee_activation->function().IsClosureFunction()) { |
| 1069 // If the callee is a closure, we should have stored the context | 1076 // If the callee is a closure, we should have stored the context |
| 1070 // in the current frame before making the call. | 1077 // in the current frame before making the call. |
| 1071 const Context& closure_call_ctx = | 1078 const Context& closure_call_ctx = |
| 1072 Context::Handle(isolate, activation->GetSavedCurrentContext()); | 1079 Context::Handle(isolate, activation->GetSavedCurrentContext()); |
| 1073 ASSERT(!closure_call_ctx.IsNull()); | 1080 ASSERT(!closure_call_ctx.IsNull()); |
| 1074 activation->SetContext(closure_call_ctx); | 1081 activation->SetContext(closure_call_ctx); |
| 1075 | 1082 |
| 1076 } else { | 1083 } else { |
| 1077 // Use the context provided by our callee. This is either the | 1084 // Use the context provided by our callee. This is either the |
| 1078 // callee's context or a context that was saved in the callee's | 1085 // callee's context or a context that was saved in the callee's |
| 1079 // frame. | 1086 // frame. |
| 1087 // | |
| 1088 // The callee's saved context may be NULL if it was eliminated by | |
| 1089 // the optimizing compiler. | |
| 1080 const Context& callee_ctx = | 1090 const Context& callee_ctx = |
| 1081 Context::Handle(isolate, callee_activation->GetSavedEntryContext()); | 1091 Context::Handle(isolate, callee_activation->GetSavedEntryContext()); |
| 1082 activation->SetContext(callee_ctx); | 1092 activation->SetContext(callee_ctx); |
| 1083 } | 1093 } |
| 1084 return activation; | 1094 return activation; |
| 1085 } | 1095 } |
| 1086 | 1096 |
| 1087 | 1097 |
| 1088 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate, | 1098 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate, |
| 1089 StackFrame* frame, | 1099 StackFrame* frame, |
| (...skipping 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2305 } | 2315 } |
| 2306 | 2316 |
| 2307 | 2317 |
| 2308 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2318 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 2309 ASSERT(bpt->next() == NULL); | 2319 ASSERT(bpt->next() == NULL); |
| 2310 bpt->set_next(code_breakpoints_); | 2320 bpt->set_next(code_breakpoints_); |
| 2311 code_breakpoints_ = bpt; | 2321 code_breakpoints_ = bpt; |
| 2312 } | 2322 } |
| 2313 | 2323 |
| 2314 } // namespace dart | 2324 } // namespace dart |
| OLD | NEW |