Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/inspector/v8-debugger.h" | 5 #include "src/inspector/v8-debugger.h" |
| 6 | 6 |
| 7 #include "src/inspector/debugger-script.h" | 7 #include "src/inspector/debugger-script.h" |
| 8 #include "src/inspector/inspected-context.h" | 8 #include "src/inspector/inspected-context.h" |
| 9 #include "src/inspector/protocol/Protocol.h" | 9 #include "src/inspector/protocol/Protocol.h" |
| 10 #include "src/inspector/script-breakpoint.h" | 10 #include "src/inspector/script-breakpoint.h" |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 bool V8Debugger::IsFunctionBlackboxed(v8::Local<v8::debug::Script> script, | 556 bool V8Debugger::IsFunctionBlackboxed(v8::Local<v8::debug::Script> script, |
| 557 const v8::debug::Location& start, | 557 const v8::debug::Location& start, |
| 558 const v8::debug::Location& end) { | 558 const v8::debug::Location& end) { |
| 559 V8DebuggerAgentImpl* agent = agentForScript(m_inspector, script); | 559 V8DebuggerAgentImpl* agent = agentForScript(m_inspector, script); |
| 560 if (!agent) return false; | 560 if (!agent) return false; |
| 561 return agent->isFunctionBlackboxed(String16::fromInteger(script->Id()), start, | 561 return agent->isFunctionBlackboxed(String16::fromInteger(script->Id()), start, |
| 562 end); | 562 end); |
| 563 } | 563 } |
| 564 | 564 |
| 565 void V8Debugger::PromiseEventOccurred(v8::debug::PromiseDebugActionType type, | 565 void V8Debugger::PromiseEventOccurred(v8::debug::PromiseDebugActionType type, |
| 566 int id) { | 566 int id, int parentId) { |
| 567 if (!m_maxAsyncCallStackDepth) return; | 567 if (!m_maxAsyncCallStackDepth) return; |
| 568 // Async task events from Promises are given misaligned pointers to prevent | 568 // Async task events from Promises are given misaligned pointers to prevent |
| 569 // from overlapping with other Blink task identifiers. There is a single | 569 // from overlapping with other Blink task identifiers. There is a single |
| 570 // namespace of such ids, managed by src/js/promise.js. | 570 // namespace of such ids, managed by src/js/promise.js. |
| 571 void* ptr = reinterpret_cast<void*>(id * 2 + 1); | 571 void* ptr = reinterpret_cast<void*>(id * 2 + 1); |
| 572 switch (type) { | 572 switch (type) { |
| 573 case v8::debug::kDebugPromiseCreated: | |
| 574 asyncTaskCreated( | |
| 575 ptr, parentId ? reinterpret_cast<void*>(parentId * 2 + 1) : nullptr); | |
| 576 break; | |
| 573 case v8::debug::kDebugEnqueueAsyncFunction: | 577 case v8::debug::kDebugEnqueueAsyncFunction: |
| 574 asyncTaskScheduled("async function", ptr, true); | 578 asyncTaskScheduled("async function", ptr, true); |
| 575 break; | 579 break; |
| 576 case v8::debug::kDebugEnqueuePromiseResolve: | 580 case v8::debug::kDebugEnqueuePromiseResolve: |
| 577 asyncTaskScheduled("Promise.resolve", ptr, true); | 581 asyncTaskScheduled("Promise.resolve", ptr, true); |
| 578 break; | 582 break; |
| 579 case v8::debug::kDebugEnqueuePromiseReject: | 583 case v8::debug::kDebugEnqueuePromiseReject: |
| 580 asyncTaskScheduled("Promise.reject", ptr, true); | 584 asyncTaskScheduled("Promise.reject", ptr, true); |
| 581 break; | 585 break; |
| 582 case v8::debug::kDebugEnqueuePromiseResolveThenableJob: | |
| 583 asyncTaskScheduled("PromiseResolveThenableJob", ptr, true); | |
| 584 break; | |
| 585 case v8::debug::kDebugPromiseCollected: | 586 case v8::debug::kDebugPromiseCollected: |
| 586 asyncTaskCanceled(ptr); | 587 asyncTaskCanceled(ptr); |
| 587 break; | 588 break; |
| 588 case v8::debug::kDebugWillHandle: | 589 case v8::debug::kDebugWillHandle: |
| 589 asyncTaskStarted(ptr); | 590 asyncTaskStarted(ptr); |
| 590 break; | 591 break; |
| 591 case v8::debug::kDebugDidHandle: | 592 case v8::debug::kDebugDidHandle: |
| 592 asyncTaskFinished(ptr); | 593 asyncTaskFinished(ptr); |
| 593 break; | 594 break; |
| 594 } | 595 } |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 850 for (const auto& pair : m_maxAsyncCallStackDepthMap) { | 851 for (const auto& pair : m_maxAsyncCallStackDepthMap) { |
| 851 if (pair.second > maxAsyncCallStackDepth) | 852 if (pair.second > maxAsyncCallStackDepth) |
| 852 maxAsyncCallStackDepth = pair.second; | 853 maxAsyncCallStackDepth = pair.second; |
| 853 } | 854 } |
| 854 | 855 |
| 855 if (m_maxAsyncCallStackDepth == maxAsyncCallStackDepth) return; | 856 if (m_maxAsyncCallStackDepth == maxAsyncCallStackDepth) return; |
| 856 m_maxAsyncCallStackDepth = maxAsyncCallStackDepth; | 857 m_maxAsyncCallStackDepth = maxAsyncCallStackDepth; |
| 857 if (!maxAsyncCallStackDepth) allAsyncTasksCanceled(); | 858 if (!maxAsyncCallStackDepth) allAsyncTasksCanceled(); |
| 858 } | 859 } |
| 859 | 860 |
| 861 void V8Debugger::asyncTaskCreated(void* task, void* parentTask) { | |
| 862 if (parentTask) m_parentTask[task] = parentTask; | |
| 863 } | |
| 864 | |
| 860 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, | 865 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, |
| 861 bool recurring) { | 866 bool recurring) { |
| 862 if (!m_maxAsyncCallStackDepth) return; | 867 if (!m_maxAsyncCallStackDepth) return; |
| 863 asyncTaskScheduled(toString16(taskName), task, recurring); | 868 asyncTaskScheduled(toString16(taskName), task, recurring); |
| 864 } | 869 } |
| 865 | 870 |
| 866 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, | 871 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, |
| 867 bool recurring) { | 872 bool recurring) { |
| 868 if (!m_maxAsyncCallStackDepth) return; | 873 if (!m_maxAsyncCallStackDepth) return; |
| 869 v8::HandleScope scope(m_isolate); | 874 v8::HandleScope scope(m_isolate); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 884 void* taskToRemove = m_idToTask.begin()->second; | 889 void* taskToRemove = m_idToTask.begin()->second; |
| 885 asyncTaskCanceled(taskToRemove); | 890 asyncTaskCanceled(taskToRemove); |
| 886 } | 891 } |
| 887 } | 892 } |
| 888 } | 893 } |
| 889 | 894 |
| 890 void V8Debugger::asyncTaskCanceled(void* task) { | 895 void V8Debugger::asyncTaskCanceled(void* task) { |
| 891 if (!m_maxAsyncCallStackDepth) return; | 896 if (!m_maxAsyncCallStackDepth) return; |
| 892 m_asyncTaskStacks.erase(task); | 897 m_asyncTaskStacks.erase(task); |
| 893 m_recurringTasks.erase(task); | 898 m_recurringTasks.erase(task); |
| 899 m_parentTask.erase(task); | |
| 894 auto it = m_taskToId.find(task); | 900 auto it = m_taskToId.find(task); |
| 895 if (it == m_taskToId.end()) return; | 901 if (it == m_taskToId.end()) return; |
| 896 m_idToTask.erase(it->second); | 902 m_idToTask.erase(it->second); |
| 897 m_taskToId.erase(it); | 903 m_taskToId.erase(it); |
| 898 } | 904 } |
| 899 | 905 |
| 900 void V8Debugger::asyncTaskStarted(void* task) { | 906 void V8Debugger::asyncTaskStarted(void* task) { |
| 901 if (!m_maxAsyncCallStackDepth) return; | 907 if (!m_maxAsyncCallStackDepth) return; |
| 902 m_currentTasks.push_back(task); | 908 m_currentTasks.push_back(task); |
| 903 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find(task); | 909 auto parentIt = m_parentTask.find(task); |
| 910 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find( | |
| 911 parentIt == m_parentTask.end() ? task : parentIt->second); | |
| 904 // Needs to support following order of events: | 912 // Needs to support following order of events: |
| 905 // - asyncTaskScheduled | 913 // - asyncTaskScheduled |
| 906 // <-- attached here --> | 914 // <-- attached here --> |
| 907 // - asyncTaskStarted | 915 // - asyncTaskStarted |
| 908 // - asyncTaskCanceled <-- canceled before finished | 916 // - asyncTaskCanceled <-- canceled before finished |
| 909 // <-- async stack requested here --> | 917 // <-- async stack requested here --> |
| 910 // - asyncTaskFinished | 918 // - asyncTaskFinished |
| 911 std::unique_ptr<V8StackTraceImpl> stack; | 919 std::unique_ptr<V8StackTraceImpl> stack; |
| 912 if (stackIt != m_asyncTaskStacks.end() && stackIt->second) | 920 if (stackIt != m_asyncTaskStacks.end() && stackIt->second) |
| 913 stack = stackIt->second->cloneImpl(); | 921 stack = stackIt->second->cloneImpl(); |
| 914 m_currentStacks.push_back(std::move(stack)); | 922 m_currentStacks.push_back(std::move(stack)); |
| 915 } | 923 } |
| 916 | 924 |
| 917 void V8Debugger::asyncTaskFinished(void* task) { | 925 void V8Debugger::asyncTaskFinished(void* task) { |
| 918 if (!m_maxAsyncCallStackDepth) return; | 926 if (!m_maxAsyncCallStackDepth) return; |
| 919 // We could start instrumenting half way and the stack is empty. | 927 // We could start instrumenting half way and the stack is empty. |
| 920 if (!m_currentStacks.size()) return; | 928 if (!m_currentStacks.size()) return; |
| 921 | 929 |
| 922 DCHECK(m_currentTasks.back() == task); | 930 DCHECK(m_currentTasks.back() == task); |
| 923 m_currentTasks.pop_back(); | 931 m_currentTasks.pop_back(); |
| 924 | 932 |
| 925 m_currentStacks.pop_back(); | 933 m_currentStacks.pop_back(); |
| 926 if (m_recurringTasks.find(task) == m_recurringTasks.end()) { | 934 if (m_recurringTasks.find(task) == m_recurringTasks.end()) { |
| 927 m_asyncTaskStacks.erase(task); | 935 m_asyncTaskStacks.erase(task); |
|
dgozman
2017/01/24 18:13:51
Call asyncTaskCanceled here.
kozy
2017/01/24 18:41:41
Done.
| |
| 928 auto it = m_taskToId.find(task); | 936 auto it = m_taskToId.find(task); |
| 929 if (it == m_taskToId.end()) return; | 937 if (it == m_taskToId.end()) return; |
| 930 m_idToTask.erase(it->second); | 938 m_idToTask.erase(it->second); |
| 931 m_taskToId.erase(it); | 939 m_taskToId.erase(it); |
| 932 } | 940 } |
| 933 } | 941 } |
| 934 | 942 |
| 935 void V8Debugger::allAsyncTasksCanceled() { | 943 void V8Debugger::allAsyncTasksCanceled() { |
| 936 m_asyncTaskStacks.clear(); | 944 m_asyncTaskStacks.clear(); |
| 937 m_recurringTasks.clear(); | 945 m_recurringTasks.clear(); |
| 938 m_currentStacks.clear(); | 946 m_currentStacks.clear(); |
| 939 m_currentTasks.clear(); | 947 m_currentTasks.clear(); |
| 948 m_parentTask.clear(); | |
| 940 m_idToTask.clear(); | 949 m_idToTask.clear(); |
| 941 m_taskToId.clear(); | 950 m_taskToId.clear(); |
| 942 m_lastTaskId = 0; | 951 m_lastTaskId = 0; |
| 943 } | 952 } |
| 944 | 953 |
| 945 void V8Debugger::muteScriptParsedEvents() { | 954 void V8Debugger::muteScriptParsedEvents() { |
| 946 ++m_ignoreScriptParsedEventsCounter; | 955 ++m_ignoreScriptParsedEventsCounter; |
| 947 } | 956 } |
| 948 | 957 |
| 949 void V8Debugger::unmuteScriptParsedEvents() { | 958 void V8Debugger::unmuteScriptParsedEvents() { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 962 | 971 |
| 963 size_t stackSize = | 972 size_t stackSize = |
| 964 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; | 973 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; |
| 965 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) | 974 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) |
| 966 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; | 975 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; |
| 967 | 976 |
| 968 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); | 977 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); |
| 969 } | 978 } |
| 970 | 979 |
| 971 } // namespace v8_inspector | 980 } // namespace v8_inspector |
| OLD | NEW |