OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 | 556 |
557 | 557 |
558 // Default break enabled. | 558 // Default break enabled. |
559 bool Debug::disable_break_ = false; | 559 bool Debug::disable_break_ = false; |
560 | 560 |
561 // Default call debugger on uncaught exception. | 561 // Default call debugger on uncaught exception. |
562 bool Debug::break_on_exception_ = false; | 562 bool Debug::break_on_exception_ = false; |
563 bool Debug::break_on_uncaught_exception_ = true; | 563 bool Debug::break_on_uncaught_exception_ = true; |
564 | 564 |
565 Handle<Context> Debug::debug_context_ = Handle<Context>(); | 565 Handle<Context> Debug::debug_context_ = Handle<Context>(); |
566 Code* Debug::debug_break_return_entry_ = NULL; | |
567 Code* Debug::debug_break_return_ = NULL; | 566 Code* Debug::debug_break_return_ = NULL; |
568 | 567 |
569 | 568 |
570 void ScriptCache::Add(Handle<Script> script) { | 569 void ScriptCache::Add(Handle<Script> script) { |
571 // Create an entry in the hash map for the script. | 570 // Create an entry in the hash map for the script. |
572 int id = Smi::cast(script->id())->value(); | 571 int id = Smi::cast(script->id())->value(); |
573 HashMap::Entry* entry = | 572 HashMap::Entry* entry = |
574 HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true); | 573 HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true); |
575 if (entry->value != NULL) { | 574 if (entry->value != NULL) { |
576 ASSERT(*script == *reinterpret_cast<Script**>(entry->value)); | 575 ASSERT(*script == *reinterpret_cast<Script**>(entry->value)); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 | 636 |
638 // Clear the weak handle. | 637 // Clear the weak handle. |
639 obj.Dispose(); | 638 obj.Dispose(); |
640 obj.Clear(); | 639 obj.Clear(); |
641 } | 640 } |
642 | 641 |
643 | 642 |
644 void Debug::Setup(bool create_heap_objects) { | 643 void Debug::Setup(bool create_heap_objects) { |
645 ThreadInit(); | 644 ThreadInit(); |
646 if (create_heap_objects) { | 645 if (create_heap_objects) { |
647 // Get code to handle entry to debug break on return. | |
648 debug_break_return_entry_ = | |
649 Builtins::builtin(Builtins::Return_DebugBreakEntry); | |
650 ASSERT(debug_break_return_entry_->IsCode()); | |
651 | |
652 // Get code to handle debug break on return. | 646 // Get code to handle debug break on return. |
653 debug_break_return_ = | 647 debug_break_return_ = |
654 Builtins::builtin(Builtins::Return_DebugBreak); | 648 Builtins::builtin(Builtins::Return_DebugBreak); |
655 ASSERT(debug_break_return_->IsCode()); | 649 ASSERT(debug_break_return_->IsCode()); |
656 } | 650 } |
657 } | 651 } |
658 | 652 |
659 | 653 |
660 void Debug::HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data) { | 654 void Debug::HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data) { |
661 DebugInfoListNode* node = reinterpret_cast<DebugInfoListNode*>(data); | 655 DebugInfoListNode* node = reinterpret_cast<DebugInfoListNode*>(data); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 | 797 |
804 | 798 |
805 // Set the flag indicating that preemption happened during debugging. | 799 // Set the flag indicating that preemption happened during debugging. |
806 void Debug::PreemptionWhileInDebugger() { | 800 void Debug::PreemptionWhileInDebugger() { |
807 ASSERT(InDebugger()); | 801 ASSERT(InDebugger()); |
808 Debug::set_interrupts_pending(PREEMPT); | 802 Debug::set_interrupts_pending(PREEMPT); |
809 } | 803 } |
810 | 804 |
811 | 805 |
812 void Debug::Iterate(ObjectVisitor* v) { | 806 void Debug::Iterate(ObjectVisitor* v) { |
813 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_entry_))); | |
814 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_))); | 807 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_))); |
815 } | 808 } |
816 | 809 |
817 | 810 |
818 Object* Debug::Break(Arguments args) { | 811 Object* Debug::Break(Arguments args) { |
819 HandleScope scope; | 812 HandleScope scope; |
820 ASSERT(args.length() == 0); | 813 ASSERT(args.length() == 0); |
821 | 814 |
822 // Get the top-most JavaScript frame. | 815 // Get the top-most JavaScript frame. |
823 JavaScriptFrameIterator it; | 816 JavaScriptFrameIterator it; |
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1607 Handle<Code> frame_code(frame->code()); | 1600 Handle<Code> frame_code(frame->code()); |
1608 ASSERT(frame_code.is_identical_to(code)); | 1601 ASSERT(frame_code.is_identical_to(code)); |
1609 #endif | 1602 #endif |
1610 | 1603 |
1611 // Find the call address in the running code. This address holds the call to | 1604 // Find the call address in the running code. This address holds the call to |
1612 // either a DebugBreakXXX or to the debug break return entry code if the | 1605 // either a DebugBreakXXX or to the debug break return entry code if the |
1613 // break point is still active after processing the break point. | 1606 // break point is still active after processing the break point. |
1614 Address addr = frame->pc() - Assembler::kPatchReturnSequenceLength; | 1607 Address addr = frame->pc() - Assembler::kPatchReturnSequenceLength; |
1615 | 1608 |
1616 // Check if the location is at JS exit. | 1609 // Check if the location is at JS exit. |
1617 bool at_js_exit = false; | 1610 bool at_js_return = false; |
| 1611 bool break_at_js_return_active = false; |
1618 RelocIterator it(debug_info->code()); | 1612 RelocIterator it(debug_info->code()); |
1619 while (!it.done()) { | 1613 while (!it.done()) { |
1620 if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) { | 1614 if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) { |
1621 at_js_exit = (it.rinfo()->pc() == | 1615 at_js_return = (it.rinfo()->pc() == |
1622 addr - Assembler::kPatchReturnSequenceAddressOffset); | 1616 addr - Assembler::kPatchReturnSequenceAddressOffset); |
| 1617 break_at_js_return_active = it.rinfo()->IsCallInstruction(); |
1623 } | 1618 } |
1624 it.next(); | 1619 it.next(); |
1625 } | 1620 } |
1626 | 1621 |
1627 // Handle the jump to continue execution after break point depending on the | 1622 // Handle the jump to continue execution after break point depending on the |
1628 // break location. | 1623 // break location. |
1629 if (at_js_exit) { | 1624 if (at_js_return) { |
1630 // First check if the call in the code is still the debug break return | 1625 // If the break point as return is still active jump to the corresponding |
1631 // entry code. If it is the break point is still active. If not the break | 1626 // place in the original code. If not the break point was removed during |
1632 // point was removed during break point processing. | 1627 // break point processing. |
1633 if (Assembler::target_address_at(addr) == | 1628 if (break_at_js_return_active) { |
1634 debug_break_return_entry()->entry()) { | |
1635 // Break point still active. Jump to the corresponding place in the | |
1636 // original code. | |
1637 addr += original_code->instruction_start() - code->instruction_start(); | 1629 addr += original_code->instruction_start() - code->instruction_start(); |
1638 } | 1630 } |
1639 | 1631 |
1640 // Move back to where the call instruction sequence started. | 1632 // Move back to where the call instruction sequence started. |
1641 thread_local_.after_break_target_ = | 1633 thread_local_.after_break_target_ = |
1642 addr - Assembler::kPatchReturnSequenceAddressOffset; | 1634 addr - Assembler::kPatchReturnSequenceAddressOffset; |
1643 } else { | 1635 } else { |
1644 // Check if there still is a debug break call at the target address. If the | 1636 // Check if there still is a debug break call at the target address. If the |
1645 // break point has been removed it will have disappeared. If it have | 1637 // break point has been removed it will have disappeared. If it have |
1646 // disappeared don't try to look in the original code as the running code | 1638 // disappeared don't try to look in the original code as the running code |
(...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2722 | 2714 |
2723 | 2715 |
2724 void LockingCommandMessageQueue::Clear() { | 2716 void LockingCommandMessageQueue::Clear() { |
2725 ScopedLock sl(lock_); | 2717 ScopedLock sl(lock_); |
2726 queue_.Clear(); | 2718 queue_.Clear(); |
2727 } | 2719 } |
2728 | 2720 |
2729 #endif // ENABLE_DEBUGGER_SUPPORT | 2721 #endif // ENABLE_DEBUGGER_SUPPORT |
2730 | 2722 |
2731 } } // namespace v8::internal | 2723 } } // namespace v8::internal |
OLD | NEW |