| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 int id = script->id()->value(); | 639 int id = script->id()->value(); |
| 640 HashMap::Entry* entry = | 640 HashMap::Entry* entry = |
| 641 HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true); | 641 HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true); |
| 642 if (entry->value != NULL) { | 642 if (entry->value != NULL) { |
| 643 ASSERT(*script == *reinterpret_cast<Script**>(entry->value)); | 643 ASSERT(*script == *reinterpret_cast<Script**>(entry->value)); |
| 644 return; | 644 return; |
| 645 } | 645 } |
| 646 // Globalize the script object, make it weak and use the location of the | 646 // Globalize the script object, make it weak and use the location of the |
| 647 // global handle as the value in the hash map. | 647 // global handle as the value in the hash map. |
| 648 Handle<Script> script_ = | 648 Handle<Script> script_ = |
| 649 Handle<Script>::cast( | 649 Handle<Script>::cast(global_handles->Create(*script)); |
| 650 (global_handles->Create(*script))); | 650 GlobalHandles::MakeWeak(reinterpret_cast<Object**>(script_.location()), |
| 651 global_handles->MakeWeak(reinterpret_cast<Object**>(script_.location()), | 651 this, |
| 652 this, | 652 ScriptCache::HandleWeakScript); |
| 653 ScriptCache::HandleWeakScript); | |
| 654 entry->value = script_.location(); | 653 entry->value = script_.location(); |
| 655 } | 654 } |
| 656 | 655 |
| 657 | 656 |
| 658 Handle<FixedArray> ScriptCache::GetScripts() { | 657 Handle<FixedArray> ScriptCache::GetScripts() { |
| 659 Factory* factory = isolate_->factory(); | 658 Factory* factory = isolate_->factory(); |
| 660 Handle<FixedArray> instances = factory->NewFixedArray(occupancy()); | 659 Handle<FixedArray> instances = factory->NewFixedArray(occupancy()); |
| 661 int count = 0; | 660 int count = 0; |
| 662 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { | 661 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { |
| 663 ASSERT(entry->value != NULL); | 662 ASSERT(entry->value != NULL); |
| 664 if (entry->value != NULL) { | 663 if (entry->value != NULL) { |
| 665 instances->set(count, *reinterpret_cast<Script**>(entry->value)); | 664 instances->set(count, *reinterpret_cast<Script**>(entry->value)); |
| 666 count++; | 665 count++; |
| 667 } | 666 } |
| 668 } | 667 } |
| 669 return instances; | 668 return instances; |
| 670 } | 669 } |
| 671 | 670 |
| 672 | 671 |
| 673 void ScriptCache::ProcessCollectedScripts() { | 672 void ScriptCache::ProcessCollectedScripts() { |
| 674 Debugger* debugger = isolate_->debugger(); | 673 Debugger* debugger = isolate_->debugger(); |
| 675 for (int i = 0; i < collected_scripts_.length(); i++) { | 674 for (int i = 0; i < collected_scripts_.length(); i++) { |
| 676 debugger->OnScriptCollected(collected_scripts_[i]); | 675 debugger->OnScriptCollected(collected_scripts_[i]); |
| 677 } | 676 } |
| 678 collected_scripts_.Clear(); | 677 collected_scripts_.Clear(); |
| 679 } | 678 } |
| 680 | 679 |
| 681 | 680 |
| 682 void ScriptCache::Clear() { | 681 void ScriptCache::Clear() { |
| 683 GlobalHandles* global_handles = isolate_->global_handles(); | |
| 684 // Iterate the script cache to get rid of all the weak handles. | 682 // Iterate the script cache to get rid of all the weak handles. |
| 685 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { | 683 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { |
| 686 ASSERT(entry != NULL); | 684 ASSERT(entry != NULL); |
| 687 Object** location = reinterpret_cast<Object**>(entry->value); | 685 Object** location = reinterpret_cast<Object**>(entry->value); |
| 688 ASSERT((*location)->IsScript()); | 686 ASSERT((*location)->IsScript()); |
| 689 global_handles->ClearWeakness(location); | 687 GlobalHandles::ClearWeakness(location); |
| 690 global_handles->Destroy(location); | 688 GlobalHandles::Destroy(location); |
| 691 } | 689 } |
| 692 // Clear the content of the hash map. | 690 // Clear the content of the hash map. |
| 693 HashMap::Clear(); | 691 HashMap::Clear(); |
| 694 } | 692 } |
| 695 | 693 |
| 696 | 694 |
| 697 void ScriptCache::HandleWeakScript(v8::Isolate* isolate, | 695 void ScriptCache::HandleWeakScript( |
| 698 v8::Persistent<v8::Value>* obj, | 696 const v8::WeakCallbackData<v8::Value, void>& data) { |
| 699 void* data) { | 697 // Retrieve the script identifier. |
| 700 ScriptCache* script_cache = reinterpret_cast<ScriptCache*>(data); | 698 Handle<Object> object = Utils::OpenHandle(*data.GetValue()); |
| 701 // Find the location of the global handle. | 699 int id = Handle<Script>::cast(object)->id()->value(); |
| 702 Script** location = | 700 void* key = reinterpret_cast<void*>(id); |
| 703 reinterpret_cast<Script**>(Utils::OpenPersistent(*obj).location()); | 701 uint32_t hash = Hash(id); |
| 704 ASSERT((*location)->IsScript()); | |
| 705 | 702 |
| 706 // Remove the entry from the cache. | 703 // Remove the corresponding entry from the cache. |
| 707 int id = (*location)->id()->value(); | 704 ScriptCache* script_cache = |
| 708 script_cache->Remove(reinterpret_cast<void*>(id), Hash(id)); | 705 reinterpret_cast<ScriptCache*>(data.GetParameter()); |
| 706 HashMap::Entry* entry = script_cache->Lookup(key, hash, false); |
| 707 Object** location = reinterpret_cast<Object**>(entry->value); |
| 708 script_cache->Remove(key, hash); |
| 709 script_cache->collected_scripts_.Add(id); | 709 script_cache->collected_scripts_.Add(id); |
| 710 | 710 |
| 711 // Clear the weak handle. | 711 // Clear the weak handle. |
| 712 obj->Reset(); | 712 GlobalHandles::Destroy(location); |
| 713 } | 713 } |
| 714 | 714 |
| 715 | 715 |
| 716 void Debug::SetUp(bool create_heap_objects) { | 716 void Debug::SetUp(bool create_heap_objects) { |
| 717 ThreadInit(); | 717 ThreadInit(); |
| 718 if (create_heap_objects) { | 718 if (create_heap_objects) { |
| 719 // Get code to handle debug break on return. | 719 // Get code to handle debug break on return. |
| 720 debug_break_return_ = | 720 debug_break_return_ = |
| 721 isolate_->builtins()->builtin(Builtins::kReturn_DebugBreak); | 721 isolate_->builtins()->builtin(Builtins::kReturn_DebugBreak); |
| 722 ASSERT(debug_break_return_->IsCode()); | 722 ASSERT(debug_break_return_->IsCode()); |
| 723 // Get code to handle debug break in debug break slots. | 723 // Get code to handle debug break in debug break slots. |
| 724 debug_break_slot_ = | 724 debug_break_slot_ = |
| 725 isolate_->builtins()->builtin(Builtins::kSlot_DebugBreak); | 725 isolate_->builtins()->builtin(Builtins::kSlot_DebugBreak); |
| 726 ASSERT(debug_break_slot_->IsCode()); | 726 ASSERT(debug_break_slot_->IsCode()); |
| 727 } | 727 } |
| 728 } | 728 } |
| 729 | 729 |
| 730 | 730 |
| 731 void Debug::HandleWeakDebugInfo(v8::Isolate* isolate, | 731 void Debug::HandleWeakDebugInfo( |
| 732 v8::Persistent<v8::Value>* obj, | 732 const v8::WeakCallbackData<v8::Value, void>& data) { |
| 733 void* data) { | 733 Debug* debug = reinterpret_cast<Isolate*>(data.GetIsolate())->debug(); |
| 734 Debug* debug = reinterpret_cast<Isolate*>(isolate)->debug(); | 734 DebugInfoListNode* node = |
| 735 DebugInfoListNode* node = reinterpret_cast<DebugInfoListNode*>(data); | 735 reinterpret_cast<DebugInfoListNode*>(data.GetParameter()); |
| 736 // We need to clear all breakpoints associated with the function to restore | 736 // We need to clear all breakpoints associated with the function to restore |
| 737 // original code and avoid patching the code twice later because | 737 // original code and avoid patching the code twice later because |
| 738 // the function will live in the heap until next gc, and can be found by | 738 // the function will live in the heap until next gc, and can be found by |
| 739 // Debug::FindSharedFunctionInfoInScript. | 739 // Debug::FindSharedFunctionInfoInScript. |
| 740 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); | 740 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); |
| 741 it.ClearAllDebugBreak(); | 741 it.ClearAllDebugBreak(); |
| 742 debug->RemoveDebugInfo(node->debug_info()); | 742 debug->RemoveDebugInfo(node->debug_info()); |
| 743 #ifdef DEBUG | 743 #ifdef DEBUG |
| 744 node = debug->debug_info_list_; | 744 for (DebugInfoListNode* n = debug->debug_info_list_; |
| 745 while (node != NULL) { | 745 n != NULL; |
| 746 ASSERT(node != reinterpret_cast<DebugInfoListNode*>(data)); | 746 n = n->next()) { |
| 747 node = node->next(); | 747 ASSERT(n != node); |
| 748 } | 748 } |
| 749 #endif | 749 #endif |
| 750 } | 750 } |
| 751 | 751 |
| 752 | 752 |
| 753 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { | 753 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { |
| 754 // Globalize the request debug info object and make it weak. |
| 754 GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles(); | 755 GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles(); |
| 755 // Globalize the request debug info object and make it weak. | 756 debug_info_ = Handle<DebugInfo>::cast(global_handles->Create(debug_info)); |
| 756 debug_info_ = Handle<DebugInfo>::cast( | 757 GlobalHandles::MakeWeak(reinterpret_cast<Object**>(debug_info_.location()), |
| 757 (global_handles->Create(debug_info))); | 758 this, |
| 758 global_handles->MakeWeak(reinterpret_cast<Object**>(debug_info_.location()), | 759 Debug::HandleWeakDebugInfo); |
| 759 this, | |
| 760 Debug::HandleWeakDebugInfo); | |
| 761 } | 760 } |
| 762 | 761 |
| 763 | 762 |
| 764 DebugInfoListNode::~DebugInfoListNode() { | 763 DebugInfoListNode::~DebugInfoListNode() { |
| 765 debug_info_->GetIsolate()->global_handles()->Destroy( | 764 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_info_.location())); |
| 766 reinterpret_cast<Object**>(debug_info_.location())); | |
| 767 } | 765 } |
| 768 | 766 |
| 769 | 767 |
| 770 bool Debug::CompileDebuggerScript(Isolate* isolate, int index) { | 768 bool Debug::CompileDebuggerScript(Isolate* isolate, int index) { |
| 771 Factory* factory = isolate->factory(); | 769 Factory* factory = isolate->factory(); |
| 772 HandleScope scope(isolate); | 770 HandleScope scope(isolate); |
| 773 | 771 |
| 774 // Bail out if the index is invalid. | 772 // Bail out if the index is invalid. |
| 775 if (index == -1) { | 773 if (index == -1) { |
| 776 return false; | 774 return false; |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 void Debug::Unload() { | 912 void Debug::Unload() { |
| 915 // Return debugger is not loaded. | 913 // Return debugger is not loaded. |
| 916 if (!IsLoaded()) { | 914 if (!IsLoaded()) { |
| 917 return; | 915 return; |
| 918 } | 916 } |
| 919 | 917 |
| 920 // Clear the script cache. | 918 // Clear the script cache. |
| 921 DestroyScriptCache(); | 919 DestroyScriptCache(); |
| 922 | 920 |
| 923 // Clear debugger context global handle. | 921 // Clear debugger context global handle. |
| 924 isolate_->global_handles()->Destroy( | 922 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location())); |
| 925 reinterpret_cast<Object**>(debug_context_.location())); | |
| 926 debug_context_ = Handle<Context>(); | 923 debug_context_ = Handle<Context>(); |
| 927 } | 924 } |
| 928 | 925 |
| 929 | 926 |
| 930 // Set the flag indicating that preemption happened during debugging. | 927 // Set the flag indicating that preemption happened during debugging. |
| 931 void Debug::PreemptionWhileInDebugger() { | 928 void Debug::PreemptionWhileInDebugger() { |
| 932 ASSERT(InDebugger()); | 929 ASSERT(InDebugger()); |
| 933 Debug::set_interrupts_pending(PREEMPT); | 930 Debug::set_interrupts_pending(PREEMPT); |
| 934 } | 931 } |
| 935 | 932 |
| (...skipping 2306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3242 | 3239 |
| 3243 | 3240 |
| 3244 void Debugger::SetEventListener(Handle<Object> callback, | 3241 void Debugger::SetEventListener(Handle<Object> callback, |
| 3245 Handle<Object> data) { | 3242 Handle<Object> data) { |
| 3246 HandleScope scope(isolate_); | 3243 HandleScope scope(isolate_); |
| 3247 GlobalHandles* global_handles = isolate_->global_handles(); | 3244 GlobalHandles* global_handles = isolate_->global_handles(); |
| 3248 | 3245 |
| 3249 // Clear the global handles for the event listener and the event listener data | 3246 // Clear the global handles for the event listener and the event listener data |
| 3250 // object. | 3247 // object. |
| 3251 if (!event_listener_.is_null()) { | 3248 if (!event_listener_.is_null()) { |
| 3252 global_handles->Destroy( | 3249 GlobalHandles::Destroy( |
| 3253 reinterpret_cast<Object**>(event_listener_.location())); | 3250 reinterpret_cast<Object**>(event_listener_.location())); |
| 3254 event_listener_ = Handle<Object>(); | 3251 event_listener_ = Handle<Object>(); |
| 3255 } | 3252 } |
| 3256 if (!event_listener_data_.is_null()) { | 3253 if (!event_listener_data_.is_null()) { |
| 3257 global_handles->Destroy( | 3254 GlobalHandles::Destroy( |
| 3258 reinterpret_cast<Object**>(event_listener_data_.location())); | 3255 reinterpret_cast<Object**>(event_listener_data_.location())); |
| 3259 event_listener_data_ = Handle<Object>(); | 3256 event_listener_data_ = Handle<Object>(); |
| 3260 } | 3257 } |
| 3261 | 3258 |
| 3262 // If there is a new debug event listener register it together with its data | 3259 // If there is a new debug event listener register it together with its data |
| 3263 // object. | 3260 // object. |
| 3264 if (!callback->IsUndefined() && !callback->IsNull()) { | 3261 if (!callback->IsUndefined() && !callback->IsNull()) { |
| 3265 event_listener_ = Handle<Object>::cast( | 3262 event_listener_ = Handle<Object>::cast( |
| 3266 global_handles->Create(*callback)); | 3263 global_handles->Create(*callback)); |
| 3267 if (data.is_null()) { | 3264 if (data.is_null()) { |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3854 { | 3851 { |
| 3855 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); | 3852 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); |
| 3856 isolate_->debugger()->CallMessageDispatchHandler(); | 3853 isolate_->debugger()->CallMessageDispatchHandler(); |
| 3857 } | 3854 } |
| 3858 } | 3855 } |
| 3859 } | 3856 } |
| 3860 | 3857 |
| 3861 #endif // ENABLE_DEBUGGER_SUPPORT | 3858 #endif // ENABLE_DEBUGGER_SUPPORT |
| 3862 | 3859 |
| 3863 } } // namespace v8::internal | 3860 } } // namespace v8::internal |
| OLD | NEW |