OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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_index_table.h" | 7 #include "vm/code_index_table.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" |
11 #include "vm/flags.h" | 11 #include "vm/flags.h" |
12 #include "vm/globals.h" | 12 #include "vm/globals.h" |
13 #include "vm/longjump.h" | 13 #include "vm/longjump.h" |
14 #include "vm/object.h" | 14 #include "vm/object.h" |
15 #include "vm/object_store.h" | 15 #include "vm/object_store.h" |
16 #include "vm/os.h" | 16 #include "vm/os.h" |
17 #include "vm/stack_frame.h" | 17 #include "vm/stack_frame.h" |
18 #include "vm/stub_code.h" | 18 #include "vm/stub_code.h" |
19 #include "vm/visitor.h" | 19 #include "vm/visitor.h" |
20 | 20 |
21 | 21 |
22 namespace dart { | 22 namespace dart { |
23 | 23 |
24 static const bool verbose = false; | 24 static const bool verbose = false; |
25 | 25 |
| 26 |
26 Breakpoint::Breakpoint(const Function& func, intptr_t pc_desc_index) | 27 Breakpoint::Breakpoint(const Function& func, intptr_t pc_desc_index) |
27 : function_(func.raw()), | 28 : function_(func.raw()), |
28 pc_desc_index_(pc_desc_index), | 29 pc_desc_index_(pc_desc_index), |
29 pc_(0), | 30 pc_(0), |
30 saved_bytes_(0), | 31 saved_bytes_(0), |
31 line_number_(-1), | 32 line_number_(-1), |
32 next_(NULL) { | 33 next_(NULL) { |
33 Code& code = Code::Handle(func.code()); | 34 Code& code = Code::Handle(func.code()); |
34 ASSERT(!code.IsNull()); // Function must be compiled. | 35 ASSERT(!code.IsNull()); // Function must be compiled. |
35 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 36 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 function = cls.LookupDynamicFunction(function_name); | 341 function = cls.LookupDynamicFunction(function_name); |
341 } | 342 } |
342 } | 343 } |
343 return function.raw(); | 344 return function.raw(); |
344 } | 345 } |
345 | 346 |
346 | 347 |
347 // TODO(hausner): Distinguish between newly created breakpoints and | 348 // TODO(hausner): Distinguish between newly created breakpoints and |
348 // returning a breakpoint that already exists? | 349 // returning a breakpoint that already exists? |
349 Breakpoint* Debugger::SetBreakpoint(const Function& target_function, | 350 Breakpoint* Debugger::SetBreakpoint(const Function& target_function, |
350 intptr_t token_index) { | 351 intptr_t token_index, |
| 352 Error* error) { |
351 if ((token_index < target_function.token_index()) || | 353 if ((token_index < target_function.token_index()) || |
352 (target_function.end_token_index() <= token_index)) { | 354 (target_function.end_token_index() <= token_index)) { |
353 // The given token position is not within the target function. | 355 // The given token position is not within the target function. |
354 return NULL; | 356 return NULL; |
355 } | 357 } |
356 if (!target_function.HasCode()) { | 358 if (!target_function.HasCode()) { |
357 Compiler::CompileFunction(target_function); | 359 *error = Compiler::CompileFunction(target_function); |
| 360 if (!error->IsNull()) { |
| 361 return NULL; |
| 362 } |
358 } | 363 } |
359 Code& code = Code::Handle(target_function.code()); | 364 Code& code = Code::Handle(target_function.code()); |
360 ASSERT(!code.IsNull()); | 365 ASSERT(!code.IsNull()); |
361 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 366 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
362 for (int i = 0; i < desc.Length(); i++) { | 367 for (int i = 0; i < desc.Length(); i++) { |
363 if (desc.TokenIndex(i) < token_index) { | 368 if (desc.TokenIndex(i) < token_index) { |
364 continue; | 369 continue; |
365 } | 370 } |
366 PcDescriptors::Kind kind = desc.DescriptorKind(i); | 371 PcDescriptors::Kind kind = desc.DescriptorKind(i); |
367 Breakpoint* bpt = NULL; | 372 Breakpoint* bpt = NULL; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 ASSERT(bpt->pc() == desc.PC(desc_index)); | 422 ASSERT(bpt->pc() == desc.PC(desc_index)); |
418 PcDescriptors::Kind kind = desc.DescriptorKind(desc_index); | 423 PcDescriptors::Kind kind = desc.DescriptorKind(desc_index); |
419 if (kind == PcDescriptors::kIcCall) { | 424 if (kind == PcDescriptors::kIcCall) { |
420 CodePatcher::PatchInstanceCallAt(desc.PC(desc_index), bpt->saved_bytes_); | 425 CodePatcher::PatchInstanceCallAt(desc.PC(desc_index), bpt->saved_bytes_); |
421 } else { | 426 } else { |
422 CodePatcher::PatchStaticCallAt(desc.PC(desc_index), bpt->saved_bytes_); | 427 CodePatcher::PatchStaticCallAt(desc.PC(desc_index), bpt->saved_bytes_); |
423 } | 428 } |
424 } | 429 } |
425 | 430 |
426 | 431 |
427 Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function) { | 432 Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function, |
| 433 Error* error) { |
428 ASSERT(!target_function.IsNull()); | 434 ASSERT(!target_function.IsNull()); |
429 return SetBreakpoint(target_function, target_function.token_index()); | 435 return SetBreakpoint(target_function, target_function.token_index(), error); |
430 } | 436 } |
431 | 437 |
432 | 438 |
433 Breakpoint* Debugger::SetBreakpointAtLine(const String& script_url, | 439 Breakpoint* Debugger::SetBreakpointAtLine(const String& script_url, |
434 intptr_t line_number) { | 440 intptr_t line_number, |
| 441 Error* error) { |
435 Library& lib = Library::Handle(); | 442 Library& lib = Library::Handle(); |
436 Script& script = Script::Handle(); | 443 Script& script = Script::Handle(); |
437 lib = isolate_->object_store()->registered_libraries(); | 444 lib = isolate_->object_store()->registered_libraries(); |
438 while (!lib.IsNull()) { | 445 while (!lib.IsNull()) { |
439 script = lib.LookupScript(script_url); | 446 script = lib.LookupScript(script_url); |
440 if (!script.IsNull()) { | 447 if (!script.IsNull()) { |
441 break; | 448 break; |
442 } | 449 } |
443 lib = lib.next_registered(); | 450 lib = lib.next_registered(); |
444 } | 451 } |
445 if (script.IsNull()) { | 452 if (script.IsNull()) { |
446 return NULL; | 453 return NULL; |
447 } | 454 } |
448 intptr_t token_index_at_line = script.TokenIndexAtLine(line_number); | 455 intptr_t token_index_at_line = script.TokenIndexAtLine(line_number); |
449 if (token_index_at_line < 0) { | 456 if (token_index_at_line < 0) { |
450 // Script does not contain the given line number. | 457 // Script does not contain the given line number. |
451 return NULL; | 458 return NULL; |
452 } | 459 } |
453 const Function& func = | 460 const Function& func = |
454 Function::Handle(lib.LookupFunctionInScript(script, token_index_at_line)); | 461 Function::Handle(lib.LookupFunctionInScript(script, token_index_at_line)); |
455 if (func.IsNull()) { | 462 if (func.IsNull()) { |
456 return NULL; | 463 return NULL; |
457 } | 464 } |
458 return SetBreakpoint(func, token_index_at_line); | 465 return SetBreakpoint(func, token_index_at_line, error); |
459 } | 466 } |
460 | 467 |
461 | 468 |
462 static RawArray* MakeNameValueList(const GrowableArray<Object*>& pairs) { | 469 static RawArray* MakeNameValueList(const GrowableArray<Object*>& pairs) { |
463 int pairs_len = pairs.length(); | 470 int pairs_len = pairs.length(); |
464 ASSERT(pairs_len % 2 == 0); | 471 ASSERT(pairs_len % 2 == 0); |
465 const Array& list = Array::Handle(Array::New(pairs_len)); | 472 const Array& list = Array::Handle(Array::New(pairs_len)); |
466 for (int i = 0; i < pairs_len; i++) { | 473 for (int i = 0; i < pairs_len; i++) { |
467 list.SetAt(i, *pairs[i]); | 474 list.SetAt(i, *pairs[i]); |
468 } | 475 } |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 | 690 |
684 | 691 |
685 void Debugger::RegisterBreakpoint(Breakpoint* bpt) { | 692 void Debugger::RegisterBreakpoint(Breakpoint* bpt) { |
686 ASSERT(bpt->next() == NULL); | 693 ASSERT(bpt->next() == NULL); |
687 bpt->set_next(this->breakpoints_); | 694 bpt->set_next(this->breakpoints_); |
688 this->breakpoints_ = bpt; | 695 this->breakpoints_ = bpt; |
689 } | 696 } |
690 | 697 |
691 | 698 |
692 } // namespace dart | 699 } // namespace dart |
OLD | NEW |