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 |