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 11797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11808 ScopeTypeLocal, | 11808 ScopeTypeLocal, |
| 11809 ScopeTypeWith, | 11809 ScopeTypeWith, |
| 11810 ScopeTypeClosure, | 11810 ScopeTypeClosure, |
| 11811 ScopeTypeCatch, | 11811 ScopeTypeCatch, |
| 11812 ScopeTypeBlock, | 11812 ScopeTypeBlock, |
| 11813 ScopeTypeModule | 11813 ScopeTypeModule |
| 11814 }; | 11814 }; |
| 11815 | 11815 |
| 11816 ScopeIterator(Isolate* isolate, | 11816 ScopeIterator(Isolate* isolate, |
| 11817 JavaScriptFrame* frame, | 11817 JavaScriptFrame* frame, |
| 11818 int inlined_jsframe_index) | 11818 int inlined_jsframe_index, |
| 11819 bool ignore_nested_scopes = false) | |
| 11819 : isolate_(isolate), | 11820 : isolate_(isolate), |
| 11820 frame_(frame), | 11821 frame_(frame), |
| 11821 inlined_jsframe_index_(inlined_jsframe_index), | 11822 inlined_jsframe_index_(inlined_jsframe_index), |
| 11822 function_(frame->function()), | 11823 function_(frame->function()), |
| 11823 context_(Context::cast(frame->context())), | 11824 context_(Context::cast(frame->context())), |
| 11824 nested_scope_chain_(4), | 11825 nested_scope_chain_(4), |
| 11825 failed_(false) { | 11826 failed_(false) { |
| 11826 | 11827 |
| 11827 // Catch the case when the debugger stops in an internal function. | 11828 // Catch the case when the debugger stops in an internal function. |
| 11828 Handle<SharedFunctionInfo> shared_info(function_->shared()); | 11829 Handle<SharedFunctionInfo> shared_info(function_->shared()); |
| 11829 Handle<ScopeInfo> scope_info(shared_info->scope_info()); | 11830 Handle<ScopeInfo> scope_info(shared_info->scope_info()); |
| 11830 if (shared_info->script() == isolate->heap()->undefined_value()) { | 11831 if (shared_info->script() == isolate->heap()->undefined_value()) { |
| 11831 while (context_->closure() == *function_) { | 11832 while (context_->closure() == *function_) { |
| 11832 context_ = Handle<Context>(context_->previous(), isolate_); | 11833 context_ = Handle<Context>(context_->previous(), isolate_); |
| 11833 } | 11834 } |
| 11834 return; | 11835 return; |
| 11835 } | 11836 } |
| 11836 | 11837 |
| 11837 // Get the debug info (create it if it does not exist). | 11838 // Get the debug info (create it if it does not exist). |
| 11838 if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) { | 11839 if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) { |
| 11839 // Return if ensuring debug info failed. | 11840 // Return if ensuring debug info failed. |
| 11840 return; | 11841 return; |
| 11841 } | 11842 } |
| 11842 Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info); | |
| 11843 | 11843 |
| 11844 // Find the break point where execution has stopped. | 11844 // Currently it takes too much time to find nested scopes due to script |
| 11845 BreakLocationIterator break_location_iterator(debug_info, | 11845 // parsing. Sometimes we want to run the ScopeIterator as fast as possible |
| 11846 ALL_BREAK_LOCATIONS); | 11846 // (for example, while collecting async call stacks on every |
| 11847 // pc points to the instruction after the current one, possibly a break | 11847 // addEventListener call), even if we drop some nested scopes. |
| 11848 // location as well. So the "- 1" to exclude it from the search. | 11848 // Later we may optimize getting the nested scopes (cache the result?) |
| 11849 break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1); | 11849 // and include nested scopes into the "fast" iteration case as well. |
| 11850 if (break_location_iterator.IsExit()) { | 11850 if (!ignore_nested_scopes) { |
| 11851 // We are within the return sequence. At the momemt it is not possible to | 11851 Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info); |
| 11852 | |
| 11853 // Find the break point where execution has stopped. | |
| 11854 BreakLocationIterator break_location_iterator(debug_info, | |
| 11855 ALL_BREAK_LOCATIONS); | |
| 11856 // pc points to the instruction after the current one, possibly a break | |
| 11857 // location as well. So the "- 1" to exclude it from the search. | |
| 11858 break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1); | |
| 11859 | |
| 11860 // Within the return sequence at the moment it is not possible to | |
| 11852 // get a source position which is consistent with the current scope chain. | 11861 // get a source position which is consistent with the current scope chain. |
| 11853 // Thus all nested with, catch and block contexts are skipped and we only | 11862 // Thus all nested with, catch and block contexts are skipped and we only |
| 11854 // provide the function scope. | 11863 // provide the function scope. |
| 11864 ignore_nested_scopes = break_location_iterator.IsExit(); | |
| 11865 } | |
| 11866 | |
| 11867 if (ignore_nested_scopes) { | |
| 11855 if (scope_info->HasContext()) { | 11868 if (scope_info->HasContext()) { |
| 11856 context_ = Handle<Context>(context_->declaration_context(), isolate_); | 11869 context_ = Handle<Context>(context_->declaration_context(), isolate_); |
| 11857 } else { | 11870 } else { |
| 11858 while (context_->closure() == *function_) { | 11871 while (context_->closure() == *function_) { |
| 11859 context_ = Handle<Context>(context_->previous(), isolate_); | 11872 context_ = Handle<Context>(context_->previous(), isolate_); |
| 11860 } | 11873 } |
| 11861 } | 11874 } |
| 11862 if (scope_info->scope_type() != EVAL_SCOPE) { | 11875 if (scope_info->scope_type() != EVAL_SCOPE && |
|
ulan
2014/03/21 12:02:21
Considering the comment above: "we only provide th
| |
| 11876 scope_info->scope_type() != GLOBAL_SCOPE) { | |
| 11863 nested_scope_chain_.Add(scope_info); | 11877 nested_scope_chain_.Add(scope_info); |
| 11864 } | 11878 } |
| 11865 } else { | 11879 } else { |
| 11866 // Reparse the code and analyze the scopes. | 11880 // Reparse the code and analyze the scopes. |
| 11867 Handle<Script> script(Script::cast(shared_info->script())); | 11881 Handle<Script> script(Script::cast(shared_info->script())); |
| 11868 Scope* scope = NULL; | 11882 Scope* scope = NULL; |
| 11869 | 11883 |
| 11870 // Check whether we are in global, eval or function code. | 11884 // Check whether we are in global, eval or function code. |
| 11871 Handle<ScopeInfo> scope_info(shared_info->scope_info()); | 11885 Handle<ScopeInfo> scope_info(shared_info->scope_info()); |
| 11872 if (scope_info->scope_type() != FUNCTION_SCOPE) { | 11886 if (scope_info->scope_type() != FUNCTION_SCOPE) { |
| (...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12320 Handle<JSObject> details = MaterializeScopeDetails(isolate, &it); | 12334 Handle<JSObject> details = MaterializeScopeDetails(isolate, &it); |
| 12321 RETURN_IF_EMPTY_HANDLE(isolate, details); | 12335 RETURN_IF_EMPTY_HANDLE(isolate, details); |
| 12322 return *details; | 12336 return *details; |
| 12323 } | 12337 } |
| 12324 | 12338 |
| 12325 | 12339 |
| 12326 // Return an array of scope details | 12340 // Return an array of scope details |
| 12327 // args[0]: number: break id | 12341 // args[0]: number: break id |
| 12328 // args[1]: number: frame index | 12342 // args[1]: number: frame index |
| 12329 // args[2]: number: inlined frame index | 12343 // args[2]: number: inlined frame index |
| 12344 // args[3]: boolean: ignore nested scopes | |
| 12330 // | 12345 // |
| 12331 // The array returned contains arrays with the following information: | 12346 // The array returned contains arrays with the following information: |
| 12332 // 0: Scope type | 12347 // 0: Scope type |
| 12333 // 1: Scope object | 12348 // 1: Scope object |
| 12334 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAllScopesDetails) { | 12349 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAllScopesDetails) { |
| 12335 HandleScope scope(isolate); | 12350 HandleScope scope(isolate); |
| 12336 ASSERT(args.length() == 3); | 12351 ASSERT(args.length() == 3 || args.length() == 4); |
| 12337 | 12352 |
| 12338 // Check arguments. | 12353 // Check arguments. |
| 12339 Object* check; | 12354 Object* check; |
| 12340 { MaybeObject* maybe_check = Runtime_CheckExecutionState( | 12355 { MaybeObject* maybe_check = Runtime_CheckExecutionState( |
| 12341 RUNTIME_ARGUMENTS(isolate, args)); | 12356 RUNTIME_ARGUMENTS(isolate, args)); |
| 12342 if (!maybe_check->ToObject(&check)) return maybe_check; | 12357 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 12343 } | 12358 } |
| 12344 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); | 12359 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); |
| 12345 CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]); | 12360 CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]); |
| 12346 | 12361 |
| 12362 bool ignore_nested_scopes = false; | |
| 12363 if (args.length() == 4) { | |
| 12364 CONVERT_BOOLEAN_ARG_CHECKED(flag, 3); | |
| 12365 ignore_nested_scopes = flag; | |
| 12366 } | |
| 12367 | |
| 12347 // Get the frame where the debugging is performed. | 12368 // Get the frame where the debugging is performed. |
| 12348 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 12369 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
| 12349 JavaScriptFrameIterator frame_it(isolate, id); | 12370 JavaScriptFrameIterator frame_it(isolate, id); |
| 12350 JavaScriptFrame* frame = frame_it.frame(); | 12371 JavaScriptFrame* frame = frame_it.frame(); |
| 12351 | 12372 |
| 12352 List<Handle<JSObject> > result(4); | 12373 List<Handle<JSObject> > result(4); |
| 12353 ScopeIterator it(isolate, frame, inlined_jsframe_index); | 12374 ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes); |
| 12354 for (; !it.Done(); it.Next()) { | 12375 for (; !it.Done(); it.Next()) { |
| 12355 Handle<JSObject> details = MaterializeScopeDetails(isolate, &it); | 12376 Handle<JSObject> details = MaterializeScopeDetails(isolate, &it); |
| 12356 RETURN_IF_EMPTY_HANDLE(isolate, details); | 12377 RETURN_IF_EMPTY_HANDLE(isolate, details); |
| 12357 result.Add(details); | 12378 result.Add(details); |
| 12358 } | 12379 } |
| 12359 | 12380 |
| 12360 Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length()); | 12381 Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length()); |
| 12361 for (int i = 0; i < result.length(); ++i) { | 12382 for (int i = 0; i < result.length(); ++i) { |
| 12362 array->set(i, *result[i]); | 12383 array->set(i, *result[i]); |
| 12363 } | 12384 } |
| (...skipping 2676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 15040 // Handle last resort GC and make sure to allow future allocations | 15061 // Handle last resort GC and make sure to allow future allocations |
| 15041 // to grow the heap without causing GCs (if possible). | 15062 // to grow the heap without causing GCs (if possible). |
| 15042 isolate->counters()->gc_last_resort_from_js()->Increment(); | 15063 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 15043 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 15064 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 15044 "Runtime::PerformGC"); | 15065 "Runtime::PerformGC"); |
| 15045 } | 15066 } |
| 15046 } | 15067 } |
| 15047 | 15068 |
| 15048 | 15069 |
| 15049 } } // namespace v8::internal | 15070 } } // namespace v8::internal |
| OLD | NEW |