| 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 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 intptr_t ActivationFrame::TokenPos() { | 255 intptr_t ActivationFrame::TokenPos() { |
| 256 if (token_pos_ < 0) { | 256 if (token_pos_ < 0) { |
| 257 GetPcDescriptors(); | 257 GetPcDescriptors(); |
| 258 for (int i = 0; i < pc_desc_.Length(); i++) { | 258 for (int i = 0; i < pc_desc_.Length(); i++) { |
| 259 if (pc_desc_.PC(i) == pc_) { | 259 if (pc_desc_.PC(i) == pc_) { |
| 260 pc_desc_index_ = i; | 260 pc_desc_index_ = i; |
| 261 token_pos_ = pc_desc_.TokenPos(i); | 261 token_pos_ = pc_desc_.TokenPos(i); |
| 262 break; | 262 break; |
| 263 } | 263 } |
| 264 } | 264 } |
| 265 ASSERT(token_pos_ >= 0); | |
| 266 } | 265 } |
| 267 return token_pos_; | 266 return token_pos_; |
| 268 } | 267 } |
| 269 | 268 |
| 270 | 269 |
| 271 intptr_t ActivationFrame::PcDescIndex() { | 270 intptr_t ActivationFrame::PcDescIndex() { |
| 272 if (pc_desc_index_ < 0) { | 271 if (pc_desc_index_ < 0) { |
| 273 TokenPos(); | 272 TokenPos(); // Sets pc_desc_index_ as a side effect. |
| 274 ASSERT(pc_desc_index_ >= 0); | |
| 275 } | 273 } |
| 276 return pc_desc_index_; | 274 return pc_desc_index_; |
| 277 } | 275 } |
| 278 | 276 |
| 279 | 277 |
| 280 intptr_t ActivationFrame::TryIndex() { | 278 intptr_t ActivationFrame::TryIndex() { |
| 281 intptr_t desc_index = PcDescIndex(); | 279 intptr_t desc_index = PcDescIndex(); |
| 282 return pc_desc_.TryIndex(desc_index); | 280 if (desc_index < 0) { |
| 281 return -1; |
| 282 } else { |
| 283 return pc_desc_.TryIndex(desc_index); |
| 284 } |
| 283 } | 285 } |
| 284 | 286 |
| 285 | 287 |
| 286 intptr_t ActivationFrame::LineNumber() { | 288 intptr_t ActivationFrame::LineNumber() { |
| 287 // Compute line number lazily since it causes scanning of the script. | 289 // Compute line number lazily since it causes scanning of the script. |
| 288 if (line_number_ < 0) { | 290 if ((line_number_ < 0) && (TokenPos() >= 0)) { |
| 289 const Script& script = Script::Handle(SourceScript()); | 291 const Script& script = Script::Handle(SourceScript()); |
| 290 intptr_t ignore_column; | 292 intptr_t ignore_column; |
| 291 script.GetTokenLocation(TokenPos(), &line_number_, &ignore_column); | 293 script.GetTokenLocation(TokenPos(), &line_number_, &ignore_column); |
| 292 } | 294 } |
| 293 return line_number_; | 295 return line_number_; |
| 294 } | 296 } |
| 295 | 297 |
| 296 | 298 |
| 297 void ActivationFrame::GetVarDescriptors() { | 299 void ActivationFrame::GetVarDescriptors() { |
| 298 if (var_descriptors_.IsNull()) { | 300 if (var_descriptors_.IsNull()) { |
| 299 var_descriptors_ = code().var_descriptors(); | 301 var_descriptors_ = code().var_descriptors(); |
| 300 ASSERT(!var_descriptors_.IsNull()); | 302 ASSERT(!var_descriptors_.IsNull()); |
| 301 } | 303 } |
| 302 } | 304 } |
| 303 | 305 |
| 304 | 306 |
| 305 // Calculate the context level at the current token index of the frame. | 307 // Calculate the context level at the current token index of the frame. |
| 306 intptr_t ActivationFrame::ContextLevel() { | 308 intptr_t ActivationFrame::ContextLevel() { |
| 307 if (context_level_ < 0 && !ctx_.IsNull()) { | 309 if (context_level_ < 0 && !ctx_.IsNull()) { |
| 308 ASSERT(!code_.is_optimized()); | 310 ASSERT(!code_.is_optimized()); |
| 309 context_level_ = 0; | 311 context_level_ = 0; |
| 310 intptr_t pc_desc_idx = PcDescIndex(); | 312 intptr_t pc_desc_idx = PcDescIndex(); |
| 313 // TODO(hausner): What to do if there is no descriptor entry |
| 314 // for the code position of the frame? For now say we are at context |
| 315 // level 0. |
| 316 if (pc_desc_idx < 0) { |
| 317 return context_level_; |
| 318 } |
| 311 ASSERT(!pc_desc_.IsNull()); | 319 ASSERT(!pc_desc_.IsNull()); |
| 312 if (pc_desc_.DescriptorKind(pc_desc_idx) == PcDescriptors::kReturn) { | 320 if (pc_desc_.DescriptorKind(pc_desc_idx) == PcDescriptors::kReturn) { |
| 313 // Special case: the context chain has already been deallocated. | 321 // Special case: the context chain has already been deallocated. |
| 314 // The context level is 0. | 322 // The context level is 0. |
| 315 return context_level_; | 323 return context_level_; |
| 316 } | 324 } |
| 317 intptr_t innermost_begin_pos = 0; | 325 intptr_t innermost_begin_pos = 0; |
| 318 intptr_t activation_token_pos = TokenPos(); | 326 intptr_t activation_token_pos = TokenPos(); |
| 327 ASSERT(activation_token_pos >= 0); |
| 319 GetVarDescriptors(); | 328 GetVarDescriptors(); |
| 320 intptr_t var_desc_len = var_descriptors_.Length(); | 329 intptr_t var_desc_len = var_descriptors_.Length(); |
| 321 for (int cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { | 330 for (int cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
| 322 RawLocalVarDescriptors::VarInfo var_info; | 331 RawLocalVarDescriptors::VarInfo var_info; |
| 323 var_descriptors_.GetInfo(cur_idx, &var_info); | 332 var_descriptors_.GetInfo(cur_idx, &var_info); |
| 324 if ((var_info.kind == RawLocalVarDescriptors::kContextLevel) && | 333 if ((var_info.kind == RawLocalVarDescriptors::kContextLevel) && |
| 325 (var_info.begin_pos <= activation_token_pos) && | 334 (var_info.begin_pos <= activation_token_pos) && |
| 326 (activation_token_pos < var_info.end_pos)) { | 335 (activation_token_pos < var_info.end_pos)) { |
| 327 // This var_descriptors_ entry is a context scope which is in scope | 336 // This var_descriptors_ entry is a context scope which is in scope |
| 328 // of the current token position. Now check whether it is shadowing | 337 // of the current token position. Now check whether it is shadowing |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 | 408 |
| 400 // We don't trust variable descriptors in optimized code. | 409 // We don't trust variable descriptors in optimized code. |
| 401 // Rather than potentially displaying incorrect values, we | 410 // Rather than potentially displaying incorrect values, we |
| 402 // pretend that there are no variables in the frame. | 411 // pretend that there are no variables in the frame. |
| 403 // We should be more clever about this in the future. | 412 // We should be more clever about this in the future. |
| 404 if (code().is_optimized()) { | 413 if (code().is_optimized()) { |
| 405 vars_initialized_ = true; | 414 vars_initialized_ = true; |
| 406 return; | 415 return; |
| 407 } | 416 } |
| 408 | 417 |
| 418 intptr_t activation_token_pos = TokenPos(); |
| 419 if (activation_token_pos < 0) { |
| 420 // We don't have a token position for this frame, so can't determine |
| 421 // which variables are visible. |
| 422 vars_initialized_ = true; |
| 423 return; |
| 424 } |
| 425 |
| 409 GrowableArray<String*> var_names(8); | 426 GrowableArray<String*> var_names(8); |
| 410 intptr_t activation_token_pos = TokenPos(); | |
| 411 intptr_t var_desc_len = var_descriptors_.Length(); | 427 intptr_t var_desc_len = var_descriptors_.Length(); |
| 412 for (int cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { | 428 for (int cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
| 413 ASSERT(var_names.length() == desc_indices_.length()); | 429 ASSERT(var_names.length() == desc_indices_.length()); |
| 414 RawLocalVarDescriptors::VarInfo var_info; | 430 RawLocalVarDescriptors::VarInfo var_info; |
| 415 var_descriptors_.GetInfo(cur_idx, &var_info); | 431 var_descriptors_.GetInfo(cur_idx, &var_info); |
| 416 if ((var_info.kind != RawLocalVarDescriptors::kStackVar) && | 432 if ((var_info.kind != RawLocalVarDescriptors::kStackVar) && |
| 417 (var_info.kind != RawLocalVarDescriptors::kContextVar)) { | 433 (var_info.kind != RawLocalVarDescriptors::kContextVar)) { |
| 418 continue; | 434 continue; |
| 419 } | 435 } |
| 420 if ((var_info.begin_pos <= activation_token_pos) && | 436 if ((var_info.begin_pos <= activation_token_pos) && |
| (...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 985 // We attempt to find the PC descriptor that is closest to the | 1001 // We attempt to find the PC descriptor that is closest to the |
| 986 // beginning of the token range, in terms of native code address. If we | 1002 // beginning of the token range, in terms of native code address. If we |
| 987 // don't find a PC descriptor within the given range, we pick the | 1003 // don't find a PC descriptor within the given range, we pick the |
| 988 // nearest one to the beginning of the range, in terms of token position. | 1004 // nearest one to the beginning of the range, in terms of token position. |
| 989 intptr_t best_fit_index = -1; | 1005 intptr_t best_fit_index = -1; |
| 990 intptr_t best_fit = INT_MAX; | 1006 intptr_t best_fit = INT_MAX; |
| 991 uword lowest_pc = kUwordMax; | 1007 uword lowest_pc = kUwordMax; |
| 992 intptr_t lowest_pc_index = -1; | 1008 intptr_t lowest_pc_index = -1; |
| 993 for (int i = 0; i < desc.Length(); i++) { | 1009 for (int i = 0; i < desc.Length(); i++) { |
| 994 intptr_t desc_token_pos = desc.TokenPos(i); | 1010 intptr_t desc_token_pos = desc.TokenPos(i); |
| 1011 ASSERT(desc_token_pos >= 0); |
| 995 if (desc_token_pos < first_token_pos) { | 1012 if (desc_token_pos < first_token_pos) { |
| 996 continue; | 1013 continue; |
| 997 } | 1014 } |
| 998 PcDescriptors::Kind kind = desc.DescriptorKind(i); | 1015 PcDescriptors::Kind kind = desc.DescriptorKind(i); |
| 999 if ((kind == PcDescriptors::kIcCall) || | 1016 if ((kind == PcDescriptors::kIcCall) || |
| 1000 (kind == PcDescriptors::kFuncCall) || | 1017 (kind == PcDescriptors::kFuncCall) || |
| 1001 (kind == PcDescriptors::kReturn)) { | 1018 (kind == PcDescriptors::kReturn)) { |
| 1002 if ((desc_token_pos - first_token_pos) < best_fit) { | 1019 if ((desc_token_pos - first_token_pos) < best_fit) { |
| 1003 best_fit = desc_token_pos - first_token_pos; | 1020 best_fit = desc_token_pos - first_token_pos; |
| 1004 ASSERT(best_fit >= 0); | 1021 ASSERT(best_fit >= 0); |
| (...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1741 } | 1758 } |
| 1742 | 1759 |
| 1743 | 1760 |
| 1744 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 1761 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 1745 ASSERT(bpt->next() == NULL); | 1762 ASSERT(bpt->next() == NULL); |
| 1746 bpt->set_next(code_breakpoints_); | 1763 bpt->set_next(code_breakpoints_); |
| 1747 code_breakpoints_ = bpt; | 1764 code_breakpoints_ = bpt; |
| 1748 } | 1765 } |
| 1749 | 1766 |
| 1750 } // namespace dart | 1767 } // namespace dart |
| OLD | NEW |