| 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 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 | 778 |
| 779 // Find source and name for the requested script. | 779 // Find source and name for the requested script. |
| 780 Handle<String> source_code = | 780 Handle<String> source_code = |
| 781 isolate->bootstrapper()->NativesSourceLookup(index); | 781 isolate->bootstrapper()->NativesSourceLookup(index); |
| 782 Vector<const char> name = Natives::GetScriptName(index); | 782 Vector<const char> name = Natives::GetScriptName(index); |
| 783 Handle<String> script_name = factory->NewStringFromAscii(name); | 783 Handle<String> script_name = factory->NewStringFromAscii(name); |
| 784 Handle<Context> context = isolate->native_context(); | 784 Handle<Context> context = isolate->native_context(); |
| 785 | 785 |
| 786 // Compile the script. | 786 // Compile the script. |
| 787 Handle<SharedFunctionInfo> function_info; | 787 Handle<SharedFunctionInfo> function_info; |
| 788 function_info = Compiler::Compile(source_code, | 788 function_info = Compiler::CompileScript(source_code, |
| 789 script_name, | 789 script_name, 0, 0, |
| 790 0, 0, | 790 false, |
| 791 false, | 791 context, |
| 792 context, | 792 NULL, NULL, |
| 793 NULL, NULL, | 793 Handle<String>::null(), |
| 794 Handle<String>::null(), | 794 NATIVES_CODE); |
| 795 NATIVES_CODE); | |
| 796 | 795 |
| 797 // Silently ignore stack overflows during compilation. | 796 // Silently ignore stack overflows during compilation. |
| 798 if (function_info.is_null()) { | 797 if (function_info.is_null()) { |
| 799 ASSERT(isolate->has_pending_exception()); | 798 ASSERT(isolate->has_pending_exception()); |
| 800 isolate->clear_pending_exception(); | 799 isolate->clear_pending_exception(); |
| 801 return false; | 800 return false; |
| 802 } | 801 } |
| 803 | 802 |
| 804 // Execute the shared function in the debugger context. | 803 // Execute the shared function in the debugger context. |
| 805 bool caught_exception; | 804 bool caught_exception; |
| (...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1864 } | 1863 } |
| 1865 | 1864 |
| 1866 | 1865 |
| 1867 void Debug::ClearStepNext() { | 1866 void Debug::ClearStepNext() { |
| 1868 thread_local_.last_step_action_ = StepNone; | 1867 thread_local_.last_step_action_ = StepNone; |
| 1869 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; | 1868 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; |
| 1870 thread_local_.last_fp_ = 0; | 1869 thread_local_.last_fp_ = 0; |
| 1871 } | 1870 } |
| 1872 | 1871 |
| 1873 | 1872 |
| 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( | 1873 static void CollectActiveFunctionsFromThread( |
| 1910 Isolate* isolate, | 1874 Isolate* isolate, |
| 1911 ThreadLocalTop* top, | 1875 ThreadLocalTop* top, |
| 1912 List<Handle<JSFunction> >* active_functions, | 1876 List<Handle<JSFunction> >* active_functions, |
| 1913 Object* active_code_marker) { | 1877 Object* active_code_marker) { |
| 1914 // Find all non-optimized code functions with activation frames | 1878 // Find all non-optimized code functions with activation frames |
| 1915 // on the stack. This includes functions which have optimized | 1879 // on the stack. This includes functions which have optimized |
| 1916 // activations (including inlined functions) on the stack as the | 1880 // activations (including inlined functions) on the stack as the |
| 1917 // non-optimized code is needed for the lazy deoptimization. | 1881 // non-optimized code is needed for the lazy deoptimization. |
| 1918 for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) { | 1882 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() { | 2019 void Debug::PrepareForBreakPoints() { |
| 2056 // If preparing for the first break point make sure to deoptimize all | 2020 // If preparing for the first break point make sure to deoptimize all |
| 2057 // functions as debugging does not work with optimized code. | 2021 // functions as debugging does not work with optimized code. |
| 2058 if (!has_break_points_) { | 2022 if (!has_break_points_) { |
| 2059 if (isolate_->concurrent_recompilation_enabled()) { | 2023 if (isolate_->concurrent_recompilation_enabled()) { |
| 2060 isolate_->optimizing_compiler_thread()->Flush(); | 2024 isolate_->optimizing_compiler_thread()->Flush(); |
| 2061 } | 2025 } |
| 2062 | 2026 |
| 2063 Deoptimizer::DeoptimizeAll(isolate_); | 2027 Deoptimizer::DeoptimizeAll(isolate_); |
| 2064 | 2028 |
| 2065 Handle<Code> lazy_compile = | 2029 Handle<Code> lazy_compile = isolate_->builtins()->CompileUnoptimized(); |
| 2066 Handle<Code>(isolate_->builtins()->builtin(Builtins::kLazyCompile)); | |
| 2067 | 2030 |
| 2068 // There will be at least one break point when we are done. | 2031 // There will be at least one break point when we are done. |
| 2069 has_break_points_ = true; | 2032 has_break_points_ = true; |
| 2070 | 2033 |
| 2071 // Keep the list of activated functions in a handlified list as it | 2034 // Keep the list of activated functions in a handlified list as it |
| 2072 // is used both in GC and non-GC code. | 2035 // is used both in GC and non-GC code. |
| 2073 List<Handle<JSFunction> > active_functions(100); | 2036 List<Handle<JSFunction> > active_functions(100); |
| 2074 | 2037 |
| 2075 { | 2038 { |
| 2076 // We are going to iterate heap to find all functions without | 2039 // 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; | 2071 if (!shared->script()->IsScript()) continue; |
| 2109 if (function->IsBuiltin()) continue; | 2072 if (function->IsBuiltin()) continue; |
| 2110 if (shared->code()->gc_metadata() == active_code_marker) continue; | 2073 if (shared->code()->gc_metadata() == active_code_marker) continue; |
| 2111 | 2074 |
| 2112 Code::Kind kind = function->code()->kind(); | 2075 Code::Kind kind = function->code()->kind(); |
| 2113 if (kind == Code::FUNCTION && | 2076 if (kind == Code::FUNCTION && |
| 2114 !function->code()->has_debug_break_slots()) { | 2077 !function->code()->has_debug_break_slots()) { |
| 2115 function->set_code(*lazy_compile); | 2078 function->set_code(*lazy_compile); |
| 2116 function->shared()->set_code(*lazy_compile); | 2079 function->shared()->set_code(*lazy_compile); |
| 2117 } else if (kind == Code::BUILTIN && | 2080 } else if (kind == Code::BUILTIN && |
| 2118 (function->IsInRecompileQueue() || | 2081 (function->IsInOptimizationQueue() || |
| 2119 function->IsMarkedForLazyRecompilation() || | 2082 function->IsMarkedForOptimization() || |
| 2120 function->IsMarkedForConcurrentRecompilation())) { | 2083 function->IsMarkedForConcurrentOptimization())) { |
| 2121 // Abort in-flight compilation. | 2084 // Abort in-flight compilation. |
| 2122 Code* shared_code = function->shared()->code(); | 2085 Code* shared_code = function->shared()->code(); |
| 2123 if (shared_code->kind() == Code::FUNCTION && | 2086 if (shared_code->kind() == Code::FUNCTION && |
| 2124 shared_code->has_debug_break_slots()) { | 2087 shared_code->has_debug_break_slots()) { |
| 2125 function->set_code(shared_code); | 2088 function->set_code(shared_code); |
| 2126 } else { | 2089 } else { |
| 2127 function->set_code(*lazy_compile); | 2090 function->set_code(*lazy_compile); |
| 2128 function->shared()->set_code(*lazy_compile); | 2091 function->shared()->set_code(*lazy_compile); |
| 2129 } | 2092 } |
| 2130 } | 2093 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2155 !shared->allows_lazy_compilation() || | 2118 !shared->allows_lazy_compilation() || |
| 2156 shared->code()->kind() == Code::BUILTIN) { | 2119 shared->code()->kind() == Code::BUILTIN) { |
| 2157 continue; | 2120 continue; |
| 2158 } | 2121 } |
| 2159 | 2122 |
| 2160 // Make sure that the shared full code is compiled with debug | 2123 // Make sure that the shared full code is compiled with debug |
| 2161 // break slots. | 2124 // break slots. |
| 2162 if (!shared->code()->has_debug_break_slots()) { | 2125 if (!shared->code()->has_debug_break_slots()) { |
| 2163 // Try to compile the full code with debug break slots. If it | 2126 // Try to compile the full code with debug break slots. If it |
| 2164 // fails just keep the current code. | 2127 // 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 = | 2128 bool prev_force_debugger_active = |
| 2168 isolate_->debugger()->force_debugger_active(); | 2129 isolate_->debugger()->force_debugger_active(); |
| 2169 isolate_->debugger()->set_force_debugger_active(true); | 2130 isolate_->debugger()->set_force_debugger_active(true); |
| 2170 ASSERT(current_code->kind() == Code::FUNCTION); | 2131 function->ReplaceCode(*Compiler::GetCodeForDebugging(function)); |
| 2171 CompileFullCodeForDebugging(function, current_code); | |
| 2172 isolate_->debugger()->set_force_debugger_active( | 2132 isolate_->debugger()->set_force_debugger_active( |
| 2173 prev_force_debugger_active); | 2133 prev_force_debugger_active); |
| 2174 if (!shared->is_compiled()) { | |
| 2175 shared->set_code(*current_code); | |
| 2176 continue; | |
| 2177 } | |
| 2178 } | 2134 } |
| 2179 | 2135 |
| 2180 // Keep function code in sync with shared function info. | 2136 // Keep function code in sync with shared function info. |
| 2181 function->set_code(shared->code()); | 2137 function->set_code(shared->code()); |
| 2182 } | 2138 } |
| 2183 | 2139 |
| 2184 RedirectActivationsToRecompiledCodeOnThread(isolate_, | 2140 RedirectActivationsToRecompiledCodeOnThread(isolate_, |
| 2185 isolate_->thread_local_top()); | 2141 isolate_->thread_local_top()); |
| 2186 | 2142 |
| 2187 ActiveFunctionsRedirector active_functions_redirector; | 2143 ActiveFunctionsRedirector active_functions_redirector; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2280 has_break_points_ = true; | 2236 has_break_points_ = true; |
| 2281 | 2237 |
| 2282 // If the candidate found is compiled we are done. | 2238 // If the candidate found is compiled we are done. |
| 2283 done = target->is_compiled(); | 2239 done = target->is_compiled(); |
| 2284 if (!done) { | 2240 if (!done) { |
| 2285 // If the candidate is not compiled, compile it to reveal any inner | 2241 // If the candidate is not compiled, compile it to reveal any inner |
| 2286 // functions which might contain the requested source position. This | 2242 // functions which might contain the requested source position. This |
| 2287 // will compile all inner functions that cannot be compiled without a | 2243 // will compile all inner functions that cannot be compiled without a |
| 2288 // context, because Compiler::BuildFunctionInfo checks whether the | 2244 // context, because Compiler::BuildFunctionInfo checks whether the |
| 2289 // debugger is active. | 2245 // debugger is active. |
| 2290 if (target_function.is_null()) { | 2246 Handle<Code> result = target_function.is_null() |
| 2291 SharedFunctionInfo::CompileLazy(target, KEEP_EXCEPTION); | 2247 ? Compiler::GetUnoptimizedCode(target) |
| 2292 } else { | 2248 : Compiler::GetUnoptimizedCode(target_function); |
| 2293 JSFunction::CompileLazy(target_function, KEEP_EXCEPTION); | 2249 if (result.is_null()) return isolate_->heap()->undefined_value(); |
| 2294 } | |
| 2295 } | 2250 } |
| 2296 } // End while loop. | 2251 } // End while loop. |
| 2297 | 2252 |
| 2298 return *target; | 2253 return *target; |
| 2299 } | 2254 } |
| 2300 | 2255 |
| 2301 | 2256 |
| 2302 // Ensures the debug information is present for shared. | 2257 // Ensures the debug information is present for shared. |
| 2303 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared, | 2258 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared, |
| 2304 Handle<JSFunction> function) { | 2259 Handle<JSFunction> function) { |
| 2305 Isolate* isolate = shared->GetIsolate(); | 2260 Isolate* isolate = shared->GetIsolate(); |
| 2306 | 2261 |
| 2307 // Return if we already have the debug info for shared. | 2262 // Return if we already have the debug info for shared. |
| 2308 if (HasDebugInfo(shared)) { | 2263 if (HasDebugInfo(shared)) { |
| 2309 ASSERT(shared->is_compiled()); | 2264 ASSERT(shared->is_compiled()); |
| 2310 return true; | 2265 return true; |
| 2311 } | 2266 } |
| 2312 | 2267 |
| 2313 // There will be at least one break point when we are done. | 2268 // There will be at least one break point when we are done. |
| 2314 has_break_points_ = true; | 2269 has_break_points_ = true; |
| 2315 | 2270 |
| 2316 // Ensure function is compiled. Return false if this failed. | 2271 // Ensure function is compiled. Return false if this failed. |
| 2317 if (!function.is_null() && | 2272 if (!function.is_null() && |
| 2318 !JSFunction::EnsureCompiled(function, CLEAR_EXCEPTION)) { | 2273 !Compiler::EnsureCompiled(function, CLEAR_EXCEPTION)) { |
| 2319 return false; | 2274 return false; |
| 2320 } | 2275 } |
| 2321 | 2276 |
| 2322 // Create the debug info object. | 2277 // Create the debug info object. |
| 2323 Handle<DebugInfo> debug_info = isolate->factory()->NewDebugInfo(shared); | 2278 Handle<DebugInfo> debug_info = isolate->factory()->NewDebugInfo(shared); |
| 2324 | 2279 |
| 2325 // Add debug info to the list. | 2280 // Add debug info to the list. |
| 2326 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); | 2281 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); |
| 2327 node->set_next(debug_info_list_); | 2282 node->set_next(debug_info_list_); |
| 2328 debug_info_list_ = node; | 2283 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 | 2549 // Perform GC to get unreferenced scripts evicted from the cache before |
| 2595 // returning the content. | 2550 // returning the content. |
| 2596 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 2551 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 2597 "Debug::GetLoadedScripts"); | 2552 "Debug::GetLoadedScripts"); |
| 2598 | 2553 |
| 2599 // Get the scripts from the cache. | 2554 // Get the scripts from the cache. |
| 2600 return script_cache_->GetScripts(); | 2555 return script_cache_->GetScripts(); |
| 2601 } | 2556 } |
| 2602 | 2557 |
| 2603 | 2558 |
| 2559 void Debug::RecordEvalCaller(Handle<Script> script) { |
| 2560 script->set_compilation_type(Script::COMPILATION_TYPE_EVAL); |
| 2561 // For eval scripts add information on the function from which eval was |
| 2562 // called. |
| 2563 StackTraceFrameIterator it(script->GetIsolate()); |
| 2564 if (!it.done()) { |
| 2565 script->set_eval_from_shared(it.frame()->function()->shared()); |
| 2566 Code* code = it.frame()->LookupCode(); |
| 2567 int offset = static_cast<int>( |
| 2568 it.frame()->pc() - code->instruction_start()); |
| 2569 script->set_eval_from_instructions_offset(Smi::FromInt(offset)); |
| 2570 } |
| 2571 } |
| 2572 |
| 2573 |
| 2604 void Debug::AfterGarbageCollection() { | 2574 void Debug::AfterGarbageCollection() { |
| 2605 // Generate events for collected scripts. | 2575 // Generate events for collected scripts. |
| 2606 if (script_cache_ != NULL) { | 2576 if (script_cache_ != NULL) { |
| 2607 script_cache_->ProcessCollectedScripts(); | 2577 script_cache_->ProcessCollectedScripts(); |
| 2608 } | 2578 } |
| 2609 } | 2579 } |
| 2610 | 2580 |
| 2611 | 2581 |
| 2612 Debugger::Debugger(Isolate* isolate) | 2582 Debugger::Debugger(Isolate* isolate) |
| 2613 : debugger_access_(isolate->debugger_access()), | 2583 : debugger_access_(isolate->debugger_access()), |
| (...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3854 { | 3824 { |
| 3855 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); | 3825 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); |
| 3856 isolate_->debugger()->CallMessageDispatchHandler(); | 3826 isolate_->debugger()->CallMessageDispatchHandler(); |
| 3857 } | 3827 } |
| 3858 } | 3828 } |
| 3859 } | 3829 } |
| 3860 | 3830 |
| 3861 #endif // ENABLE_DEBUGGER_SUPPORT | 3831 #endif // ENABLE_DEBUGGER_SUPPORT |
| 3862 | 3832 |
| 3863 } } // namespace v8::internal | 3833 } } // namespace v8::internal |
| OLD | NEW |