Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: src/debug.cc

Issue 1206573004: Debugger: use list to find shared function info in a script. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix liveedit Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/debug.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/arguments.h" 8 #include "src/arguments.h"
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 1966 matching lines...) Expand 10 before | Expand all | Expand 10 after
1977 RedirectActivationsToRecompiledCodeOnThread(isolate_, 1977 RedirectActivationsToRecompiledCodeOnThread(isolate_,
1978 isolate_->thread_local_top()); 1978 isolate_->thread_local_top());
1979 1979
1980 ActiveFunctionsRedirector active_functions_redirector; 1980 ActiveFunctionsRedirector active_functions_redirector;
1981 isolate_->thread_manager()->IterateArchivedThreads( 1981 isolate_->thread_manager()->IterateArchivedThreads(
1982 &active_functions_redirector); 1982 &active_functions_redirector);
1983 } 1983 }
1984 } 1984 }
1985 1985
1986 1986
1987 class SharedFunctionInfoFinder {
1988 public:
1989 explicit SharedFunctionInfoFinder(int target_position)
1990 : current_candidate_(NULL),
1991 current_candidate_closure_(NULL),
1992 current_start_position_(RelocInfo::kNoPosition),
1993 target_position_(target_position) {}
1994
1995 void NewCandidate(SharedFunctionInfo* shared, JSFunction* closure = NULL) {
1996 int start_position = shared->function_token_position();
1997 if (start_position == RelocInfo::kNoPosition) {
1998 start_position = shared->start_position();
1999 }
2000
2001 if (start_position > target_position_) return;
2002 if (target_position_ > shared->end_position()) return;
2003
2004 if (current_candidate_ != NULL) {
2005 if (current_start_position_ == start_position &&
2006 shared->end_position() == current_candidate_->end_position()) {
2007 // If a top-level function contains only one function
2008 // declaration the source for the top-level and the function
2009 // is the same. In that case prefer the non top-level function.
2010 if (shared->is_toplevel()) return;
2011 } else if (start_position < current_start_position_ ||
2012 current_candidate_->end_position() < shared->end_position()) {
2013 return;
2014 }
2015 }
2016
2017 current_start_position_ = start_position;
2018 current_candidate_ = shared;
2019 current_candidate_closure_ = closure;
2020 }
2021
2022 SharedFunctionInfo* Result() { return current_candidate_; }
2023
2024 JSFunction* ResultClosure() { return current_candidate_closure_; }
2025
2026 private:
2027 SharedFunctionInfo* current_candidate_;
2028 JSFunction* current_candidate_closure_;
2029 int current_start_position_;
2030 int target_position_;
2031 DisallowHeapAllocation no_gc_;
2032 };
2033
2034
2035 template <typename C>
2036 bool Debug::CompileToRevealInnerFunctions(C* compilable) {
2037 HandleScope scope(isolate_);
2038 // Force compiling inner functions that require context.
2039 // TODO(yangguo): remove this hack.
2040 bool has_break_points = has_break_points_;
2041 has_break_points_ = true;
2042 Handle<C> compilable_handle(compilable);
2043 bool result = !Compiler::GetUnoptimizedCode(compilable_handle).is_null();
2044 has_break_points_ = has_break_points;
2045 return result;
2046 }
2047
2048
1987 Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script, 2049 Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
1988 int position) { 2050 int position) {
1989 // Iterate the heap looking for SharedFunctionInfo generated from the 2051 while (true) {
1990 // script. The inner most SharedFunctionInfo containing the source position 2052 // Go through all shared function infos associated with this script to
1991 // for the requested break point is found. 2053 // find the inner most function containing this position.
1992 // NOTE: This might require several heap iterations. If the SharedFunctionInfo 2054 if (!script->shared_function_infos()->IsWeakFixedArray()) break;
1993 // which is found is not compiled it is compiled and the heap is iterated 2055 WeakFixedArray* array =
1994 // again as the compilation might create inner functions from the newly 2056 WeakFixedArray::cast(script->shared_function_infos());
1995 // compiled function and the actual requested break point might be in one of 2057
1996 // these functions. 2058 SharedFunctionInfo* shared;
1997 // NOTE: The below fix-point iteration depends on all functions that cannot be 2059 {
1998 // compiled lazily without a context to not be compiled at all. Compilation 2060 SharedFunctionInfoFinder finder(position);
1999 // will be triggered at points where we do not need a context. 2061 for (int i = 0; i < array->Length(); i++) {
2000 bool done = false; 2062 Object* item = array->Get(i);
2001 // The current candidate for the source position: 2063 if (!item->IsSharedFunctionInfo()) continue;
2002 int target_start_position = RelocInfo::kNoPosition; 2064 SharedFunctionInfo* shared = SharedFunctionInfo::cast(item);
brucedawson 2015/06/29 17:08:53 Is it intentional that this shadows the outer-scop
2003 Handle<JSFunction> target_function; 2065 finder.NewCandidate(shared);
2004 Handle<SharedFunctionInfo> target; 2066 }
2005 Heap* heap = isolate_->heap(); 2067 shared = finder.Result();
2006 while (!done) { 2068 if (shared == NULL) break;
2007 { // Extra scope for iterator. 2069 // We found it if it's already compiled.
2008 // If lazy compilation is off, we won't have duplicate shared function 2070 if (shared->is_compiled()) return handle(shared);
2009 // infos that need to be filtered. 2071 }
2010 HeapIterator iterator(heap, FLAG_lazy ? HeapIterator::kNoFiltering 2072 // If not, compile to reveal inner functions, if possible.
2011 : HeapIterator::kFilterUnreachable); 2073 if (shared->allows_lazy_compilation_without_context()) {
2012 for (HeapObject* obj = iterator.next(); 2074 if (!CompileToRevealInnerFunctions(shared)) break;
2013 obj != NULL; obj = iterator.next()) { 2075 continue;
2014 bool found_next_candidate = false; 2076 }
2015 Handle<JSFunction> function; 2077
2016 Handle<SharedFunctionInfo> shared; 2078 // If not possible, comb the heap for the best suitable compile target.
2017 if (obj->IsJSFunction()) { 2079 JSFunction* closure;
2018 function = Handle<JSFunction>(JSFunction::cast(obj)); 2080 {
2019 shared = Handle<SharedFunctionInfo>(function->shared()); 2081 HeapIterator it(isolate_->heap(), HeapIterator::kNoFiltering);
2020 DCHECK(shared->allows_lazy_compilation() || shared->is_compiled()); 2082 SharedFunctionInfoFinder finder(position);
2021 found_next_candidate = true; 2083 while (HeapObject* object = it.next()) {
2022 } else if (obj->IsSharedFunctionInfo()) { 2084 JSFunction* closure = NULL;
brucedawson 2015/06/29 17:08:53 Is it intentional that this shadows the outer-scop
2023 shared = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(obj)); 2085 SharedFunctionInfo* shared = NULL;
brucedawson 2015/06/29 17:08:53 Is it intentional that this shadows the outer-scop
2024 // Skip functions that we cannot compile lazily without a context, 2086 if (object->IsJSFunction()) {
2025 // which is not available here, because there is no closure. 2087 closure = JSFunction::cast(object);
2026 found_next_candidate = shared->is_compiled() || 2088 shared = closure->shared();
2027 shared->allows_lazy_compilation_without_context(); 2089 } else if (object->IsSharedFunctionInfo()) {
2090 shared = SharedFunctionInfo::cast(object);
2091 if (!shared->allows_lazy_compilation_without_context()) continue;
2092 } else {
2093 continue;
2028 } 2094 }
2029 if (!found_next_candidate) continue; 2095 if (shared->script() == *script) finder.NewCandidate(shared, closure);
2030 if (shared->script() == *script) { 2096 }
2031 // If the SharedFunctionInfo found has the requested script data and 2097 closure = finder.ResultClosure();
2032 // contains the source position it is a candidate. 2098 shared = finder.Result();
2033 int start_position = shared->function_token_position();
2034 if (start_position == RelocInfo::kNoPosition) {
2035 start_position = shared->start_position();
2036 }
2037 if (start_position <= position &&
2038 position <= shared->end_position()) {
2039 // If there is no candidate or this function is within the current
2040 // candidate this is the new candidate.
2041 if (target.is_null()) {
2042 target_start_position = start_position;
2043 target_function = function;
2044 target = shared;
2045 } else {
2046 if (target_start_position == start_position &&
2047 shared->end_position() == target->end_position()) {
2048 // If a top-level function contains only one function
2049 // declaration the source for the top-level and the function
2050 // is the same. In that case prefer the non top-level function.
2051 if (!shared->is_toplevel()) {
2052 target_start_position = start_position;
2053 target_function = function;
2054 target = shared;
2055 }
2056 } else if (target_start_position <= start_position &&
2057 shared->end_position() <= target->end_position()) {
2058 // This containment check includes equality as a function
2059 // inside a top-level function can share either start or end
2060 // position with the top-level function.
2061 target_start_position = start_position;
2062 target_function = function;
2063 target = shared;
2064 }
2065 }
2066 }
2067 }
2068 } // End for loop.
2069 } // End no-allocation scope.
2070
2071 if (target.is_null()) return isolate_->factory()->undefined_value();
2072
2073 // There will be at least one break point when we are done.
2074 has_break_points_ = true;
2075
2076 // If the candidate found is compiled we are done.
2077 done = target->is_compiled();
2078 if (!done) {
2079 // If the candidate is not compiled, compile it to reveal any inner
2080 // functions which might contain the requested source position. This
2081 // will compile all inner functions that cannot be compiled without a
2082 // context, because Compiler::GetSharedFunctionInfo checks whether the
2083 // debugger is active.
2084 MaybeHandle<Code> maybe_result = target_function.is_null()
2085 ? Compiler::GetUnoptimizedCode(target)
2086 : Compiler::GetUnoptimizedCode(target_function);
2087 if (maybe_result.is_null()) return isolate_->factory()->undefined_value();
2088 } 2099 }
2089 } // End while loop. 2100 if (closure == NULL ? !CompileToRevealInnerFunctions(shared)
2090 2101 : !CompileToRevealInnerFunctions(closure)) {
2091 // JSFunctions from the same literal may not have the same shared function 2102 break;
2092 // info. Find those JSFunctions and deduplicate the shared function info.
2093 HeapIterator iterator(heap, FLAG_lazy ? HeapIterator::kNoFiltering
2094 : HeapIterator::kFilterUnreachable);
2095 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
2096 if (!obj->IsJSFunction()) continue;
2097 JSFunction* function = JSFunction::cast(obj);
2098 SharedFunctionInfo* shared = function->shared();
2099 if (shared != *target && shared->script() == target->script() &&
2100 shared->start_position_and_type() ==
2101 target->start_position_and_type()) {
2102 function->set_shared(*target);
2103 } 2103 }
2104 } 2104 }
2105 2105 return isolate_->factory()->undefined_value();
2106 return target;
2107 } 2106 }
2108 2107
2109 2108
2110 // Ensures the debug information is present for shared. 2109 // Ensures the debug information is present for shared.
2111 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared, 2110 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
2112 Handle<JSFunction> function) { 2111 Handle<JSFunction> function) {
2113 Isolate* isolate = shared->GetIsolate(); 2112 Isolate* isolate = shared->GetIsolate();
2114 2113
2115 // Return if we already have the debug info for shared. 2114 // Return if we already have the debug info for shared.
2116 if (HasDebugInfo(shared)) { 2115 if (HasDebugInfo(shared)) {
(...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after
3387 } 3386 }
3388 3387
3389 3388
3390 void LockingCommandMessageQueue::Clear() { 3389 void LockingCommandMessageQueue::Clear() {
3391 base::LockGuard<base::Mutex> lock_guard(&mutex_); 3390 base::LockGuard<base::Mutex> lock_guard(&mutex_);
3392 queue_.Clear(); 3391 queue_.Clear();
3393 } 3392 }
3394 3393
3395 } // namespace internal 3394 } // namespace internal
3396 } // namespace v8 3395 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698