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" |
11 #include "vm/compiler.h" | 11 #include "vm/compiler.h" |
12 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
| 13 #include "vm/deopt_instructions.h" |
13 #include "vm/flags.h" | 14 #include "vm/flags.h" |
14 #include "vm/globals.h" | 15 #include "vm/globals.h" |
15 #include "vm/longjump.h" | 16 #include "vm/longjump.h" |
16 #include "vm/object.h" | 17 #include "vm/object.h" |
17 #include "vm/object_store.h" | 18 #include "vm/object_store.h" |
18 #include "vm/os.h" | 19 #include "vm/os.h" |
19 #include "vm/port.h" | 20 #include "vm/port.h" |
20 #include "vm/stack_frame.h" | 21 #include "vm/stack_frame.h" |
21 #include "vm/stub_code.h" | 22 #include "vm/stub_code.h" |
22 #include "vm/symbols.h" | 23 #include "vm/symbols.h" |
23 #include "vm/visitor.h" | 24 #include "vm/visitor.h" |
24 | 25 |
25 | 26 |
26 namespace dart { | 27 namespace dart { |
27 | 28 |
28 DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages"); | 29 DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages"); |
| 30 DEFINE_FLAG(bool, use_new_stacktrace, true, |
| 31 "Use new stacktrace creation"); |
29 | 32 |
30 | 33 |
31 Debugger::EventHandler* Debugger::event_handler_ = NULL; | 34 Debugger::EventHandler* Debugger::event_handler_ = NULL; |
32 | 35 |
33 | 36 |
34 class RemoteObjectCache : public ZoneAllocated { | 37 class RemoteObjectCache : public ZoneAllocated { |
35 public: | 38 public: |
36 explicit RemoteObjectCache(intptr_t initial_size); | 39 explicit RemoteObjectCache(intptr_t initial_size); |
37 intptr_t AddObject(const Object& obj); | 40 intptr_t AddObject(const Object& obj); |
38 RawObject* GetObj(intptr_t obj_id) const; | 41 RawObject* GetObj(intptr_t obj_id) const; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 | 129 |
127 ActivationFrame::ActivationFrame(uword pc, uword fp, uword sp, const Code& code) | 130 ActivationFrame::ActivationFrame(uword pc, uword fp, uword sp, const Code& code) |
128 : pc_(pc), fp_(fp), sp_(sp), | 131 : pc_(pc), fp_(fp), sp_(sp), |
129 ctx_(Context::ZoneHandle()), | 132 ctx_(Context::ZoneHandle()), |
130 code_(Code::ZoneHandle(code.raw())), | 133 code_(Code::ZoneHandle(code.raw())), |
131 function_(Function::ZoneHandle(code.function())), | 134 function_(Function::ZoneHandle(code.function())), |
132 token_pos_(-1), | 135 token_pos_(-1), |
133 pc_desc_index_(-1), | 136 pc_desc_index_(-1), |
134 line_number_(-1), | 137 line_number_(-1), |
135 context_level_(-1), | 138 context_level_(-1), |
| 139 deopt_frame_(Array::ZoneHandle()), |
| 140 deopt_frame_offset_(0), |
136 vars_initialized_(false), | 141 vars_initialized_(false), |
137 var_descriptors_(LocalVarDescriptors::ZoneHandle()), | 142 var_descriptors_(LocalVarDescriptors::ZoneHandle()), |
138 desc_indices_(8), | 143 desc_indices_(8), |
139 pc_desc_(PcDescriptors::ZoneHandle()) { | 144 pc_desc_(PcDescriptors::ZoneHandle()) { |
140 } | 145 } |
141 | 146 |
142 | 147 |
143 void Debugger::SignalIsolateEvent(EventType type) { | 148 void Debugger::SignalIsolateEvent(EventType type) { |
144 if (event_handler_ != NULL) { | 149 if (event_handler_ != NULL) { |
145 Debugger* debugger = Isolate::Current()->debugger(); | 150 Debugger* debugger = Isolate::Current()->debugger(); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 pc_desc_ = code().pc_descriptors(); | 243 pc_desc_ = code().pc_descriptors(); |
239 ASSERT(!pc_desc_.IsNull()); | 244 ASSERT(!pc_desc_.IsNull()); |
240 } | 245 } |
241 } | 246 } |
242 | 247 |
243 | 248 |
244 // Compute token_pos_ and pc_desc_index_. | 249 // Compute token_pos_ and pc_desc_index_. |
245 intptr_t ActivationFrame::TokenPos() { | 250 intptr_t ActivationFrame::TokenPos() { |
246 if (token_pos_ < 0) { | 251 if (token_pos_ < 0) { |
247 GetPcDescriptors(); | 252 GetPcDescriptors(); |
248 for (int i = 0; i < pc_desc_.Length(); i++) { | 253 for (intptr_t i = 0; i < pc_desc_.Length(); i++) { |
249 if (pc_desc_.PC(i) == pc_) { | 254 if (pc_desc_.PC(i) == pc_) { |
250 pc_desc_index_ = i; | 255 pc_desc_index_ = i; |
251 token_pos_ = pc_desc_.TokenPos(i); | 256 token_pos_ = pc_desc_.TokenPos(i); |
252 break; | 257 break; |
253 } | 258 } |
254 } | 259 } |
255 } | 260 } |
256 return token_pos_; | 261 return token_pos_; |
257 } | 262 } |
258 | 263 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 if (pc_desc_.DescriptorKind(pc_desc_idx) == PcDescriptors::kReturn) { | 319 if (pc_desc_.DescriptorKind(pc_desc_idx) == PcDescriptors::kReturn) { |
315 // Special case: the context chain has already been deallocated. | 320 // Special case: the context chain has already been deallocated. |
316 // The context level is 0. | 321 // The context level is 0. |
317 return context_level_; | 322 return context_level_; |
318 } | 323 } |
319 intptr_t innermost_begin_pos = 0; | 324 intptr_t innermost_begin_pos = 0; |
320 intptr_t activation_token_pos = TokenPos(); | 325 intptr_t activation_token_pos = TokenPos(); |
321 ASSERT(activation_token_pos >= 0); | 326 ASSERT(activation_token_pos >= 0); |
322 GetVarDescriptors(); | 327 GetVarDescriptors(); |
323 intptr_t var_desc_len = var_descriptors_.Length(); | 328 intptr_t var_desc_len = var_descriptors_.Length(); |
324 for (int cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { | 329 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
325 RawLocalVarDescriptors::VarInfo var_info; | 330 RawLocalVarDescriptors::VarInfo var_info; |
326 var_descriptors_.GetInfo(cur_idx, &var_info); | 331 var_descriptors_.GetInfo(cur_idx, &var_info); |
327 if ((var_info.kind == RawLocalVarDescriptors::kContextLevel) && | 332 if ((var_info.kind == RawLocalVarDescriptors::kContextLevel) && |
328 (var_info.begin_pos <= activation_token_pos) && | 333 (var_info.begin_pos <= activation_token_pos) && |
329 (activation_token_pos < var_info.end_pos)) { | 334 (activation_token_pos < var_info.end_pos)) { |
330 // This var_descriptors_ entry is a context scope which is in scope | 335 // This var_descriptors_ entry is a context scope which is in scope |
331 // of the current token position. Now check whether it is shadowing | 336 // of the current token position. Now check whether it is shadowing |
332 // the previous context scope. | 337 // the previous context scope. |
333 if (innermost_begin_pos < var_info.begin_pos) { | 338 if (innermost_begin_pos < var_info.begin_pos) { |
334 innermost_begin_pos = var_info.begin_pos; | 339 innermost_begin_pos = var_info.begin_pos; |
335 context_level_ = var_info.index; | 340 context_level_ = var_info.index; |
336 } | 341 } |
337 } | 342 } |
338 } | 343 } |
339 ASSERT(context_level_ >= 0); | 344 ASSERT(context_level_ >= 0); |
340 } | 345 } |
341 return context_level_; | 346 return context_level_; |
342 } | 347 } |
343 | 348 |
344 | 349 |
345 // Get the caller's context, or return ctx if the function does not | 350 // Get the caller's context, or return ctx if the function does not |
346 // save the caller's context on entry. | 351 // save the caller's context on entry. |
347 RawContext* ActivationFrame::GetSavedEntryContext(const Context& ctx) { | 352 RawContext* ActivationFrame::GetSavedEntryContext(const Context& ctx) { |
348 GetVarDescriptors(); | 353 GetVarDescriptors(); |
349 intptr_t var_desc_len = var_descriptors_.Length(); | 354 intptr_t var_desc_len = var_descriptors_.Length(); |
350 for (int i = 0; i < var_desc_len; i++) { | 355 for (intptr_t i = 0; i < var_desc_len; i++) { |
351 RawLocalVarDescriptors::VarInfo var_info; | 356 RawLocalVarDescriptors::VarInfo var_info; |
352 var_descriptors_.GetInfo(i, &var_info); | 357 var_descriptors_.GetInfo(i, &var_info); |
353 if (var_info.kind == RawLocalVarDescriptors::kSavedEntryContext) { | 358 if (var_info.kind == RawLocalVarDescriptors::kSavedEntryContext) { |
354 return reinterpret_cast<RawContext*>(GetLocalVarValue(var_info.index)); | 359 return GetLocalContextVar(var_info.index); |
355 } | 360 } |
356 } | 361 } |
357 return ctx.raw(); | 362 return ctx.raw(); |
358 } | 363 } |
359 | 364 |
360 | 365 |
| 366 RawContext* ActivationFrame::GetSavedEntryContextNew() { |
| 367 if (ctx_.IsNull()) { |
| 368 // We have bailed on providing a context for this frame. Bail for |
| 369 // the caller as well. |
| 370 return Context::null(); |
| 371 } |
| 372 |
| 373 // Attempt to find a saved context. |
| 374 GetVarDescriptors(); |
| 375 intptr_t var_desc_len = var_descriptors_.Length(); |
| 376 for (intptr_t i = 0; i < var_desc_len; i++) { |
| 377 RawLocalVarDescriptors::VarInfo var_info; |
| 378 var_descriptors_.GetInfo(i, &var_info); |
| 379 if (var_info.kind == RawLocalVarDescriptors::kSavedEntryContext) { |
| 380 return GetLocalContextVar(var_info.index); |
| 381 } |
| 382 } |
| 383 |
| 384 // No saved context. Return the current context. |
| 385 return ctx_.raw(); |
| 386 } |
| 387 |
| 388 |
361 // Get the saved context if the callee of this activation frame is a | 389 // Get the saved context if the callee of this activation frame is a |
362 // closure function. | 390 // closure function. |
363 RawContext* ActivationFrame::GetSavedCurrentContext() { | 391 RawContext* ActivationFrame::GetSavedCurrentContext() { |
364 GetVarDescriptors(); | 392 GetVarDescriptors(); |
365 intptr_t var_desc_len = var_descriptors_.Length(); | 393 intptr_t var_desc_len = var_descriptors_.Length(); |
366 for (int i = 0; i < var_desc_len; i++) { | 394 for (intptr_t i = 0; i < var_desc_len; i++) { |
367 RawLocalVarDescriptors::VarInfo var_info; | 395 RawLocalVarDescriptors::VarInfo var_info; |
368 var_descriptors_.GetInfo(i, &var_info); | 396 var_descriptors_.GetInfo(i, &var_info); |
369 if (var_info.kind == RawLocalVarDescriptors::kSavedCurrentContext) { | 397 if (var_info.kind == RawLocalVarDescriptors::kSavedCurrentContext) { |
370 return reinterpret_cast<RawContext*>(GetLocalVarValue(var_info.index)); | 398 return GetLocalContextVar(var_info.index); |
371 } | 399 } |
372 } | 400 } |
373 return Context::null(); | 401 return Context::null(); |
374 } | 402 } |
375 | 403 |
376 | 404 |
377 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( | 405 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( |
378 const Instance& exc_obj) const { | 406 const Instance& exc_obj) const { |
379 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); | 407 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); |
380 Array& handled_types = Array::Handle(); | 408 Array& handled_types = Array::Handle(); |
381 AbstractType& type = Type::Handle(); | 409 AbstractType& type = Type::Handle(); |
382 const TypeArguments& no_instantiator = TypeArguments::Handle(); | 410 const TypeArguments& no_instantiator = TypeArguments::Handle(); |
383 for (int frame_index = 0; frame_index < UnfilteredLength(); frame_index++) { | 411 for (intptr_t frame_index = 0; |
| 412 frame_index < UnfilteredLength(); |
| 413 frame_index++) { |
384 ActivationFrame* frame = UnfilteredFrameAt(frame_index); | 414 ActivationFrame* frame = UnfilteredFrameAt(frame_index); |
385 intptr_t try_index = frame->TryIndex(); | 415 intptr_t try_index = frame->TryIndex(); |
386 if (try_index < 0) continue; | 416 if (try_index < 0) continue; |
387 handlers = frame->code().exception_handlers(); | 417 handlers = frame->code().exception_handlers(); |
388 ASSERT(!handlers.IsNull()); | 418 ASSERT(!handlers.IsNull()); |
389 intptr_t num_handlers_checked = 0; | 419 intptr_t num_handlers_checked = 0; |
390 while (try_index >= 0) { | 420 while (try_index >= 0) { |
391 // Detect circles in the exception handler data. | 421 // Detect circles in the exception handler data. |
392 num_handlers_checked++; | 422 num_handlers_checked++; |
393 ASSERT(num_handlers_checked <= handlers.Length()); | 423 ASSERT(num_handlers_checked <= handlers.Length()); |
394 handled_types = handlers.GetHandledTypes(try_index); | 424 handled_types = handlers.GetHandledTypes(try_index); |
395 const intptr_t num_types = handled_types.Length(); | 425 const intptr_t num_types = handled_types.Length(); |
396 for (int k = 0; k < num_types; k++) { | 426 for (intptr_t k = 0; k < num_types; k++) { |
397 type ^= handled_types.At(k); | 427 type ^= handled_types.At(k); |
398 ASSERT(!type.IsNull()); | 428 ASSERT(!type.IsNull()); |
399 // Uninstantiated types are not added to ExceptionHandlers data. | 429 // Uninstantiated types are not added to ExceptionHandlers data. |
400 ASSERT(type.IsInstantiated()); | 430 ASSERT(type.IsInstantiated()); |
401 if (type.IsDynamicType()) return frame; | 431 if (type.IsDynamicType()) return frame; |
402 if (type.IsMalformed()) continue; | 432 if (type.IsMalformed()) continue; |
403 if (exc_obj.IsInstanceOf(type, no_instantiator, NULL)) { | 433 if (exc_obj.IsInstanceOf(type, no_instantiator, NULL)) { |
404 return frame; | 434 return frame; |
405 } | 435 } |
406 } | 436 } |
407 try_index = handlers.OuterTryIndex(try_index); | 437 try_index = handlers.OuterTryIndex(try_index); |
408 } | 438 } |
409 } | 439 } |
410 return NULL; | 440 return NULL; |
411 } | 441 } |
412 | 442 |
413 | 443 |
414 void ActivationFrame::GetDescIndices() { | 444 void ActivationFrame::GetDescIndices() { |
415 if (vars_initialized_) { | 445 if (vars_initialized_) { |
416 return; | 446 return; |
417 } | 447 } |
418 GetVarDescriptors(); | 448 GetVarDescriptors(); |
419 | 449 |
420 // We don't trust variable descriptors in optimized code. | 450 // We don't trust variable descriptors in optimized code. |
421 // Rather than potentially displaying incorrect values, we | 451 // Rather than potentially displaying incorrect values, we |
422 // pretend that there are no variables in the frame. | 452 // pretend that there are no variables in the frame. |
423 // We should be more clever about this in the future. | 453 // We should be more clever about this in the future. |
424 if (code().is_optimized()) { | 454 if (!FLAG_use_new_stacktrace && code().is_optimized()) { |
425 vars_initialized_ = true; | 455 vars_initialized_ = true; |
426 return; | 456 return; |
427 } | 457 } |
428 | 458 |
429 intptr_t activation_token_pos = TokenPos(); | 459 intptr_t activation_token_pos = TokenPos(); |
430 if (activation_token_pos < 0) { | 460 if (activation_token_pos < 0) { |
431 // We don't have a token position for this frame, so can't determine | 461 // We don't have a token position for this frame, so can't determine |
432 // which variables are visible. | 462 // which variables are visible. |
433 vars_initialized_ = true; | 463 vars_initialized_ = true; |
434 return; | 464 return; |
435 } | 465 } |
436 | 466 |
437 GrowableArray<String*> var_names(8); | 467 GrowableArray<String*> var_names(8); |
438 intptr_t var_desc_len = var_descriptors_.Length(); | 468 intptr_t var_desc_len = var_descriptors_.Length(); |
439 for (int cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { | 469 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
440 ASSERT(var_names.length() == desc_indices_.length()); | 470 ASSERT(var_names.length() == desc_indices_.length()); |
441 RawLocalVarDescriptors::VarInfo var_info; | 471 RawLocalVarDescriptors::VarInfo var_info; |
442 var_descriptors_.GetInfo(cur_idx, &var_info); | 472 var_descriptors_.GetInfo(cur_idx, &var_info); |
443 if ((var_info.kind != RawLocalVarDescriptors::kStackVar) && | 473 if ((var_info.kind != RawLocalVarDescriptors::kStackVar) && |
444 (var_info.kind != RawLocalVarDescriptors::kContextVar)) { | 474 (var_info.kind != RawLocalVarDescriptors::kContextVar)) { |
445 continue; | 475 continue; |
446 } | 476 } |
447 if ((var_info.begin_pos <= activation_token_pos) && | 477 if ((var_info.begin_pos <= activation_token_pos) && |
448 (activation_token_pos <= var_info.end_pos)) { | 478 (activation_token_pos <= var_info.end_pos)) { |
449 if ((var_info.kind == RawLocalVarDescriptors::kContextVar) && | 479 if ((var_info.kind == RawLocalVarDescriptors::kContextVar) && |
450 (ContextLevel() < var_info.scope_id)) { | 480 (ContextLevel() < var_info.scope_id)) { |
451 // The variable is textually in scope but the context level | 481 // The variable is textually in scope but the context level |
452 // at the activation frame's PC is lower than the context | 482 // at the activation frame's PC is lower than the context |
453 // level of the variable. The context containing the variable | 483 // level of the variable. The context containing the variable |
454 // has already been removed from the chain. This can happen when we | 484 // has already been removed from the chain. This can happen when we |
455 // break at a return statement, since the contexts get discarded | 485 // break at a return statement, since the contexts get discarded |
456 // before the debugger gets called. | 486 // before the debugger gets called. |
457 continue; | 487 continue; |
458 } | 488 } |
459 // The current variable is textually in scope. Now check whether | 489 // The current variable is textually in scope. Now check whether |
460 // there is another local variable with the same name that shadows | 490 // there is another local variable with the same name that shadows |
461 // or is shadowed by this variable. | 491 // or is shadowed by this variable. |
462 String& var_name = String::Handle(var_descriptors_.GetName(cur_idx)); | 492 String& var_name = String::Handle(var_descriptors_.GetName(cur_idx)); |
463 intptr_t indices_len = desc_indices_.length(); | 493 intptr_t indices_len = desc_indices_.length(); |
464 bool name_match_found = false; | 494 bool name_match_found = false; |
465 for (int i = 0; i < indices_len; i++) { | 495 for (intptr_t i = 0; i < indices_len; i++) { |
466 if (var_name.Equals(*var_names[i])) { | 496 if (var_name.Equals(*var_names[i])) { |
467 // Found two local variables with the same name. Now determine | 497 // Found two local variables with the same name. Now determine |
468 // which one is shadowed. | 498 // which one is shadowed. |
469 name_match_found = true; | 499 name_match_found = true; |
470 RawLocalVarDescriptors::VarInfo i_var_info; | 500 RawLocalVarDescriptors::VarInfo i_var_info; |
471 var_descriptors_.GetInfo(desc_indices_[i], &i_var_info); | 501 var_descriptors_.GetInfo(desc_indices_[i], &i_var_info); |
472 if (i_var_info.begin_pos < var_info.begin_pos) { | 502 if (i_var_info.begin_pos < var_info.begin_pos) { |
473 // The variable we found earlier is in an outer scope | 503 // The variable we found earlier is in an outer scope |
474 // and is shadowed by the current variable. Replace the | 504 // and is shadowed by the current variable. Replace the |
475 // descriptor index of the previously found variable | 505 // descriptor index of the previously found variable |
(...skipping 17 matching lines...) Expand all Loading... |
493 } | 523 } |
494 vars_initialized_ = true; | 524 vars_initialized_ = true; |
495 } | 525 } |
496 | 526 |
497 | 527 |
498 intptr_t ActivationFrame::NumLocalVariables() { | 528 intptr_t ActivationFrame::NumLocalVariables() { |
499 GetDescIndices(); | 529 GetDescIndices(); |
500 return desc_indices_.length(); | 530 return desc_indices_.length(); |
501 } | 531 } |
502 | 532 |
| 533 // TODO(hausner): Handle captured variables. |
| 534 RawObject* ActivationFrame::GetLocalVar(intptr_t slot_index) { |
| 535 if (deopt_frame_.IsNull()) { |
| 536 uword var_address = fp() + slot_index * kWordSize; |
| 537 return reinterpret_cast<RawObject*>( |
| 538 *reinterpret_cast<uword*>(var_address)); |
| 539 } else { |
| 540 return deopt_frame_.At(deopt_frame_offset_ + slot_index); |
| 541 } |
| 542 } |
| 543 |
| 544 |
| 545 RawInstance* ActivationFrame::GetLocalInstanceVar(intptr_t slot_index) { |
| 546 Instance& instance = Instance::Handle(); |
| 547 instance ^= GetLocalVar(slot_index); |
| 548 return instance.raw(); |
| 549 } |
| 550 |
| 551 |
| 552 RawContext* ActivationFrame::GetLocalContextVar(intptr_t slot_index) { |
| 553 Context& context = Context::Handle(); |
| 554 context ^= GetLocalVar(slot_index); |
| 555 return context.raw(); |
| 556 } |
| 557 |
503 | 558 |
504 void ActivationFrame::VariableAt(intptr_t i, | 559 void ActivationFrame::VariableAt(intptr_t i, |
505 String* name, | 560 String* name, |
506 intptr_t* token_pos, | 561 intptr_t* token_pos, |
507 intptr_t* end_pos, | 562 intptr_t* end_pos, |
508 Instance* value) { | 563 Instance* value) { |
509 GetDescIndices(); | 564 GetDescIndices(); |
510 ASSERT(i < desc_indices_.length()); | 565 ASSERT(i < desc_indices_.length()); |
511 intptr_t desc_index = desc_indices_[i]; | 566 intptr_t desc_index = desc_indices_[i]; |
512 ASSERT(name != NULL); | 567 ASSERT(name != NULL); |
513 *name ^= var_descriptors_.GetName(desc_index); | 568 *name ^= var_descriptors_.GetName(desc_index); |
514 RawLocalVarDescriptors::VarInfo var_info; | 569 RawLocalVarDescriptors::VarInfo var_info; |
515 var_descriptors_.GetInfo(desc_index, &var_info); | 570 var_descriptors_.GetInfo(desc_index, &var_info); |
516 ASSERT(token_pos != NULL); | 571 ASSERT(token_pos != NULL); |
517 *token_pos = var_info.begin_pos; | 572 *token_pos = var_info.begin_pos; |
518 ASSERT(end_pos != NULL); | 573 ASSERT(end_pos != NULL); |
519 *end_pos = var_info.end_pos; | 574 *end_pos = var_info.end_pos; |
520 ASSERT(value != NULL); | 575 ASSERT(value != NULL); |
521 if (var_info.kind == RawLocalVarDescriptors::kStackVar) { | 576 if (var_info.kind == RawLocalVarDescriptors::kStackVar) { |
522 *value = GetLocalVarValue(var_info.index); | 577 *value = GetLocalInstanceVar(var_info.index); |
523 } else { | 578 } else { |
524 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); | 579 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); |
525 // The context level at the PC/token index of this activation frame. | 580 // The context level at the PC/token index of this activation frame. |
526 intptr_t frame_ctx_level = ContextLevel(); | 581 intptr_t frame_ctx_level = ContextLevel(); |
527 if (ctx_.IsNull()) { | 582 if (ctx_.IsNull()) { |
528 *value = Symbols::New("<unknown>"); | 583 *value = Symbols::New("<unknown>"); |
529 return; | 584 return; |
530 } | 585 } |
531 // The context level of the variable. | 586 // The context level of the variable. |
532 intptr_t var_ctx_level = var_info.scope_id; | 587 intptr_t var_ctx_level = var_info.scope_id; |
(...skipping 26 matching lines...) Expand all Loading... |
559 } | 614 } |
560 } | 615 } |
561 | 616 |
562 | 617 |
563 RawArray* ActivationFrame::GetLocalVariables() { | 618 RawArray* ActivationFrame::GetLocalVariables() { |
564 GetDescIndices(); | 619 GetDescIndices(); |
565 intptr_t num_variables = desc_indices_.length(); | 620 intptr_t num_variables = desc_indices_.length(); |
566 String& var_name = String::Handle(); | 621 String& var_name = String::Handle(); |
567 Instance& value = Instance::Handle(); | 622 Instance& value = Instance::Handle(); |
568 const Array& list = Array::Handle(Array::New(2 * num_variables)); | 623 const Array& list = Array::Handle(Array::New(2 * num_variables)); |
569 for (int i = 0; i < num_variables; i++) { | 624 for (intptr_t i = 0; i < num_variables; i++) { |
570 intptr_t ignore; | 625 intptr_t ignore; |
571 VariableAt(i, &var_name, &ignore, &ignore, &value); | 626 VariableAt(i, &var_name, &ignore, &ignore, &value); |
572 list.SetAt(2 * i, var_name); | 627 list.SetAt(2 * i, var_name); |
573 list.SetAt((2 * i) + 1, value); | 628 list.SetAt((2 * i) + 1, value); |
574 } | 629 } |
575 return list.raw(); | 630 return list.raw(); |
576 } | 631 } |
577 | 632 |
578 | 633 |
579 const char* ActivationFrame::ToCString() { | 634 const char* ActivationFrame::ToCString() { |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 | 810 |
756 | 811 |
757 RemoteObjectCache::RemoteObjectCache(intptr_t initial_size) { | 812 RemoteObjectCache::RemoteObjectCache(intptr_t initial_size) { |
758 objs_ = &GrowableObjectArray::ZoneHandle( | 813 objs_ = &GrowableObjectArray::ZoneHandle( |
759 GrowableObjectArray::New(initial_size)); | 814 GrowableObjectArray::New(initial_size)); |
760 } | 815 } |
761 | 816 |
762 | 817 |
763 intptr_t RemoteObjectCache::AddObject(const Object& obj) { | 818 intptr_t RemoteObjectCache::AddObject(const Object& obj) { |
764 intptr_t len = objs_->Length(); | 819 intptr_t len = objs_->Length(); |
765 for (int i = 0; i < len; i++) { | 820 for (intptr_t i = 0; i < len; i++) { |
766 if (objs_->At(i) == obj.raw()) { | 821 if (objs_->At(i) == obj.raw()) { |
767 return i; | 822 return i; |
768 } | 823 } |
769 } | 824 } |
770 objs_->Add(obj); | 825 objs_->Add(obj); |
771 return len; | 826 return len; |
772 } | 827 } |
773 | 828 |
774 | 829 |
775 RawObject* RemoteObjectCache::GetObj(intptr_t obj_id) const { | 830 RawObject* RemoteObjectCache::GetObj(intptr_t obj_id) const { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
911 // adding breakpoints to target. | 966 // adding breakpoints to target. |
912 if (!target_function.HasCode()) { | 967 if (!target_function.HasCode()) { |
913 return; | 968 return; |
914 } | 969 } |
915 } | 970 } |
916 DeoptimizeWorld(); | 971 DeoptimizeWorld(); |
917 ASSERT(!target_function.HasOptimizedCode()); | 972 ASSERT(!target_function.HasOptimizedCode()); |
918 Code& code = Code::Handle(target_function.unoptimized_code()); | 973 Code& code = Code::Handle(target_function.unoptimized_code()); |
919 ASSERT(!code.IsNull()); | 974 ASSERT(!code.IsNull()); |
920 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 975 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
921 for (int i = 0; i < desc.Length(); i++) { | 976 for (intptr_t i = 0; i < desc.Length(); i++) { |
922 CodeBreakpoint* bpt = GetCodeBreakpoint(desc.PC(i)); | 977 CodeBreakpoint* bpt = GetCodeBreakpoint(desc.PC(i)); |
923 if (bpt != NULL) { | 978 if (bpt != NULL) { |
924 // There is already a breakpoint for this address. Make sure | 979 // There is already a breakpoint for this address. Make sure |
925 // it is enabled. | 980 // it is enabled. |
926 bpt->Enable(); | 981 bpt->Enable(); |
927 continue; | 982 continue; |
928 } | 983 } |
929 if (IsSafePoint(desc.DescriptorKind(i))) { | 984 if (IsSafePoint(desc.DescriptorKind(i))) { |
930 bpt = new CodeBreakpoint(target_function, i); | 985 bpt = new CodeBreakpoint(target_function, i); |
931 RegisterCodeBreakpoint(bpt); | 986 RegisterCodeBreakpoint(bpt); |
932 bpt->Enable(); | 987 bpt->Enable(); |
933 } | 988 } |
934 } | 989 } |
935 } | 990 } |
936 | 991 |
937 | 992 |
938 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { | 993 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { |
939 if (event_handler_ != NULL) { | 994 if (event_handler_ != NULL) { |
940 DebuggerEvent event; | 995 DebuggerEvent event; |
941 event.type = kBreakpointResolved; | 996 event.type = kBreakpointResolved; |
942 event.breakpoint = bpt; | 997 event.breakpoint = bpt; |
943 (*event_handler_)(&event); | 998 (*event_handler_)(&event); |
944 } | 999 } |
945 } | 1000 } |
946 | 1001 |
947 | 1002 |
| 1003 static void PrintStackTraceError(const char* message, |
| 1004 ActivationFrame* current_activation, |
| 1005 ActivationFrame* callee_activation) { |
| 1006 const Function& current = current_activation->function(); |
| 1007 const Function& callee = callee_activation->function(); |
| 1008 const Script& script = |
| 1009 Script::Handle(Class::Handle(current.Owner()).script()); |
| 1010 intptr_t line, col; |
| 1011 script.GetTokenLocation(current_activation->TokenPos(), &line, &col); |
| 1012 OS::PrintErr("Error building stack trace: %s:" |
| 1013 "current function '%s' callee_function '%s' " |
| 1014 " line %" Pd " column %" Pd "\n", |
| 1015 message, |
| 1016 current.ToFullyQualifiedCString(), |
| 1017 callee.ToFullyQualifiedCString(), |
| 1018 line, col); |
| 1019 } |
| 1020 |
| 1021 |
| 1022 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, |
| 1023 uword pc, |
| 1024 StackFrame* frame, |
| 1025 const Code& code, |
| 1026 bool optimized, |
| 1027 ActivationFrame* callee_activation, |
| 1028 const Context& entry_ctx) { |
| 1029 // We never provide both a callee activation and an entry context. |
| 1030 ASSERT((callee_activation == NULL) || entry_ctx.IsNull()); |
| 1031 ActivationFrame* activation = |
| 1032 new ActivationFrame(pc, frame->fp(), frame->sp(), code); |
| 1033 |
| 1034 // Recover the context for this frame. |
| 1035 if (optimized) { |
| 1036 // Bail out for optimized frames for now. |
| 1037 activation->SetContext(Context::Handle(isolate)); |
| 1038 |
| 1039 } else if (callee_activation == NULL) { |
| 1040 // No callee. Use incoming entry context. Could be from |
| 1041 // isolate's top context or from an entry frame. |
| 1042 activation->SetContext(entry_ctx); |
| 1043 |
| 1044 } else if (callee_activation->function().IsClosureFunction()) { |
| 1045 // If the callee is a closure, we should have stored the context |
| 1046 // in the current frame before making the call. |
| 1047 const Context& closure_call_ctx = |
| 1048 Context::Handle(isolate, activation->GetSavedCurrentContext()); |
| 1049 activation->SetContext(closure_call_ctx); |
| 1050 |
| 1051 // Sometimes there is no saved context. This is a bug. |
| 1052 // https://code.google.com/p/dart/issues/detail?id=12767 |
| 1053 if (FLAG_verbose_debug && closure_call_ctx.IsNull()) { |
| 1054 PrintStackTraceError( |
| 1055 "Expected to find saved context for call to closure function", |
| 1056 activation, callee_activation); |
| 1057 } |
| 1058 |
| 1059 } else { |
| 1060 // Use the context provided by our callee. This is either the |
| 1061 // callee's context or a context that was saved in the callee's |
| 1062 // frame. |
| 1063 const Context& callee_ctx = |
| 1064 Context::Handle(isolate, callee_activation->GetSavedEntryContextNew()); |
| 1065 activation->SetContext(callee_ctx); |
| 1066 } |
| 1067 return activation; |
| 1068 } |
| 1069 |
| 1070 |
| 1071 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate, |
| 1072 StackFrame* frame, |
| 1073 const Code& code) { |
| 1074 ASSERT(code.is_optimized()); |
| 1075 |
| 1076 // Create the DeoptContext for this deoptimization. |
| 1077 DeoptContext* deopt_context = |
| 1078 new DeoptContext(frame, code, |
| 1079 DeoptContext::kDestIsAllocated, |
| 1080 NULL, NULL); |
| 1081 isolate->set_deopt_context(deopt_context); |
| 1082 |
| 1083 deopt_context->FillDestFrame(); |
| 1084 deopt_context->MaterializeDeferredObjects(); |
| 1085 const Array& dest_frame = Array::Handle(deopt_context->DestFrameAsArray()); |
| 1086 |
| 1087 isolate->set_deopt_context(NULL); |
| 1088 delete deopt_context; |
| 1089 |
| 1090 return dest_frame.raw(); |
| 1091 } |
| 1092 |
| 1093 |
| 1094 DebuggerStackTrace* Debugger::CollectStackTraceNew() { |
| 1095 Isolate* isolate = Isolate::Current(); |
| 1096 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); |
| 1097 StackFrameIterator iterator(false); |
| 1098 ActivationFrame* current_activation = NULL; |
| 1099 Context& entry_ctx = Context::Handle(isolate->top_context()); |
| 1100 Code& code = Code::Handle(isolate); |
| 1101 Code& inlined_code = Code::Handle(isolate); |
| 1102 Array& deopt_frame = Array::Handle(isolate); |
| 1103 |
| 1104 for (StackFrame* frame = iterator.NextFrame(); |
| 1105 frame != NULL; |
| 1106 frame = iterator.NextFrame()) { |
| 1107 ASSERT(frame->IsValid()); |
| 1108 if (frame->IsEntryFrame()) { |
| 1109 current_activation = NULL; |
| 1110 entry_ctx = reinterpret_cast<EntryFrame*>(frame)->SavedContext(); |
| 1111 |
| 1112 } else if (frame->IsDartFrame()) { |
| 1113 code = frame->LookupDartCode(); |
| 1114 if (code.is_optimized()) { |
| 1115 deopt_frame = DeoptimizeToArray(isolate, frame, code); |
| 1116 for (InlinedFunctionsIterator it(code, frame->pc()); |
| 1117 !it.Done(); |
| 1118 it.Advance()) { |
| 1119 inlined_code = it.code(); |
| 1120 intptr_t deopt_frame_offset = it.GetDeoptFpOffset(); |
| 1121 current_activation = CollectDartFrame(isolate, |
| 1122 it.pc(), |
| 1123 frame, |
| 1124 inlined_code, |
| 1125 true, |
| 1126 current_activation, |
| 1127 entry_ctx); |
| 1128 current_activation->SetDeoptFrame(deopt_frame, deopt_frame_offset); |
| 1129 stack_trace->AddActivation(current_activation); |
| 1130 entry_ctx = Context::null(); // Only use entry context once. |
| 1131 } |
| 1132 } else { |
| 1133 current_activation = CollectDartFrame(isolate, |
| 1134 frame->pc(), |
| 1135 frame, |
| 1136 code, |
| 1137 false, |
| 1138 current_activation, |
| 1139 entry_ctx); |
| 1140 stack_trace->AddActivation(current_activation); |
| 1141 entry_ctx = Context::null(); // Only use entry context once. |
| 1142 } |
| 1143 } |
| 1144 } |
| 1145 return stack_trace; |
| 1146 } |
| 1147 |
| 1148 |
| 1149 |
948 DebuggerStackTrace* Debugger::CollectStackTrace() { | 1150 DebuggerStackTrace* Debugger::CollectStackTrace() { |
| 1151 if (FLAG_use_new_stacktrace) { |
| 1152 // Guard new stack trace generation under a flag in case there are |
| 1153 // problems rolling it out. |
| 1154 return CollectStackTraceNew(); |
| 1155 } |
949 Isolate* isolate = Isolate::Current(); | 1156 Isolate* isolate = Isolate::Current(); |
950 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); | 1157 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); |
951 Context& ctx = Context::Handle(isolate->top_context()); | 1158 Context& ctx = Context::Handle(isolate->top_context()); |
952 Code& code = Code::Handle(isolate); | 1159 Code& code = Code::Handle(isolate); |
953 StackFrameIterator iterator(false); | 1160 StackFrameIterator iterator(false); |
954 ActivationFrame* callee_activation = NULL; | 1161 ActivationFrame* callee_activation = NULL; |
955 bool optimized_frame_found = false; | 1162 bool optimized_frame_found = false; |
956 for (StackFrame* frame = iterator.NextFrame(); | 1163 for (StackFrame* frame = iterator.NextFrame(); |
957 frame != NULL; | 1164 frame != NULL; |
958 frame = iterator.NextFrame()) { | 1165 frame = iterator.NextFrame()) { |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1096 intptr_t last_token_pos) { | 1303 intptr_t last_token_pos) { |
1097 ASSERT(func.HasCode()); | 1304 ASSERT(func.HasCode()); |
1098 ASSERT(!func.HasOptimizedCode()); | 1305 ASSERT(!func.HasOptimizedCode()); |
1099 Code& code = Code::Handle(func.unoptimized_code()); | 1306 Code& code = Code::Handle(func.unoptimized_code()); |
1100 ASSERT(!code.IsNull()); | 1307 ASSERT(!code.IsNull()); |
1101 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 1308 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
1102 intptr_t best_fit_index = -1; | 1309 intptr_t best_fit_index = -1; |
1103 intptr_t best_fit = INT_MAX; | 1310 intptr_t best_fit = INT_MAX; |
1104 uword lowest_pc = kUwordMax; | 1311 uword lowest_pc = kUwordMax; |
1105 intptr_t lowest_pc_index = -1; | 1312 intptr_t lowest_pc_index = -1; |
1106 for (int i = 0; i < desc.Length(); i++) { | 1313 for (intptr_t i = 0; i < desc.Length(); i++) { |
1107 intptr_t desc_token_pos = desc.TokenPos(i); | 1314 intptr_t desc_token_pos = desc.TokenPos(i); |
1108 ASSERT(desc_token_pos >= 0); | 1315 ASSERT(desc_token_pos >= 0); |
1109 if (desc_token_pos < first_token_pos) { | 1316 if (desc_token_pos < first_token_pos) { |
1110 // This descriptor is before the given range. | 1317 // This descriptor is before the given range. |
1111 continue; | 1318 continue; |
1112 } | 1319 } |
1113 if (IsSafePoint(desc.DescriptorKind(i))) { | 1320 if (IsSafePoint(desc.DescriptorKind(i))) { |
1114 if ((desc_token_pos - first_token_pos) < best_fit) { | 1321 if ((desc_token_pos - first_token_pos) < best_fit) { |
1115 // So far, this descriptor has the closest token position to the | 1322 // So far, this descriptor has the closest token position to the |
1116 // beginning of the range. | 1323 // beginning of the range. |
(...skipping 25 matching lines...) Expand all Loading... |
1142 } | 1349 } |
1143 | 1350 |
1144 | 1351 |
1145 void Debugger::MakeCodeBreakpointsAt(const Function& func, | 1352 void Debugger::MakeCodeBreakpointsAt(const Function& func, |
1146 intptr_t token_pos, | 1353 intptr_t token_pos, |
1147 SourceBreakpoint* bpt) { | 1354 SourceBreakpoint* bpt) { |
1148 ASSERT(!func.HasOptimizedCode()); | 1355 ASSERT(!func.HasOptimizedCode()); |
1149 Code& code = Code::Handle(func.unoptimized_code()); | 1356 Code& code = Code::Handle(func.unoptimized_code()); |
1150 ASSERT(!code.IsNull()); | 1357 ASSERT(!code.IsNull()); |
1151 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 1358 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
1152 for (int i = 0; i < desc.Length(); i++) { | 1359 for (intptr_t i = 0; i < desc.Length(); i++) { |
1153 intptr_t desc_token_pos = desc.TokenPos(i); | 1360 intptr_t desc_token_pos = desc.TokenPos(i); |
1154 if ((desc_token_pos == token_pos) && IsSafePoint(desc.DescriptorKind(i))) { | 1361 if ((desc_token_pos == token_pos) && IsSafePoint(desc.DescriptorKind(i))) { |
1155 CodeBreakpoint* code_bpt = GetCodeBreakpoint(desc.PC(i)); | 1362 CodeBreakpoint* code_bpt = GetCodeBreakpoint(desc.PC(i)); |
1156 if (code_bpt == NULL) { | 1363 if (code_bpt == NULL) { |
1157 // No code breakpoint for this code exists; create one. | 1364 // No code breakpoint for this code exists; create one. |
1158 code_bpt = new CodeBreakpoint(func, i); | 1365 code_bpt = new CodeBreakpoint(func, i); |
1159 RegisterCodeBreakpoint(code_bpt); | 1366 RegisterCodeBreakpoint(code_bpt); |
1160 } | 1367 } |
1161 code_bpt->set_src_bpt(bpt); | 1368 code_bpt->set_src_bpt(bpt); |
1162 } | 1369 } |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1269 target_function.end_token_pos()); | 1476 target_function.end_token_pos()); |
1270 } | 1477 } |
1271 | 1478 |
1272 | 1479 |
1273 SourceBreakpoint* Debugger::SetBreakpointAtLine(const String& script_url, | 1480 SourceBreakpoint* Debugger::SetBreakpointAtLine(const String& script_url, |
1274 intptr_t line_number) { | 1481 intptr_t line_number) { |
1275 Library& lib = Library::Handle(isolate_); | 1482 Library& lib = Library::Handle(isolate_); |
1276 Script& script = Script::Handle(isolate_); | 1483 Script& script = Script::Handle(isolate_); |
1277 const GrowableObjectArray& libs = | 1484 const GrowableObjectArray& libs = |
1278 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); | 1485 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); |
1279 for (int i = 0; i < libs.Length(); i++) { | 1486 for (intptr_t i = 0; i < libs.Length(); i++) { |
1280 lib ^= libs.At(i); | 1487 lib ^= libs.At(i); |
1281 script = lib.LookupScript(script_url); | 1488 script = lib.LookupScript(script_url); |
1282 if (!script.IsNull()) { | 1489 if (!script.IsNull()) { |
1283 break; | 1490 break; |
1284 } | 1491 } |
1285 } | 1492 } |
1286 if (script.IsNull()) { | 1493 if (script.IsNull()) { |
1287 if (FLAG_verbose_debug) { | 1494 if (FLAG_verbose_debug) { |
1288 OS::Print("Failed to find script with url '%s'\n", | 1495 OS::Print("Failed to find script with url '%s'\n", |
1289 script_url.ToCString()); | 1496 script_url.ToCString()); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1416 Class& cls = Class::Handle(obj.clazz()); | 1623 Class& cls = Class::Handle(obj.clazz()); |
1417 Array& fields = Array::Handle(); | 1624 Array& fields = Array::Handle(); |
1418 Field& field = Field::Handle(); | 1625 Field& field = Field::Handle(); |
1419 const GrowableObjectArray& field_list = | 1626 const GrowableObjectArray& field_list = |
1420 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); | 1627 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); |
1421 String& field_name = String::Handle(); | 1628 String& field_name = String::Handle(); |
1422 Object& field_value = Object::Handle(); | 1629 Object& field_value = Object::Handle(); |
1423 // Iterate over fields in class hierarchy to count all instance fields. | 1630 // Iterate over fields in class hierarchy to count all instance fields. |
1424 while (!cls.IsNull()) { | 1631 while (!cls.IsNull()) { |
1425 fields = cls.fields(); | 1632 fields = cls.fields(); |
1426 for (int i = 0; i < fields.Length(); i++) { | 1633 for (intptr_t i = 0; i < fields.Length(); i++) { |
1427 field ^= fields.At(i); | 1634 field ^= fields.At(i); |
1428 if (!field.is_static()) { | 1635 if (!field.is_static()) { |
1429 field_name = field.name(); | 1636 field_name = field.name(); |
1430 field_list.Add(field_name); | 1637 field_list.Add(field_name); |
1431 field_value = GetInstanceField(cls, field_name, obj); | 1638 field_value = GetInstanceField(cls, field_name, obj); |
1432 field_list.Add(field_value); | 1639 field_list.Add(field_value); |
1433 } | 1640 } |
1434 } | 1641 } |
1435 cls = cls.SuperClass(); | 1642 cls = cls.SuperClass(); |
1436 } | 1643 } |
1437 return Array::MakeArray(field_list); | 1644 return Array::MakeArray(field_list); |
1438 } | 1645 } |
1439 | 1646 |
1440 | 1647 |
1441 RawArray* Debugger::GetStaticFields(const Class& cls) { | 1648 RawArray* Debugger::GetStaticFields(const Class& cls) { |
1442 const GrowableObjectArray& field_list = | 1649 const GrowableObjectArray& field_list = |
1443 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); | 1650 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); |
1444 Array& fields = Array::Handle(cls.fields()); | 1651 Array& fields = Array::Handle(cls.fields()); |
1445 Field& field = Field::Handle(); | 1652 Field& field = Field::Handle(); |
1446 String& field_name = String::Handle(); | 1653 String& field_name = String::Handle(); |
1447 Object& field_value = Object::Handle(); | 1654 Object& field_value = Object::Handle(); |
1448 for (int i = 0; i < fields.Length(); i++) { | 1655 for (intptr_t i = 0; i < fields.Length(); i++) { |
1449 field ^= fields.At(i); | 1656 field ^= fields.At(i); |
1450 if (field.is_static()) { | 1657 if (field.is_static()) { |
1451 field_name = field.name(); | 1658 field_name = field.name(); |
1452 field_value = GetStaticField(cls, field_name); | 1659 field_value = GetStaticField(cls, field_name); |
1453 field_list.Add(field_name); | 1660 field_list.Add(field_name); |
1454 field_list.Add(field_value); | 1661 field_list.Add(field_value); |
1455 } | 1662 } |
1456 } | 1663 } |
1457 return Array::MakeArray(field_list); | 1664 return Array::MakeArray(field_list); |
1458 } | 1665 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1498 } | 1705 } |
1499 | 1706 |
1500 | 1707 |
1501 RawArray* Debugger::GetGlobalFields(const Library& lib) { | 1708 RawArray* Debugger::GetGlobalFields(const Library& lib) { |
1502 const GrowableObjectArray& field_list = | 1709 const GrowableObjectArray& field_list = |
1503 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); | 1710 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); |
1504 String& prefix_name = String::Handle(isolate_); | 1711 String& prefix_name = String::Handle(isolate_); |
1505 CollectLibraryFields(field_list, lib, prefix_name, true); | 1712 CollectLibraryFields(field_list, lib, prefix_name, true); |
1506 Library& imported = Library::Handle(isolate_); | 1713 Library& imported = Library::Handle(isolate_); |
1507 intptr_t num_imports = lib.num_imports(); | 1714 intptr_t num_imports = lib.num_imports(); |
1508 for (int i = 0; i < num_imports; i++) { | 1715 for (intptr_t i = 0; i < num_imports; i++) { |
1509 imported = lib.ImportLibraryAt(i); | 1716 imported = lib.ImportLibraryAt(i); |
1510 ASSERT(!imported.IsNull()); | 1717 ASSERT(!imported.IsNull()); |
1511 CollectLibraryFields(field_list, imported, prefix_name, false); | 1718 CollectLibraryFields(field_list, imported, prefix_name, false); |
1512 } | 1719 } |
1513 LibraryPrefix& prefix = LibraryPrefix::Handle(isolate_); | 1720 LibraryPrefix& prefix = LibraryPrefix::Handle(isolate_); |
1514 LibraryPrefixIterator it(lib); | 1721 LibraryPrefixIterator it(lib); |
1515 while (it.HasNext()) { | 1722 while (it.HasNext()) { |
1516 prefix = it.GetNext(); | 1723 prefix = it.GetNext(); |
1517 prefix_name = prefix.name(); | 1724 prefix_name = prefix.name(); |
1518 ASSERT(!prefix_name.IsNull()); | 1725 ASSERT(!prefix_name.IsNull()); |
1519 prefix_name = String::Concat(prefix_name, Symbols::Dot()); | 1726 prefix_name = String::Concat(prefix_name, Symbols::Dot()); |
1520 for (int i = 0; i < prefix.num_imports(); i++) { | 1727 for (intptr_t i = 0; i < prefix.num_imports(); i++) { |
1521 imported = prefix.GetLibrary(i); | 1728 imported = prefix.GetLibrary(i); |
1522 CollectLibraryFields(field_list, imported, prefix_name, false); | 1729 CollectLibraryFields(field_list, imported, prefix_name, false); |
1523 } | 1730 } |
1524 } | 1731 } |
1525 return Array::MakeArray(field_list); | 1732 return Array::MakeArray(field_list); |
1526 } | 1733 } |
1527 | 1734 |
1528 | 1735 |
1529 void Debugger::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 1736 void Debugger::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
1530 ASSERT(visitor != NULL); | 1737 ASSERT(visitor != NULL); |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1877 } | 2084 } |
1878 | 2085 |
1879 | 2086 |
1880 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2087 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
1881 ASSERT(bpt->next() == NULL); | 2088 ASSERT(bpt->next() == NULL); |
1882 bpt->set_next(code_breakpoints_); | 2089 bpt->set_next(code_breakpoints_); |
1883 code_breakpoints_ = bpt; | 2090 code_breakpoints_ = bpt; |
1884 } | 2091 } |
1885 | 2092 |
1886 } // namespace dart | 2093 } // namespace dart |
OLD | NEW |