| 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; |
| 777 } | 775 } |
| 778 | 776 |
| 779 // Find source and name for the requested script. | 777 // Find source and name for the requested script. |
| 780 Handle<String> source_code = | 778 Handle<String> source_code = |
| 781 isolate->bootstrapper()->NativesSourceLookup(index); | 779 isolate->bootstrapper()->NativesSourceLookup(index); |
| 782 Vector<const char> name = Natives::GetScriptName(index); | 780 Vector<const char> name = Natives::GetScriptName(index); |
| 783 Handle<String> script_name = factory->NewStringFromAscii(name); | 781 Handle<String> script_name = factory->NewStringFromAscii(name); |
| 784 Handle<Context> context = isolate->native_context(); | 782 Handle<Context> context = isolate->native_context(); |
| 785 | 783 |
| 786 // Compile the script. | 784 // Compile the script. |
| 787 Handle<SharedFunctionInfo> function_info; | 785 Handle<SharedFunctionInfo> function_info; |
| 788 function_info = Compiler::Compile(source_code, | 786 function_info = Compiler::CompileScript(source_code, |
| 789 script_name, | 787 script_name, 0, 0, |
| 790 0, 0, | 788 false, |
| 791 false, | 789 context, |
| 792 context, | 790 NULL, NULL, |
| 793 NULL, NULL, | 791 Handle<String>::null(), |
| 794 Handle<String>::null(), | 792 NATIVES_CODE); |
| 795 NATIVES_CODE); | |
| 796 | 793 |
| 797 // Silently ignore stack overflows during compilation. | 794 // Silently ignore stack overflows during compilation. |
| 798 if (function_info.is_null()) { | 795 if (function_info.is_null()) { |
| 799 ASSERT(isolate->has_pending_exception()); | 796 ASSERT(isolate->has_pending_exception()); |
| 800 isolate->clear_pending_exception(); | 797 isolate->clear_pending_exception(); |
| 801 return false; | 798 return false; |
| 802 } | 799 } |
| 803 | 800 |
| 804 // Execute the shared function in the debugger context. | 801 // Execute the shared function in the debugger context. |
| 805 bool caught_exception; | 802 bool caught_exception; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 void Debug::Unload() { | 911 void Debug::Unload() { |
| 915 // Return debugger is not loaded. | 912 // Return debugger is not loaded. |
| 916 if (!IsLoaded()) { | 913 if (!IsLoaded()) { |
| 917 return; | 914 return; |
| 918 } | 915 } |
| 919 | 916 |
| 920 // Clear the script cache. | 917 // Clear the script cache. |
| 921 DestroyScriptCache(); | 918 DestroyScriptCache(); |
| 922 | 919 |
| 923 // Clear debugger context global handle. | 920 // Clear debugger context global handle. |
| 924 isolate_->global_handles()->Destroy( | 921 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location())); |
| 925 reinterpret_cast<Object**>(debug_context_.location())); | |
| 926 debug_context_ = Handle<Context>(); | 922 debug_context_ = Handle<Context>(); |
| 927 } | 923 } |
| 928 | 924 |
| 929 | 925 |
| 930 // Set the flag indicating that preemption happened during debugging. | 926 // Set the flag indicating that preemption happened during debugging. |
| 931 void Debug::PreemptionWhileInDebugger() { | 927 void Debug::PreemptionWhileInDebugger() { |
| 932 ASSERT(InDebugger()); | 928 ASSERT(InDebugger()); |
| 933 Debug::set_interrupts_pending(PREEMPT); | 929 Debug::set_interrupts_pending(PREEMPT); |
| 934 } | 930 } |
| 935 | 931 |
| (...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1864 } | 1860 } |
| 1865 | 1861 |
| 1866 | 1862 |
| 1867 void Debug::ClearStepNext() { | 1863 void Debug::ClearStepNext() { |
| 1868 thread_local_.last_step_action_ = StepNone; | 1864 thread_local_.last_step_action_ = StepNone; |
| 1869 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; | 1865 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; |
| 1870 thread_local_.last_fp_ = 0; | 1866 thread_local_.last_fp_ = 0; |
| 1871 } | 1867 } |
| 1872 | 1868 |
| 1873 | 1869 |
| 1874 // Helper function to compile full code for debugging. This code will | |
| 1875 // have debug break slots and deoptimization information. Deoptimization | |
| 1876 // information is required in case that an optimized version of this | |
| 1877 // function is still activated on the stack. It will also make sure that | |
| 1878 // the full code is compiled with the same flags as the previous version, | |
| 1879 // that is flags which can change the code generated. The current method | |
| 1880 // of mapping from already compiled full code without debug break slots | |
| 1881 // to full code with debug break slots depends on the generated code is | |
| 1882 // otherwise exactly the same. | |
| 1883 static bool CompileFullCodeForDebugging(Handle<JSFunction> function, | |
| 1884 Handle<Code> current_code) { | |
| 1885 ASSERT(!current_code->has_debug_break_slots()); | |
| 1886 | |
| 1887 CompilationInfoWithZone info(function); | |
| 1888 info.MarkCompilingForDebugging(current_code); | |
| 1889 ASSERT(!info.shared_info()->is_compiled()); | |
| 1890 ASSERT(!info.isolate()->has_pending_exception()); | |
| 1891 | |
| 1892 // Use compile lazy which will end up compiling the full code in the | |
| 1893 // configuration configured above. | |
| 1894 bool result = Compiler::CompileLazy(&info); | |
| 1895 ASSERT(result != info.isolate()->has_pending_exception()); | |
| 1896 info.isolate()->clear_pending_exception(); | |
| 1897 #if DEBUG | |
| 1898 if (result) { | |
| 1899 Handle<Code> new_code(function->shared()->code()); | |
| 1900 ASSERT(new_code->has_debug_break_slots()); | |
| 1901 ASSERT(current_code->is_compiled_optimizable() == | |
| 1902 new_code->is_compiled_optimizable()); | |
| 1903 } | |
| 1904 #endif | |
| 1905 return result; | |
| 1906 } | |
| 1907 | |
| 1908 | |
| 1909 static void CollectActiveFunctionsFromThread( | 1870 static void CollectActiveFunctionsFromThread( |
| 1910 Isolate* isolate, | 1871 Isolate* isolate, |
| 1911 ThreadLocalTop* top, | 1872 ThreadLocalTop* top, |
| 1912 List<Handle<JSFunction> >* active_functions, | 1873 List<Handle<JSFunction> >* active_functions, |
| 1913 Object* active_code_marker) { | 1874 Object* active_code_marker) { |
| 1914 // Find all non-optimized code functions with activation frames | 1875 // Find all non-optimized code functions with activation frames |
| 1915 // on the stack. This includes functions which have optimized | 1876 // on the stack. This includes functions which have optimized |
| 1916 // activations (including inlined functions) on the stack as the | 1877 // activations (including inlined functions) on the stack as the |
| 1917 // non-optimized code is needed for the lazy deoptimization. | 1878 // non-optimized code is needed for the lazy deoptimization. |
| 1918 for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) { | 1879 for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2055 void Debug::PrepareForBreakPoints() { | 2016 void Debug::PrepareForBreakPoints() { |
| 2056 // If preparing for the first break point make sure to deoptimize all | 2017 // If preparing for the first break point make sure to deoptimize all |
| 2057 // functions as debugging does not work with optimized code. | 2018 // functions as debugging does not work with optimized code. |
| 2058 if (!has_break_points_) { | 2019 if (!has_break_points_) { |
| 2059 if (isolate_->concurrent_recompilation_enabled()) { | 2020 if (isolate_->concurrent_recompilation_enabled()) { |
| 2060 isolate_->optimizing_compiler_thread()->Flush(); | 2021 isolate_->optimizing_compiler_thread()->Flush(); |
| 2061 } | 2022 } |
| 2062 | 2023 |
| 2063 Deoptimizer::DeoptimizeAll(isolate_); | 2024 Deoptimizer::DeoptimizeAll(isolate_); |
| 2064 | 2025 |
| 2065 Handle<Code> lazy_compile = | 2026 Handle<Code> lazy_compile = isolate_->builtins()->CompileUnoptimized(); |
| 2066 Handle<Code>(isolate_->builtins()->builtin(Builtins::kLazyCompile)); | |
| 2067 | 2027 |
| 2068 // There will be at least one break point when we are done. | 2028 // There will be at least one break point when we are done. |
| 2069 has_break_points_ = true; | 2029 has_break_points_ = true; |
| 2070 | 2030 |
| 2071 // Keep the list of activated functions in a handlified list as it | 2031 // Keep the list of activated functions in a handlified list as it |
| 2072 // is used both in GC and non-GC code. | 2032 // is used both in GC and non-GC code. |
| 2073 List<Handle<JSFunction> > active_functions(100); | 2033 List<Handle<JSFunction> > active_functions(100); |
| 2074 | 2034 |
| 2075 { | 2035 { |
| 2076 // We are going to iterate heap to find all functions without | 2036 // We are going to iterate heap to find all functions without |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2108 if (!shared->script()->IsScript()) continue; | 2068 if (!shared->script()->IsScript()) continue; |
| 2109 if (function->IsBuiltin()) continue; | 2069 if (function->IsBuiltin()) continue; |
| 2110 if (shared->code()->gc_metadata() == active_code_marker) continue; | 2070 if (shared->code()->gc_metadata() == active_code_marker) continue; |
| 2111 | 2071 |
| 2112 Code::Kind kind = function->code()->kind(); | 2072 Code::Kind kind = function->code()->kind(); |
| 2113 if (kind == Code::FUNCTION && | 2073 if (kind == Code::FUNCTION && |
| 2114 !function->code()->has_debug_break_slots()) { | 2074 !function->code()->has_debug_break_slots()) { |
| 2115 function->set_code(*lazy_compile); | 2075 function->set_code(*lazy_compile); |
| 2116 function->shared()->set_code(*lazy_compile); | 2076 function->shared()->set_code(*lazy_compile); |
| 2117 } else if (kind == Code::BUILTIN && | 2077 } else if (kind == Code::BUILTIN && |
| 2118 (function->IsInRecompileQueue() || | 2078 (function->IsInOptimizationQueue() || |
| 2119 function->IsMarkedForLazyRecompilation() || | 2079 function->IsMarkedForOptimization() || |
| 2120 function->IsMarkedForConcurrentRecompilation())) { | 2080 function->IsMarkedForConcurrentOptimization())) { |
| 2121 // Abort in-flight compilation. | 2081 // Abort in-flight compilation. |
| 2122 Code* shared_code = function->shared()->code(); | 2082 Code* shared_code = function->shared()->code(); |
| 2123 if (shared_code->kind() == Code::FUNCTION && | 2083 if (shared_code->kind() == Code::FUNCTION && |
| 2124 shared_code->has_debug_break_slots()) { | 2084 shared_code->has_debug_break_slots()) { |
| 2125 function->set_code(shared_code); | 2085 function->set_code(shared_code); |
| 2126 } else { | 2086 } else { |
| 2127 function->set_code(*lazy_compile); | 2087 function->set_code(*lazy_compile); |
| 2128 function->shared()->set_code(*lazy_compile); | 2088 function->shared()->set_code(*lazy_compile); |
| 2129 } | 2089 } |
| 2130 } | 2090 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2155 !shared->allows_lazy_compilation() || | 2115 !shared->allows_lazy_compilation() || |
| 2156 shared->code()->kind() == Code::BUILTIN) { | 2116 shared->code()->kind() == Code::BUILTIN) { |
| 2157 continue; | 2117 continue; |
| 2158 } | 2118 } |
| 2159 | 2119 |
| 2160 // Make sure that the shared full code is compiled with debug | 2120 // Make sure that the shared full code is compiled with debug |
| 2161 // break slots. | 2121 // break slots. |
| 2162 if (!shared->code()->has_debug_break_slots()) { | 2122 if (!shared->code()->has_debug_break_slots()) { |
| 2163 // Try to compile the full code with debug break slots. If it | 2123 // Try to compile the full code with debug break slots. If it |
| 2164 // fails just keep the current code. | 2124 // fails just keep the current code. |
| 2165 Handle<Code> current_code(function->shared()->code()); | |
| 2166 shared->set_code(*lazy_compile); | |
| 2167 bool prev_force_debugger_active = | 2125 bool prev_force_debugger_active = |
| 2168 isolate_->debugger()->force_debugger_active(); | 2126 isolate_->debugger()->force_debugger_active(); |
| 2169 isolate_->debugger()->set_force_debugger_active(true); | 2127 isolate_->debugger()->set_force_debugger_active(true); |
| 2170 ASSERT(current_code->kind() == Code::FUNCTION); | 2128 Handle<Code> code = Compiler::GetCodeForDebugging(function); |
| 2171 CompileFullCodeForDebugging(function, current_code); | 2129 function->ReplaceCode(*code); |
| 2172 isolate_->debugger()->set_force_debugger_active( | 2130 isolate_->debugger()->set_force_debugger_active( |
| 2173 prev_force_debugger_active); | 2131 prev_force_debugger_active); |
| 2174 if (!shared->is_compiled()) { | |
| 2175 shared->set_code(*current_code); | |
| 2176 continue; | |
| 2177 } | |
| 2178 } | 2132 } |
| 2179 | 2133 |
| 2180 // Keep function code in sync with shared function info. | 2134 // Keep function code in sync with shared function info. |
| 2181 function->set_code(shared->code()); | 2135 function->set_code(shared->code()); |
| 2182 } | 2136 } |
| 2183 | 2137 |
| 2184 RedirectActivationsToRecompiledCodeOnThread(isolate_, | 2138 RedirectActivationsToRecompiledCodeOnThread(isolate_, |
| 2185 isolate_->thread_local_top()); | 2139 isolate_->thread_local_top()); |
| 2186 | 2140 |
| 2187 ActiveFunctionsRedirector active_functions_redirector; | 2141 ActiveFunctionsRedirector active_functions_redirector; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2280 has_break_points_ = true; | 2234 has_break_points_ = true; |
| 2281 | 2235 |
| 2282 // If the candidate found is compiled we are done. | 2236 // If the candidate found is compiled we are done. |
| 2283 done = target->is_compiled(); | 2237 done = target->is_compiled(); |
| 2284 if (!done) { | 2238 if (!done) { |
| 2285 // If the candidate is not compiled, compile it to reveal any inner | 2239 // If the candidate is not compiled, compile it to reveal any inner |
| 2286 // functions which might contain the requested source position. This | 2240 // functions which might contain the requested source position. This |
| 2287 // will compile all inner functions that cannot be compiled without a | 2241 // will compile all inner functions that cannot be compiled without a |
| 2288 // context, because Compiler::BuildFunctionInfo checks whether the | 2242 // context, because Compiler::BuildFunctionInfo checks whether the |
| 2289 // debugger is active. | 2243 // debugger is active. |
| 2290 if (target_function.is_null()) { | 2244 Handle<Code> result = target_function.is_null() |
| 2291 SharedFunctionInfo::CompileLazy(target, KEEP_EXCEPTION); | 2245 ? Compiler::GetUnoptimizedCode(target) |
| 2292 } else { | 2246 : Compiler::GetUnoptimizedCode(target_function); |
| 2293 JSFunction::CompileLazy(target_function, KEEP_EXCEPTION); | 2247 if (result.is_null()) return isolate_->heap()->undefined_value(); |
| 2294 } | |
| 2295 } | 2248 } |
| 2296 } // End while loop. | 2249 } // End while loop. |
| 2297 | 2250 |
| 2298 return *target; | 2251 return *target; |
| 2299 } | 2252 } |
| 2300 | 2253 |
| 2301 | 2254 |
| 2302 // Ensures the debug information is present for shared. | 2255 // Ensures the debug information is present for shared. |
| 2303 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared, | 2256 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared, |
| 2304 Handle<JSFunction> function) { | 2257 Handle<JSFunction> function) { |
| 2305 Isolate* isolate = shared->GetIsolate(); | 2258 Isolate* isolate = shared->GetIsolate(); |
| 2306 | 2259 |
| 2307 // Return if we already have the debug info for shared. | 2260 // Return if we already have the debug info for shared. |
| 2308 if (HasDebugInfo(shared)) { | 2261 if (HasDebugInfo(shared)) { |
| 2309 ASSERT(shared->is_compiled()); | 2262 ASSERT(shared->is_compiled()); |
| 2310 return true; | 2263 return true; |
| 2311 } | 2264 } |
| 2312 | 2265 |
| 2313 // There will be at least one break point when we are done. | 2266 // There will be at least one break point when we are done. |
| 2314 has_break_points_ = true; | 2267 has_break_points_ = true; |
| 2315 | 2268 |
| 2316 // Ensure function is compiled. Return false if this failed. | 2269 // Ensure function is compiled. Return false if this failed. |
| 2317 if (!function.is_null() && | 2270 if (!function.is_null() && |
| 2318 !JSFunction::EnsureCompiled(function, CLEAR_EXCEPTION)) { | 2271 !Compiler::EnsureCompiled(function, CLEAR_EXCEPTION)) { |
| 2319 return false; | 2272 return false; |
| 2320 } | 2273 } |
| 2321 | 2274 |
| 2322 // Create the debug info object. | 2275 // Create the debug info object. |
| 2323 Handle<DebugInfo> debug_info = isolate->factory()->NewDebugInfo(shared); | 2276 Handle<DebugInfo> debug_info = isolate->factory()->NewDebugInfo(shared); |
| 2324 | 2277 |
| 2325 // Add debug info to the list. | 2278 // Add debug info to the list. |
| 2326 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); | 2279 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); |
| 2327 node->set_next(debug_info_list_); | 2280 node->set_next(debug_info_list_); |
| 2328 debug_info_list_ = node; | 2281 debug_info_list_ = node; |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2594 // Perform GC to get unreferenced scripts evicted from the cache before | 2547 // Perform GC to get unreferenced scripts evicted from the cache before |
| 2595 // returning the content. | 2548 // returning the content. |
| 2596 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 2549 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 2597 "Debug::GetLoadedScripts"); | 2550 "Debug::GetLoadedScripts"); |
| 2598 | 2551 |
| 2599 // Get the scripts from the cache. | 2552 // Get the scripts from the cache. |
| 2600 return script_cache_->GetScripts(); | 2553 return script_cache_->GetScripts(); |
| 2601 } | 2554 } |
| 2602 | 2555 |
| 2603 | 2556 |
| 2557 void Debug::RecordEvalCaller(Handle<Script> script) { |
| 2558 script->set_compilation_type(Script::COMPILATION_TYPE_EVAL); |
| 2559 // For eval scripts add information on the function from which eval was |
| 2560 // called. |
| 2561 StackTraceFrameIterator it(script->GetIsolate()); |
| 2562 if (!it.done()) { |
| 2563 script->set_eval_from_shared(it.frame()->function()->shared()); |
| 2564 Code* code = it.frame()->LookupCode(); |
| 2565 int offset = static_cast<int>( |
| 2566 it.frame()->pc() - code->instruction_start()); |
| 2567 script->set_eval_from_instructions_offset(Smi::FromInt(offset)); |
| 2568 } |
| 2569 } |
| 2570 |
| 2571 |
| 2604 void Debug::AfterGarbageCollection() { | 2572 void Debug::AfterGarbageCollection() { |
| 2605 // Generate events for collected scripts. | 2573 // Generate events for collected scripts. |
| 2606 if (script_cache_ != NULL) { | 2574 if (script_cache_ != NULL) { |
| 2607 script_cache_->ProcessCollectedScripts(); | 2575 script_cache_->ProcessCollectedScripts(); |
| 2608 } | 2576 } |
| 2609 } | 2577 } |
| 2610 | 2578 |
| 2611 | 2579 |
| 2612 Debugger::Debugger(Isolate* isolate) | 2580 Debugger::Debugger(Isolate* isolate) |
| 2613 : debugger_access_(isolate->debugger_access()), | 2581 : debugger_access_(isolate->debugger_access()), |
| (...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3242 | 3210 |
| 3243 | 3211 |
| 3244 void Debugger::SetEventListener(Handle<Object> callback, | 3212 void Debugger::SetEventListener(Handle<Object> callback, |
| 3245 Handle<Object> data) { | 3213 Handle<Object> data) { |
| 3246 HandleScope scope(isolate_); | 3214 HandleScope scope(isolate_); |
| 3247 GlobalHandles* global_handles = isolate_->global_handles(); | 3215 GlobalHandles* global_handles = isolate_->global_handles(); |
| 3248 | 3216 |
| 3249 // Clear the global handles for the event listener and the event listener data | 3217 // Clear the global handles for the event listener and the event listener data |
| 3250 // object. | 3218 // object. |
| 3251 if (!event_listener_.is_null()) { | 3219 if (!event_listener_.is_null()) { |
| 3252 global_handles->Destroy( | 3220 GlobalHandles::Destroy( |
| 3253 reinterpret_cast<Object**>(event_listener_.location())); | 3221 reinterpret_cast<Object**>(event_listener_.location())); |
| 3254 event_listener_ = Handle<Object>(); | 3222 event_listener_ = Handle<Object>(); |
| 3255 } | 3223 } |
| 3256 if (!event_listener_data_.is_null()) { | 3224 if (!event_listener_data_.is_null()) { |
| 3257 global_handles->Destroy( | 3225 GlobalHandles::Destroy( |
| 3258 reinterpret_cast<Object**>(event_listener_data_.location())); | 3226 reinterpret_cast<Object**>(event_listener_data_.location())); |
| 3259 event_listener_data_ = Handle<Object>(); | 3227 event_listener_data_ = Handle<Object>(); |
| 3260 } | 3228 } |
| 3261 | 3229 |
| 3262 // If there is a new debug event listener register it together with its data | 3230 // If there is a new debug event listener register it together with its data |
| 3263 // object. | 3231 // object. |
| 3264 if (!callback->IsUndefined() && !callback->IsNull()) { | 3232 if (!callback->IsUndefined() && !callback->IsNull()) { |
| 3265 event_listener_ = Handle<Object>::cast( | 3233 event_listener_ = Handle<Object>::cast( |
| 3266 global_handles->Create(*callback)); | 3234 global_handles->Create(*callback)); |
| 3267 if (data.is_null()) { | 3235 if (data.is_null()) { |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3854 { | 3822 { |
| 3855 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); | 3823 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); |
| 3856 isolate_->debugger()->CallMessageDispatchHandler(); | 3824 isolate_->debugger()->CallMessageDispatchHandler(); |
| 3857 } | 3825 } |
| 3858 } | 3826 } |
| 3859 } | 3827 } |
| 3860 | 3828 |
| 3861 #endif // ENABLE_DEBUGGER_SUPPORT | 3829 #endif // ENABLE_DEBUGGER_SUPPORT |
| 3862 | 3830 |
| 3863 } } // namespace v8::internal | 3831 } } // namespace v8::internal |
| OLD | NEW |