| 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 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 for (const auto& pair : m_maxAsyncCallStackDepthMap) { | 851 for (const auto& pair : m_maxAsyncCallStackDepthMap) { |
| 852 if (pair.second > maxAsyncCallStackDepth) | 852 if (pair.second > maxAsyncCallStackDepth) |
| 853 maxAsyncCallStackDepth = pair.second; | 853 maxAsyncCallStackDepth = pair.second; |
| 854 } | 854 } |
| 855 | 855 |
| 856 if (m_maxAsyncCallStackDepth == maxAsyncCallStackDepth) return; | 856 if (m_maxAsyncCallStackDepth == maxAsyncCallStackDepth) return; |
| 857 m_maxAsyncCallStackDepth = maxAsyncCallStackDepth; | 857 m_maxAsyncCallStackDepth = maxAsyncCallStackDepth; |
| 858 if (!maxAsyncCallStackDepth) allAsyncTasksCanceled(); | 858 if (!maxAsyncCallStackDepth) allAsyncTasksCanceled(); |
| 859 } | 859 } |
| 860 | 860 |
| 861 void V8Debugger::registerAsyncTaskIfNeeded(void* task) { |
| 862 if (m_taskToId.find(task) != m_taskToId.end()) return; |
| 863 |
| 864 int id = ++m_lastTaskId; |
| 865 m_taskToId[task] = id; |
| 866 m_idToTask[id] = task; |
| 867 if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) { |
| 868 void* taskToRemove = m_idToTask.begin()->second; |
| 869 asyncTaskCanceled(taskToRemove); |
| 870 } |
| 871 } |
| 872 |
| 861 void V8Debugger::asyncTaskCreated(void* task, void* parentTask) { | 873 void V8Debugger::asyncTaskCreated(void* task, void* parentTask) { |
| 862 if (!m_maxAsyncCallStackDepth) return; | 874 if (!m_maxAsyncCallStackDepth) return; |
| 863 if (parentTask) m_parentTask[task] = parentTask; | 875 if (parentTask) m_parentTask[task] = parentTask; |
| 876 v8::HandleScope scope(m_isolate); |
| 877 // We don't need to pass context group id here because we gets this callback |
| 878 // from V8 for promise events only. |
| 879 // Passing one as maxStackSize forces no async chain for the new stack and |
| 880 // allows us to not grow exponentially. |
| 881 std::unique_ptr<V8StackTraceImpl> creationStack = |
| 882 V8StackTraceImpl::capture(this, 0, 1, String16()); |
| 883 if (creationStack && !creationStack->isEmpty()) { |
| 884 m_asyncTaskCreationStacks[task] = std::move(creationStack); |
| 885 registerAsyncTaskIfNeeded(task); |
| 886 } |
| 864 } | 887 } |
| 865 | 888 |
| 866 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, | 889 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, |
| 867 bool recurring) { | 890 bool recurring) { |
| 868 if (!m_maxAsyncCallStackDepth) return; | 891 if (!m_maxAsyncCallStackDepth) return; |
| 869 asyncTaskScheduled(toString16(taskName), task, recurring); | 892 asyncTaskScheduled(toString16(taskName), task, recurring); |
| 870 } | 893 } |
| 871 | 894 |
| 872 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, | 895 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, |
| 873 bool recurring) { | 896 bool recurring) { |
| 874 if (!m_maxAsyncCallStackDepth) return; | 897 if (!m_maxAsyncCallStackDepth) return; |
| 875 v8::HandleScope scope(m_isolate); | 898 v8::HandleScope scope(m_isolate); |
| 876 int contextGroupId = | 899 int contextGroupId = |
| 877 m_isolate->InContext() | 900 m_isolate->InContext() |
| 878 ? m_inspector->contextGroupId(m_isolate->GetCurrentContext()) | 901 ? m_inspector->contextGroupId(m_isolate->GetCurrentContext()) |
| 879 : 0; | 902 : 0; |
| 880 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture( | 903 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture( |
| 881 this, contextGroupId, V8StackTraceImpl::maxCallStackSizeToCapture, | 904 this, contextGroupId, V8StackTraceImpl::maxCallStackSizeToCapture, |
| 882 taskName); | 905 taskName); |
| 883 if (chain) { | 906 if (chain) { |
| 884 m_asyncTaskStacks[task] = std::move(chain); | 907 m_asyncTaskStacks[task] = std::move(chain); |
| 885 if (recurring) m_recurringTasks.insert(task); | 908 if (recurring) m_recurringTasks.insert(task); |
| 886 int id = ++m_lastTaskId; | 909 registerAsyncTaskIfNeeded(task); |
| 887 m_taskToId[task] = id; | |
| 888 m_idToTask[id] = task; | |
| 889 if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) { | |
| 890 void* taskToRemove = m_idToTask.begin()->second; | |
| 891 asyncTaskCanceled(taskToRemove); | |
| 892 } | |
| 893 } | 910 } |
| 894 } | 911 } |
| 895 | 912 |
| 896 void V8Debugger::asyncTaskCanceled(void* task) { | 913 void V8Debugger::asyncTaskCanceled(void* task) { |
| 897 if (!m_maxAsyncCallStackDepth) return; | 914 if (!m_maxAsyncCallStackDepth) return; |
| 898 m_asyncTaskStacks.erase(task); | 915 m_asyncTaskStacks.erase(task); |
| 899 m_recurringTasks.erase(task); | 916 m_recurringTasks.erase(task); |
| 900 m_parentTask.erase(task); | 917 m_parentTask.erase(task); |
| 918 m_asyncTaskCreationStacks.erase(task); |
| 901 auto it = m_taskToId.find(task); | 919 auto it = m_taskToId.find(task); |
| 902 if (it == m_taskToId.end()) return; | 920 if (it == m_taskToId.end()) return; |
| 903 m_idToTask.erase(it->second); | 921 m_idToTask.erase(it->second); |
| 904 m_taskToId.erase(it); | 922 m_taskToId.erase(it); |
| 905 } | 923 } |
| 906 | 924 |
| 907 void V8Debugger::asyncTaskStarted(void* task) { | 925 void V8Debugger::asyncTaskStarted(void* task) { |
| 908 if (!m_maxAsyncCallStackDepth) return; | 926 if (!m_maxAsyncCallStackDepth) return; |
| 909 m_currentTasks.push_back(task); | 927 m_currentTasks.push_back(task); |
| 910 auto parentIt = m_parentTask.find(task); | 928 auto parentIt = m_parentTask.find(task); |
| 911 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find( | 929 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find( |
| 912 parentIt == m_parentTask.end() ? task : parentIt->second); | 930 parentIt == m_parentTask.end() ? task : parentIt->second); |
| 913 // Needs to support following order of events: | 931 // Needs to support following order of events: |
| 914 // - asyncTaskScheduled | 932 // - asyncTaskScheduled |
| 915 // <-- attached here --> | 933 // <-- attached here --> |
| 916 // - asyncTaskStarted | 934 // - asyncTaskStarted |
| 917 // - asyncTaskCanceled <-- canceled before finished | 935 // - asyncTaskCanceled <-- canceled before finished |
| 918 // <-- async stack requested here --> | 936 // <-- async stack requested here --> |
| 919 // - asyncTaskFinished | 937 // - asyncTaskFinished |
| 920 std::unique_ptr<V8StackTraceImpl> stack; | 938 std::unique_ptr<V8StackTraceImpl> stack; |
| 921 if (stackIt != m_asyncTaskStacks.end() && stackIt->second) | 939 if (stackIt != m_asyncTaskStacks.end() && stackIt->second) |
| 922 stack = stackIt->second->cloneImpl(); | 940 stack = stackIt->second->cloneImpl(); |
| 941 auto itCreation = m_asyncTaskCreationStacks.find(task); |
| 942 if (stack && itCreation != m_asyncTaskCreationStacks.end()) { |
| 943 stack->setCreation(itCreation->second->cloneImpl()); |
| 944 } |
| 923 m_currentStacks.push_back(std::move(stack)); | 945 m_currentStacks.push_back(std::move(stack)); |
| 924 } | 946 } |
| 925 | 947 |
| 926 void V8Debugger::asyncTaskFinished(void* task) { | 948 void V8Debugger::asyncTaskFinished(void* task) { |
| 927 if (!m_maxAsyncCallStackDepth) return; | 949 if (!m_maxAsyncCallStackDepth) return; |
| 928 // We could start instrumenting half way and the stack is empty. | 950 // We could start instrumenting half way and the stack is empty. |
| 929 if (!m_currentStacks.size()) return; | 951 if (!m_currentStacks.size()) return; |
| 930 | 952 |
| 931 DCHECK(m_currentTasks.back() == task); | 953 DCHECK(m_currentTasks.back() == task); |
| 932 m_currentTasks.pop_back(); | 954 m_currentTasks.pop_back(); |
| 933 | 955 |
| 934 m_currentStacks.pop_back(); | 956 m_currentStacks.pop_back(); |
| 935 if (m_recurringTasks.find(task) == m_recurringTasks.end()) { | 957 if (m_recurringTasks.find(task) == m_recurringTasks.end()) { |
| 936 asyncTaskCanceled(task); | 958 asyncTaskCanceled(task); |
| 937 } | 959 } |
| 938 } | 960 } |
| 939 | 961 |
| 940 void V8Debugger::allAsyncTasksCanceled() { | 962 void V8Debugger::allAsyncTasksCanceled() { |
| 941 m_asyncTaskStacks.clear(); | 963 m_asyncTaskStacks.clear(); |
| 942 m_recurringTasks.clear(); | 964 m_recurringTasks.clear(); |
| 943 m_currentStacks.clear(); | 965 m_currentStacks.clear(); |
| 944 m_currentTasks.clear(); | 966 m_currentTasks.clear(); |
| 945 m_parentTask.clear(); | 967 m_parentTask.clear(); |
| 968 m_asyncTaskCreationStacks.clear(); |
| 946 m_idToTask.clear(); | 969 m_idToTask.clear(); |
| 947 m_taskToId.clear(); | 970 m_taskToId.clear(); |
| 948 m_lastTaskId = 0; | 971 m_lastTaskId = 0; |
| 949 } | 972 } |
| 950 | 973 |
| 951 void V8Debugger::muteScriptParsedEvents() { | 974 void V8Debugger::muteScriptParsedEvents() { |
| 952 ++m_ignoreScriptParsedEventsCounter; | 975 ++m_ignoreScriptParsedEventsCounter; |
| 953 } | 976 } |
| 954 | 977 |
| 955 void V8Debugger::unmuteScriptParsedEvents() { | 978 void V8Debugger::unmuteScriptParsedEvents() { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 968 | 991 |
| 969 size_t stackSize = | 992 size_t stackSize = |
| 970 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; | 993 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; |
| 971 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) | 994 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) |
| 972 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; | 995 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; |
| 973 | 996 |
| 974 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); | 997 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); |
| 975 } | 998 } |
| 976 | 999 |
| 977 } // namespace v8_inspector | 1000 } // namespace v8_inspector |
| OLD | NEW |