| 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 |