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