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