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 |