| 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 "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
| 8 #include "vm/code_patcher.h" | 8 #include "vm/code_patcher.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 ASSERT(!func.HasOptimizedCode()); | 186 ASSERT(!func.HasOptimizedCode()); |
| 187 Code& code = Code::Handle(func.unoptimized_code()); | 187 Code& code = Code::Handle(func.unoptimized_code()); |
| 188 ASSERT(!code.IsNull()); | 188 ASSERT(!code.IsNull()); |
| 189 pc_desc_ = code.pc_descriptors(); | 189 pc_desc_ = code.pc_descriptors(); |
| 190 ASSERT(!pc_desc_.IsNull()); | 190 ASSERT(!pc_desc_.IsNull()); |
| 191 } | 191 } |
| 192 } | 192 } |
| 193 | 193 |
| 194 | 194 |
| 195 // Compute token_pos_ and pc_desc_index_. | 195 // Compute token_pos_ and pc_desc_index_. |
| 196 intptr_t ActivationFrame::TokenIndex() { | 196 intptr_t ActivationFrame::TokenPos() { |
| 197 if (token_pos_ < 0) { | 197 if (token_pos_ < 0) { |
| 198 GetPcDescriptors(); | 198 GetPcDescriptors(); |
| 199 for (int i = 0; i < pc_desc_.Length(); i++) { | 199 for (int i = 0; i < pc_desc_.Length(); i++) { |
| 200 if (pc_desc_.PC(i) == pc_) { | 200 if (pc_desc_.PC(i) == pc_) { |
| 201 pc_desc_index_ = i; | 201 pc_desc_index_ = i; |
| 202 token_pos_ = pc_desc_.TokenIndex(i); | 202 token_pos_ = pc_desc_.TokenPos(i); |
| 203 break; | 203 break; |
| 204 } | 204 } |
| 205 } | 205 } |
| 206 ASSERT(token_pos_ >= 0); | 206 ASSERT(token_pos_ >= 0); |
| 207 } | 207 } |
| 208 return token_pos_; | 208 return token_pos_; |
| 209 } | 209 } |
| 210 | 210 |
| 211 | 211 |
| 212 intptr_t ActivationFrame::PcDescIndex() { | 212 intptr_t ActivationFrame::PcDescIndex() { |
| 213 if (pc_desc_index_ < 0) { | 213 if (pc_desc_index_ < 0) { |
| 214 TokenIndex(); | 214 TokenPos(); |
| 215 ASSERT(pc_desc_index_ >= 0); | 215 ASSERT(pc_desc_index_ >= 0); |
| 216 } | 216 } |
| 217 return pc_desc_index_; | 217 return pc_desc_index_; |
| 218 } | 218 } |
| 219 | 219 |
| 220 | 220 |
| 221 intptr_t ActivationFrame::LineNumber() { | 221 intptr_t ActivationFrame::LineNumber() { |
| 222 // Compute line number lazily since it causes scanning of the script. | 222 // Compute line number lazily since it causes scanning of the script. |
| 223 if (line_number_ < 0) { | 223 if (line_number_ < 0) { |
| 224 const Script& script = Script::Handle(SourceScript()); | 224 const Script& script = Script::Handle(SourceScript()); |
| 225 intptr_t ignore_column; | 225 intptr_t ignore_column; |
| 226 script.GetTokenLocation(TokenIndex(), &line_number_, &ignore_column); | 226 script.GetTokenLocation(TokenPos(), &line_number_, &ignore_column); |
| 227 } | 227 } |
| 228 return line_number_; | 228 return line_number_; |
| 229 } | 229 } |
| 230 | 230 |
| 231 | 231 |
| 232 void ActivationFrame::GetVarDescriptors() { | 232 void ActivationFrame::GetVarDescriptors() { |
| 233 if (!var_descriptors_.IsNull()) { | 233 if (!var_descriptors_.IsNull()) { |
| 234 return; | 234 return; |
| 235 } | 235 } |
| 236 ASSERT(!DartFunction().HasOptimizedCode()); | 236 ASSERT(!DartFunction().HasOptimizedCode()); |
| 237 const Code& code = Code::Handle(DartFunction().unoptimized_code()); | 237 const Code& code = Code::Handle(DartFunction().unoptimized_code()); |
| 238 var_descriptors_ = code.var_descriptors(); | 238 var_descriptors_ = code.var_descriptors(); |
| 239 ASSERT(!var_descriptors_.IsNull()); | 239 ASSERT(!var_descriptors_.IsNull()); |
| 240 } | 240 } |
| 241 | 241 |
| 242 | 242 |
| 243 // Calculate the context level at the current token index of the frame. | 243 // Calculate the context level at the current token index of the frame. |
| 244 intptr_t ActivationFrame::ContextLevel() { | 244 intptr_t ActivationFrame::ContextLevel() { |
| 245 if (context_level_ < 0) { | 245 if (context_level_ < 0) { |
| 246 context_level_ = 0; | 246 context_level_ = 0; |
| 247 intptr_t pc_desc_idx = PcDescIndex(); | 247 intptr_t pc_desc_idx = PcDescIndex(); |
| 248 ASSERT(!pc_desc_.IsNull()); | 248 ASSERT(!pc_desc_.IsNull()); |
| 249 if (pc_desc_.DescriptorKind(pc_desc_idx) == PcDescriptors::kReturn) { | 249 if (pc_desc_.DescriptorKind(pc_desc_idx) == PcDescriptors::kReturn) { |
| 250 // Special case: the context chain has already been deallocated. | 250 // Special case: the context chain has already been deallocated. |
| 251 // The context level is 0. | 251 // The context level is 0. |
| 252 return context_level_; | 252 return context_level_; |
| 253 } | 253 } |
| 254 intptr_t innermost_begin_pos = 0; | 254 intptr_t innermost_begin_pos = 0; |
| 255 intptr_t activation_token_pos = TokenIndex(); | 255 intptr_t activation_token_pos = TokenPos(); |
| 256 GetVarDescriptors(); | 256 GetVarDescriptors(); |
| 257 intptr_t var_desc_len = var_descriptors_.Length(); | 257 intptr_t var_desc_len = var_descriptors_.Length(); |
| 258 for (int cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { | 258 for (int cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
| 259 RawLocalVarDescriptors::VarInfo var_info; | 259 RawLocalVarDescriptors::VarInfo var_info; |
| 260 var_descriptors_.GetInfo(cur_idx, &var_info); | 260 var_descriptors_.GetInfo(cur_idx, &var_info); |
| 261 if ((var_info.kind == RawLocalVarDescriptors::kContextLevel) && | 261 if ((var_info.kind == RawLocalVarDescriptors::kContextLevel) && |
| 262 (var_info.begin_pos <= activation_token_pos) && | 262 (var_info.begin_pos <= activation_token_pos) && |
| 263 (activation_token_pos < var_info.end_pos)) { | 263 (activation_token_pos < var_info.end_pos)) { |
| 264 // This var_descriptors_ entry is a context scope which is in scope | 264 // This var_descriptors_ entry is a context scope which is in scope |
| 265 // of the current token position. Now check whether it is shadowing | 265 // of the current token position. Now check whether it is shadowing |
| (...skipping 25 matching lines...) Expand all Loading... |
| 291 } | 291 } |
| 292 | 292 |
| 293 | 293 |
| 294 void ActivationFrame::GetDescIndices() { | 294 void ActivationFrame::GetDescIndices() { |
| 295 if (vars_initialized_) { | 295 if (vars_initialized_) { |
| 296 return; | 296 return; |
| 297 } | 297 } |
| 298 GetVarDescriptors(); | 298 GetVarDescriptors(); |
| 299 // TODO(hausner): Consider replacing this GrowableArray. | 299 // TODO(hausner): Consider replacing this GrowableArray. |
| 300 GrowableArray<String*> var_names(8); | 300 GrowableArray<String*> var_names(8); |
| 301 intptr_t activation_token_pos = TokenIndex(); | 301 intptr_t activation_token_pos = TokenPos(); |
| 302 intptr_t var_desc_len = var_descriptors_.Length(); | 302 intptr_t var_desc_len = var_descriptors_.Length(); |
| 303 for (int cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { | 303 for (int cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
| 304 ASSERT(var_names.length() == desc_indices_.length()); | 304 ASSERT(var_names.length() == desc_indices_.length()); |
| 305 RawLocalVarDescriptors::VarInfo var_info; | 305 RawLocalVarDescriptors::VarInfo var_info; |
| 306 var_descriptors_.GetInfo(cur_idx, &var_info); | 306 var_descriptors_.GetInfo(cur_idx, &var_info); |
| 307 if ((var_info.kind != RawLocalVarDescriptors::kStackVar) && | 307 if ((var_info.kind != RawLocalVarDescriptors::kStackVar) && |
| 308 (var_info.kind != RawLocalVarDescriptors::kContextVar)) { | 308 (var_info.kind != RawLocalVarDescriptors::kContextVar)) { |
| 309 continue; | 309 continue; |
| 310 } | 310 } |
| 311 if ((var_info.begin_pos <= activation_token_pos) && | 311 if ((var_info.begin_pos <= activation_token_pos) && |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 pc_(0), | 454 pc_(0), |
| 455 line_number_(-1), | 455 line_number_(-1), |
| 456 is_enabled_(false), | 456 is_enabled_(false), |
| 457 src_bpt_(NULL), | 457 src_bpt_(NULL), |
| 458 next_(NULL) { | 458 next_(NULL) { |
| 459 ASSERT(!func.HasOptimizedCode()); | 459 ASSERT(!func.HasOptimizedCode()); |
| 460 Code& code = Code::Handle(func.unoptimized_code()); | 460 Code& code = Code::Handle(func.unoptimized_code()); |
| 461 ASSERT(!code.IsNull()); // Function must be compiled. | 461 ASSERT(!code.IsNull()); // Function must be compiled. |
| 462 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 462 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
| 463 ASSERT(pc_desc_index < desc.Length()); | 463 ASSERT(pc_desc_index < desc.Length()); |
| 464 token_pos_ = desc.TokenIndex(pc_desc_index); | 464 token_pos_ = desc.TokenPos(pc_desc_index); |
| 465 ASSERT(token_pos_ >= 0); | 465 ASSERT(token_pos_ >= 0); |
| 466 pc_ = desc.PC(pc_desc_index); | 466 pc_ = desc.PC(pc_desc_index); |
| 467 ASSERT(pc_ != 0); | 467 ASSERT(pc_ != 0); |
| 468 breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); | 468 breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); |
| 469 ASSERT((breakpoint_kind_ == PcDescriptors::kIcCall) || | 469 ASSERT((breakpoint_kind_ == PcDescriptors::kIcCall) || |
| 470 (breakpoint_kind_ == PcDescriptors::kFuncCall) || | 470 (breakpoint_kind_ == PcDescriptors::kFuncCall) || |
| 471 (breakpoint_kind_ == PcDescriptors::kReturn)); | 471 (breakpoint_kind_ == PcDescriptors::kReturn)); |
| 472 } | 472 } |
| 473 | 473 |
| 474 | 474 |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 830 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
| 831 // We attempt to find the PC descriptor that is closest to the | 831 // We attempt to find the PC descriptor that is closest to the |
| 832 // beginning of the token range, in terms of native code address. If we | 832 // beginning of the token range, in terms of native code address. If we |
| 833 // don't find a PC descriptor within the given range, we pick the | 833 // don't find a PC descriptor within the given range, we pick the |
| 834 // nearest one to the beginning of the range, in terms of token position. | 834 // nearest one to the beginning of the range, in terms of token position. |
| 835 intptr_t best_fit_index = -1; | 835 intptr_t best_fit_index = -1; |
| 836 intptr_t best_fit = INT_MAX; | 836 intptr_t best_fit = INT_MAX; |
| 837 uword lowest_pc = kUwordMax; | 837 uword lowest_pc = kUwordMax; |
| 838 intptr_t lowest_pc_index = -1; | 838 intptr_t lowest_pc_index = -1; |
| 839 for (int i = 0; i < desc.Length(); i++) { | 839 for (int i = 0; i < desc.Length(); i++) { |
| 840 intptr_t desc_token_pos = desc.TokenIndex(i); | 840 intptr_t desc_token_pos = desc.TokenPos(i); |
| 841 if (desc_token_pos < first_token_pos) { | 841 if (desc_token_pos < first_token_pos) { |
| 842 continue; | 842 continue; |
| 843 } | 843 } |
| 844 PcDescriptors::Kind kind = desc.DescriptorKind(i); | 844 PcDescriptors::Kind kind = desc.DescriptorKind(i); |
| 845 if ((kind == PcDescriptors::kIcCall) || | 845 if ((kind == PcDescriptors::kIcCall) || |
| 846 (kind == PcDescriptors::kFuncCall) || | 846 (kind == PcDescriptors::kFuncCall) || |
| 847 (kind == PcDescriptors::kReturn)) { | 847 (kind == PcDescriptors::kReturn)) { |
| 848 if ((desc_token_pos - first_token_pos) < best_fit) { | 848 if ((desc_token_pos - first_token_pos) < best_fit) { |
| 849 best_fit = desc_token_pos - first_token_pos; | 849 best_fit = desc_token_pos - first_token_pos; |
| 850 ASSERT(best_fit >= 0); | 850 ASSERT(best_fit >= 0); |
| (...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1568 } | 1568 } |
| 1569 | 1569 |
| 1570 | 1570 |
| 1571 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 1571 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 1572 ASSERT(bpt->next() == NULL); | 1572 ASSERT(bpt->next() == NULL); |
| 1573 bpt->set_next(code_breakpoints_); | 1573 bpt->set_next(code_breakpoints_); |
| 1574 code_breakpoints_ = bpt; | 1574 code_breakpoints_ = bpt; |
| 1575 } | 1575 } |
| 1576 | 1576 |
| 1577 } // namespace dart | 1577 } // namespace dart |
| OLD | NEW |