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 |