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