| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
| 9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
| 10 #include "src/debug.h" | 10 #include "src/debug.h" |
| (...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1389 return; | 1389 return; |
| 1390 } | 1390 } |
| 1391 | 1391 |
| 1392 // Currently it takes too much time to find nested scopes due to script | 1392 // Currently it takes too much time to find nested scopes due to script |
| 1393 // parsing. Sometimes we want to run the ScopeIterator as fast as possible | 1393 // parsing. Sometimes we want to run the ScopeIterator as fast as possible |
| 1394 // (for example, while collecting async call stacks on every | 1394 // (for example, while collecting async call stacks on every |
| 1395 // addEventListener call), even if we drop some nested scopes. | 1395 // addEventListener call), even if we drop some nested scopes. |
| 1396 // Later we may optimize getting the nested scopes (cache the result?) | 1396 // Later we may optimize getting the nested scopes (cache the result?) |
| 1397 // and include nested scopes into the "fast" iteration case as well. | 1397 // and include nested scopes into the "fast" iteration case as well. |
| 1398 | 1398 |
| 1399 if (!ignore_nested_scopes && !shared_info->debug_info()->IsUndefined()) { | 1399 if (!ignore_nested_scopes && shared_info->HasDebugInfo()) { |
| 1400 // The source position at return is always the end of the function, | 1400 // The source position at return is always the end of the function, |
| 1401 // which is not consistent with the current scope chain. Therefore all | 1401 // which is not consistent with the current scope chain. Therefore all |
| 1402 // nested with, catch and block contexts are skipped, and we can only | 1402 // nested with, catch and block contexts are skipped, and we can only |
| 1403 // inspect the function scope. | 1403 // inspect the function scope. |
| 1404 // This can only happen if we set a break point inside right before the | 1404 // This can only happen if we set a break point inside right before the |
| 1405 // return, which requires a debug info to be available. | 1405 // return, which requires a debug info to be available. |
| 1406 Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info); | 1406 Handle<DebugInfo> debug_info(shared_info->GetDebugInfo()); |
| 1407 | 1407 |
| 1408 // PC points to the instruction after the current one, possibly a break | 1408 // PC points to the instruction after the current one, possibly a break |
| 1409 // location as well. So the "- 1" to exclude it from the search. | 1409 // location as well. So the "- 1" to exclude it from the search. |
| 1410 Address call_pc = frame()->pc() - 1; | 1410 Address call_pc = frame()->pc() - 1; |
| 1411 | 1411 |
| 1412 // Find the break point where execution has stopped. | 1412 // Find the break point where execution has stopped. |
| 1413 BreakLocation location = | 1413 BreakLocation location = |
| 1414 BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc); | 1414 BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc); |
| 1415 | 1415 |
| 1416 ignore_nested_scopes = location.IsReturn(); | 1416 ignore_nested_scopes = location.IsReturn(); |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1811 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); | 1811 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); |
| 1812 RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id)); | 1812 RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id)); |
| 1813 | 1813 |
| 1814 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); | 1814 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); |
| 1815 | 1815 |
| 1816 // Get the frame where the debugging is performed. | 1816 // Get the frame where the debugging is performed. |
| 1817 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 1817 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
| 1818 JavaScriptFrameIterator frame_it(isolate, id); | 1818 JavaScriptFrameIterator frame_it(isolate, id); |
| 1819 RUNTIME_ASSERT(!frame_it.done()); | 1819 RUNTIME_ASSERT(!frame_it.done()); |
| 1820 | 1820 |
| 1821 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); | 1821 List<int> positions; |
| 1822 frame_it.frame()->Summarize(&frames); | 1822 isolate->debug()->GetStepinPositions(frame_it.frame(), id, &positions); |
| 1823 FrameSummary summary = frames.first(); | 1823 Factory* factory = isolate->factory(); |
| 1824 | 1824 Handle<FixedArray> array = factory->NewFixedArray(positions.length()); |
| 1825 Handle<JSFunction> fun = Handle<JSFunction>(summary.function()); | 1825 for (int i = 0; i < positions.length(); ++i) { |
| 1826 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(fun->shared()); | 1826 array->set(i, Smi::FromInt(positions[i])); |
| 1827 | |
| 1828 if (!isolate->debug()->EnsureDebugInfo(shared, fun)) { | |
| 1829 return isolate->heap()->undefined_value(); | |
| 1830 } | 1827 } |
| 1831 | 1828 return *factory->NewJSArrayWithElements(array, FAST_SMI_ELEMENTS); |
| 1832 Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared); | |
| 1833 | |
| 1834 // Find range of break points starting from the break point where execution | |
| 1835 // has stopped. | |
| 1836 Address call_pc = summary.pc() - 1; | |
| 1837 List<BreakLocation> locations; | |
| 1838 BreakLocation::FromAddressSameStatement(debug_info, ALL_BREAK_LOCATIONS, | |
| 1839 call_pc, &locations); | |
| 1840 | |
| 1841 Handle<JSArray> array = isolate->factory()->NewJSArray(locations.length()); | |
| 1842 | |
| 1843 int index = 0; | |
| 1844 for (BreakLocation location : locations) { | |
| 1845 bool accept; | |
| 1846 if (location.pc() > summary.pc()) { | |
| 1847 accept = true; | |
| 1848 } else { | |
| 1849 StackFrame::Id break_frame_id = isolate->debug()->break_frame_id(); | |
| 1850 // The break point is near our pc. Could be a step-in possibility, | |
| 1851 // that is currently taken by active debugger call. | |
| 1852 if (break_frame_id == StackFrame::NO_ID) { | |
| 1853 // We are not stepping. | |
| 1854 accept = false; | |
| 1855 } else { | |
| 1856 JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id); | |
| 1857 // If our frame is a top frame and we are stepping, we can do step-in | |
| 1858 // at this place. | |
| 1859 accept = additional_frame_it.frame()->id() == id; | |
| 1860 } | |
| 1861 } | |
| 1862 if (accept) { | |
| 1863 if (location.IsStepInLocation()) { | |
| 1864 Smi* position_value = Smi::FromInt(location.position()); | |
| 1865 RETURN_FAILURE_ON_EXCEPTION( | |
| 1866 isolate, | |
| 1867 Object::SetElement(isolate, array, index, | |
| 1868 handle(position_value, isolate), SLOPPY)); | |
| 1869 index++; | |
| 1870 } | |
| 1871 } | |
| 1872 } | |
| 1873 return *array; | |
| 1874 } | 1829 } |
| 1875 | 1830 |
| 1876 | 1831 |
| 1877 static const int kScopeDetailsTypeIndex = 0; | 1832 static const int kScopeDetailsTypeIndex = 0; |
| 1878 static const int kScopeDetailsObjectIndex = 1; | 1833 static const int kScopeDetailsObjectIndex = 1; |
| 1879 static const int kScopeDetailsSize = 2; | 1834 static const int kScopeDetailsSize = 2; |
| 1880 | 1835 |
| 1881 | 1836 |
| 1882 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScopeDetails( | 1837 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScopeDetails( |
| 1883 Isolate* isolate, ScopeIterator* it) { | 1838 Isolate* isolate, ScopeIterator* it) { |
| (...skipping 1341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3225 return *isolate->factory()->undefined_value(); | 3180 return *isolate->factory()->undefined_value(); |
| 3226 } | 3181 } |
| 3227 | 3182 |
| 3228 | 3183 |
| 3229 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { | 3184 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { |
| 3230 UNIMPLEMENTED(); | 3185 UNIMPLEMENTED(); |
| 3231 return NULL; | 3186 return NULL; |
| 3232 } | 3187 } |
| 3233 } // namespace internal | 3188 } // namespace internal |
| 3234 } // namespace v8 | 3189 } // namespace v8 |
| OLD | NEW |