Chromium Code Reviews| 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 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 691 } | 691 } |
| 692 } | 692 } |
| 693 | 693 |
| 694 | 694 |
| 695 void Debug::HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data) { | 695 void Debug::HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data) { |
| 696 Debug* debug = Isolate::Current()->debug(); | 696 Debug* debug = Isolate::Current()->debug(); |
| 697 DebugInfoListNode* node = reinterpret_cast<DebugInfoListNode*>(data); | 697 DebugInfoListNode* node = reinterpret_cast<DebugInfoListNode*>(data); |
| 698 // We need to clear all breakpoints associated with the function to restore | 698 // We need to clear all breakpoints associated with the function to restore |
| 699 // original code and avoid patching the code twice later because | 699 // original code and avoid patching the code twice later because |
| 700 // the function will live in the heap until next gc, and can be found by | 700 // the function will live in the heap until next gc, and can be found by |
| 701 // Runtime::FindSharedFunctionInfoInScript. | 701 // Debug::FindSharedFunctionInfoInScript. |
| 702 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); | 702 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); |
| 703 it.ClearAllDebugBreak(); | 703 it.ClearAllDebugBreak(); |
| 704 debug->RemoveDebugInfo(node->debug_info()); | 704 debug->RemoveDebugInfo(node->debug_info()); |
| 705 #ifdef DEBUG | 705 #ifdef DEBUG |
| 706 node = debug->debug_info_list_; | 706 node = debug->debug_info_list_; |
| 707 while (node != NULL) { | 707 while (node != NULL) { |
| 708 ASSERT(node != reinterpret_cast<DebugInfoListNode*>(data)); | 708 ASSERT(node != reinterpret_cast<DebugInfoListNode*>(data)); |
| 709 node = node->next(); | 709 node = node->next(); |
| 710 } | 710 } |
| 711 #endif | 711 #endif |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1166 ASSERT(debug_info->GetBreakPointCount() > 0); | 1166 ASSERT(debug_info->GetBreakPointCount() > 0); |
| 1167 } | 1167 } |
| 1168 | 1168 |
| 1169 | 1169 |
| 1170 bool Debug::SetBreakPointForScript(Handle<Script> script, | 1170 bool Debug::SetBreakPointForScript(Handle<Script> script, |
| 1171 Handle<Object> break_point_object, | 1171 Handle<Object> break_point_object, |
| 1172 int* source_position) { | 1172 int* source_position) { |
| 1173 HandleScope scope(isolate_); | 1173 HandleScope scope(isolate_); |
| 1174 | 1174 |
| 1175 // No need to call PrepareForBreakPoints because it will be called | 1175 // No need to call PrepareForBreakPoints because it will be called |
| 1176 // implicitly by Runtime::FindSharedFunctionInfoInScript. | 1176 // implicitly by Debug::FindSharedFunctionInfoInScript. |
|
Toon Verwaest
2012/09/03 13:44:22
Just move PrepareForBreakPoints() here from FindSh
Michael Starzinger
2012/09/03 14:08:49
Done.
| |
| 1177 Object* result = Runtime::FindSharedFunctionInfoInScript(isolate_, | 1177 Object* result = FindSharedFunctionInfoInScript(script, *source_position); |
| 1178 script, | |
| 1179 *source_position); | |
| 1180 if (result->IsUndefined()) return false; | 1178 if (result->IsUndefined()) return false; |
| 1181 | 1179 |
| 1182 // Make sure the function has set up the debug info. | 1180 // Make sure the function has set up the debug info. |
| 1183 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result)); | 1181 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result)); |
| 1184 if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) { | 1182 if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) { |
| 1185 // Return if retrieving debug info failed. | 1183 // Return if retrieving debug info failed. |
| 1186 return false; | 1184 return false; |
| 1187 } | 1185 } |
| 1188 | 1186 |
| 1189 // Find position within function. The script position might be before the | 1187 // Find position within function. The script position might be before the |
| (...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2085 RedirectActivationsToRecompiledCodeOnThread(isolate_, | 2083 RedirectActivationsToRecompiledCodeOnThread(isolate_, |
| 2086 isolate_->thread_local_top()); | 2084 isolate_->thread_local_top()); |
| 2087 | 2085 |
| 2088 ActiveFunctionsRedirector active_functions_redirector; | 2086 ActiveFunctionsRedirector active_functions_redirector; |
| 2089 isolate_->thread_manager()->IterateArchivedThreads( | 2087 isolate_->thread_manager()->IterateArchivedThreads( |
| 2090 &active_functions_redirector); | 2088 &active_functions_redirector); |
| 2091 } | 2089 } |
| 2092 } | 2090 } |
| 2093 | 2091 |
| 2094 | 2092 |
| 2093 Object* Debug::FindSharedFunctionInfoInScript(Handle<Script> script, | |
| 2094 int position) { | |
| 2095 // The below fix-point iteration depends on all functions that cannot be | |
| 2096 // compiled lazily without a context to not be compiled at all. Compilation | |
| 2097 // will be triggered at points where we do not need a context. | |
| 2098 PrepareForBreakPoints(); | |
| 2099 | |
| 2100 // Iterate the heap looking for SharedFunctionInfo generated from the | |
| 2101 // script. The inner most SharedFunctionInfo containing the source position | |
| 2102 // for the requested break point is found. | |
| 2103 // NOTE: This might require several heap iterations. If the SharedFunctionInfo | |
| 2104 // which is found is not compiled it is compiled and the heap is iterated | |
| 2105 // again as the compilation might create inner functions from the newly | |
| 2106 // compiled function and the actual requested break point might be in one of | |
| 2107 // these functions. | |
| 2108 bool done = false; | |
| 2109 // The current candidate for the source position: | |
| 2110 int target_start_position = RelocInfo::kNoPosition; | |
| 2111 Handle<JSFunction> target_function; | |
| 2112 Handle<SharedFunctionInfo> target; | |
| 2113 while (!done) { | |
| 2114 { // Extra scope for iterator and no-allocation. | |
| 2115 isolate_->heap()->EnsureHeapIsIterable(); | |
| 2116 AssertNoAllocation no_alloc_during_heap_iteration; | |
| 2117 HeapIterator iterator; | |
| 2118 for (HeapObject* obj = iterator.next(); | |
| 2119 obj != NULL; obj = iterator.next()) { | |
| 2120 bool found_next_candidate = false; | |
| 2121 Handle<JSFunction> function; | |
| 2122 Handle<SharedFunctionInfo> shared; | |
| 2123 if (obj->IsJSFunction()) { | |
| 2124 function = Handle<JSFunction>(JSFunction::cast(obj)); | |
| 2125 shared = Handle<SharedFunctionInfo>(function->shared()); | |
| 2126 ASSERT(shared->allows_lazy_compilation() || shared->is_compiled()); | |
| 2127 found_next_candidate = true; | |
| 2128 } else if (obj->IsSharedFunctionInfo()) { | |
| 2129 shared = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(obj)); | |
| 2130 // Skip functions that we cannot compile lazily without a context, | |
| 2131 // which is not available here, because there is no closure. | |
| 2132 found_next_candidate = shared->is_compiled() || | |
| 2133 shared->allows_lazy_compilation_without_context(); | |
| 2134 } | |
| 2135 if (!found_next_candidate) continue; | |
| 2136 if (shared->script() == *script) { | |
| 2137 // If the SharedFunctionInfo found has the requested script data and | |
| 2138 // contains the source position it is a candidate. | |
| 2139 int start_position = shared->function_token_position(); | |
| 2140 if (start_position == RelocInfo::kNoPosition) { | |
| 2141 start_position = shared->start_position(); | |
| 2142 } | |
| 2143 if (start_position <= position && | |
| 2144 position <= shared->end_position()) { | |
| 2145 // If there is no candidate or this function is within the current | |
| 2146 // candidate this is the new candidate. | |
| 2147 if (target.is_null()) { | |
| 2148 target_start_position = start_position; | |
| 2149 target_function = function; | |
| 2150 target = shared; | |
| 2151 } else { | |
| 2152 if (target_start_position == start_position && | |
| 2153 shared->end_position() == target->end_position()) { | |
| 2154 // If a top-level function contains only one function | |
| 2155 // declaration the source for the top-level and the function | |
| 2156 // is the same. In that case prefer the non top-level function. | |
| 2157 if (!shared->is_toplevel()) { | |
| 2158 target_start_position = start_position; | |
| 2159 target_function = function; | |
| 2160 target = shared; | |
| 2161 } | |
| 2162 } else if (target_start_position <= start_position && | |
| 2163 shared->end_position() <= target->end_position()) { | |
| 2164 // This containment check includes equality as a function | |
| 2165 // inside a top-level function can share either start or end | |
| 2166 // position with the top-level function. | |
| 2167 target_start_position = start_position; | |
| 2168 target_function = function; | |
| 2169 target = shared; | |
| 2170 } | |
| 2171 } | |
| 2172 } | |
| 2173 } | |
| 2174 } // End for loop. | |
| 2175 } // End no-allocation scope. | |
| 2176 | |
| 2177 if (target.is_null()) { | |
| 2178 return isolate_->heap()->undefined_value(); | |
| 2179 } | |
| 2180 | |
| 2181 // There will be at least one break point when we are done. | |
| 2182 has_break_points_ = true; | |
|
Michael Starzinger
2012/09/03 13:36:53
These are the only two lines I changed in this fun
| |
| 2183 | |
| 2184 // If the candidate found is compiled we are done. | |
| 2185 done = target->is_compiled(); | |
| 2186 if (!done) { | |
| 2187 // If the candidate is not compiled, compile it to reveal any inner | |
| 2188 // functions which might contain the requested source position. This | |
| 2189 // will compile all inner functions that cannot be compiled without a | |
| 2190 // context, because Compiler::BuildFunctionInfo checks whether the | |
| 2191 // debugger is active. | |
| 2192 if (target_function.is_null()) { | |
| 2193 SharedFunctionInfo::CompileLazy(target, KEEP_EXCEPTION); | |
| 2194 } else { | |
| 2195 JSFunction::CompileLazy(target_function, KEEP_EXCEPTION); | |
| 2196 } | |
| 2197 } | |
| 2198 } // End while loop. | |
| 2199 | |
| 2200 return *target; | |
| 2201 } | |
| 2202 | |
| 2203 | |
| 2095 // Ensures the debug information is present for shared. | 2204 // Ensures the debug information is present for shared. |
| 2096 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared, | 2205 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared, |
| 2097 Handle<JSFunction> function) { | 2206 Handle<JSFunction> function) { |
| 2098 // Return if we already have the debug info for shared. | 2207 // Return if we already have the debug info for shared. |
| 2099 if (HasDebugInfo(shared)) { | 2208 if (HasDebugInfo(shared)) { |
| 2100 ASSERT(shared->is_compiled()); | 2209 ASSERT(shared->is_compiled()); |
| 2101 return true; | 2210 return true; |
| 2102 } | 2211 } |
| 2103 | 2212 |
| 2104 // There will be at least one break point when we are done. | 2213 // There will be at least one break point when we are done. |
| (...skipping 1552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3657 { | 3766 { |
| 3658 Locker locker; | 3767 Locker locker; |
| 3659 Isolate::Current()->debugger()->CallMessageDispatchHandler(); | 3768 Isolate::Current()->debugger()->CallMessageDispatchHandler(); |
| 3660 } | 3769 } |
| 3661 } | 3770 } |
| 3662 } | 3771 } |
| 3663 | 3772 |
| 3664 #endif // ENABLE_DEBUGGER_SUPPORT | 3773 #endif // ENABLE_DEBUGGER_SUPPORT |
| 3665 | 3774 |
| 3666 } } // namespace v8::internal | 3775 } } // namespace v8::internal |
| OLD | NEW |