Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index dcb9dc4c4ca606d1d67f536fb89305ce9f174de9..4c8098e3609ee2d249787f6f41cdeecb77e63ac8 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -11815,7 +11815,8 @@ class ScopeIterator { |
ScopeIterator(Isolate* isolate, |
JavaScriptFrame* frame, |
- int inlined_jsframe_index) |
+ int inlined_jsframe_index, |
+ bool ignore_nested_scopes = false) |
: isolate_(isolate), |
frame_(frame), |
inlined_jsframe_index_(inlined_jsframe_index), |
@@ -11839,19 +11840,31 @@ class ScopeIterator { |
// Return if ensuring debug info failed. |
return; |
} |
- Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info); |
- // Find the break point where execution has stopped. |
- BreakLocationIterator break_location_iterator(debug_info, |
- ALL_BREAK_LOCATIONS); |
- // pc points to the instruction after the current one, possibly a break |
- // location as well. So the "- 1" to exclude it from the search. |
- break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1); |
- if (break_location_iterator.IsExit()) { |
- // We are within the return sequence. At the momemt it is not possible to |
+ // Currently it takes too much time to find nested scopes due to script |
+ // parsing. Sometimes we want to run the ScopeIterator as fast as possible |
+ // (for example, while collecting async call stacks on every |
+ // addEventListener call), even if we drop some nested scopes. |
+ // Later we may optimize getting the nested scopes (cache the result?) |
+ // and include nested scopes into the "fast" iteration case as well. |
+ if (!ignore_nested_scopes) { |
+ Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info); |
+ |
+ // Find the break point where execution has stopped. |
+ BreakLocationIterator break_location_iterator(debug_info, |
+ ALL_BREAK_LOCATIONS); |
+ // pc points to the instruction after the current one, possibly a break |
+ // location as well. So the "- 1" to exclude it from the search. |
+ break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1); |
+ |
+ // Within the return sequence at the moment it is not possible to |
// get a source position which is consistent with the current scope chain. |
// Thus all nested with, catch and block contexts are skipped and we only |
// provide the function scope. |
+ ignore_nested_scopes = break_location_iterator.IsExit(); |
+ } |
+ |
+ if (ignore_nested_scopes) { |
if (scope_info->HasContext()) { |
context_ = Handle<Context>(context_->declaration_context(), isolate_); |
} else { |
@@ -11859,7 +11872,8 @@ class ScopeIterator { |
context_ = Handle<Context>(context_->previous(), isolate_); |
} |
} |
- if (scope_info->scope_type() != EVAL_SCOPE) { |
+ if (scope_info->scope_type() != EVAL_SCOPE && |
ulan
2014/03/21 12:02:21
Considering the comment above: "we only provide th
|
+ scope_info->scope_type() != GLOBAL_SCOPE) { |
nested_scope_chain_.Add(scope_info); |
} |
} else { |
@@ -12327,13 +12341,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) { |
// args[0]: number: break id |
// args[1]: number: frame index |
// args[2]: number: inlined frame index |
+// args[3]: boolean: ignore nested scopes |
// |
// The array returned contains arrays with the following information: |
// 0: Scope type |
// 1: Scope object |
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAllScopesDetails) { |
HandleScope scope(isolate); |
- ASSERT(args.length() == 3); |
+ ASSERT(args.length() == 3 || args.length() == 4); |
// Check arguments. |
Object* check; |
@@ -12344,13 +12359,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAllScopesDetails) { |
CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); |
CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]); |
+ bool ignore_nested_scopes = false; |
+ if (args.length() == 4) { |
+ CONVERT_BOOLEAN_ARG_CHECKED(flag, 3); |
+ ignore_nested_scopes = flag; |
+ } |
+ |
// Get the frame where the debugging is performed. |
StackFrame::Id id = UnwrapFrameId(wrapped_id); |
JavaScriptFrameIterator frame_it(isolate, id); |
JavaScriptFrame* frame = frame_it.frame(); |
List<Handle<JSObject> > result(4); |
- ScopeIterator it(isolate, frame, inlined_jsframe_index); |
+ ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes); |
for (; !it.Done(); it.Next()) { |
Handle<JSObject> details = MaterializeScopeDetails(isolate, &it); |
RETURN_IF_EMPTY_HANDLE(isolate, details); |