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 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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) { |
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(ptr); |
| 575 break; |
573 case v8::debug::kDebugEnqueueAsyncFunction: | 576 case v8::debug::kDebugEnqueueAsyncFunction: |
574 asyncTaskScheduled("async function", ptr, true); | 577 asyncTaskScheduled("async function", ptr, true); |
575 break; | 578 break; |
576 case v8::debug::kDebugEnqueuePromiseResolve: | 579 case v8::debug::kDebugEnqueuePromiseResolve: |
577 asyncTaskScheduled("Promise.resolve", ptr, true); | 580 asyncTaskScheduled("Promise.resolve", ptr, true); |
578 break; | 581 break; |
579 case v8::debug::kDebugEnqueuePromiseReject: | 582 case v8::debug::kDebugEnqueuePromiseReject: |
580 asyncTaskScheduled("Promise.reject", ptr, true); | 583 asyncTaskScheduled("Promise.reject", ptr, true); |
581 break; | 584 break; |
582 case v8::debug::kDebugEnqueuePromiseResolveThenableJob: | 585 case v8::debug::kDebugEnqueuePromiseResolveThenableJob: |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 for (const auto& pair : m_maxAsyncCallStackDepthMap) { | 853 for (const auto& pair : m_maxAsyncCallStackDepthMap) { |
851 if (pair.second > maxAsyncCallStackDepth) | 854 if (pair.second > maxAsyncCallStackDepth) |
852 maxAsyncCallStackDepth = pair.second; | 855 maxAsyncCallStackDepth = pair.second; |
853 } | 856 } |
854 | 857 |
855 if (m_maxAsyncCallStackDepth == maxAsyncCallStackDepth) return; | 858 if (m_maxAsyncCallStackDepth == maxAsyncCallStackDepth) return; |
856 m_maxAsyncCallStackDepth = maxAsyncCallStackDepth; | 859 m_maxAsyncCallStackDepth = maxAsyncCallStackDepth; |
857 if (!maxAsyncCallStackDepth) allAsyncTasksCanceled(); | 860 if (!maxAsyncCallStackDepth) allAsyncTasksCanceled(); |
858 } | 861 } |
859 | 862 |
| 863 void V8Debugger::registerAsyncTaskIfNeeded(void* task) { |
| 864 if (m_taskToId.find(task) != m_taskToId.end()) return; |
| 865 |
| 866 int id = ++m_lastTaskId; |
| 867 m_taskToId[task] = id; |
| 868 m_idToTask[id] = task; |
| 869 if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) { |
| 870 void* taskToRemove = m_idToTask.begin()->second; |
| 871 asyncTaskCanceled(taskToRemove); |
| 872 } |
| 873 } |
| 874 |
| 875 void V8Debugger::asyncTaskCreated(void* task) { |
| 876 if (!m_maxAsyncCallStackDepth) return; |
| 877 v8::HandleScope scope(m_isolate); |
| 878 std::unique_ptr<V8StackTraceImpl> chain = |
| 879 V8StackTraceImpl::capture(this, 0, 1, String16()); |
| 880 if (chain) { |
| 881 String16 s = chain->buildInspectorObjectImpl()->serialize(); |
| 882 m_asyncTaskCreatedStacks[task] = std::move(chain); |
| 883 registerAsyncTaskIfNeeded(task); |
| 884 } |
| 885 } |
| 886 |
860 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, | 887 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, |
861 bool recurring) { | 888 bool recurring) { |
862 if (!m_maxAsyncCallStackDepth) return; | 889 if (!m_maxAsyncCallStackDepth) return; |
863 asyncTaskScheduled(toString16(taskName), task, recurring); | 890 asyncTaskScheduled(toString16(taskName), task, recurring); |
864 } | 891 } |
865 | 892 |
866 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, | 893 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, |
867 bool recurring) { | 894 bool recurring) { |
868 if (!m_maxAsyncCallStackDepth) return; | 895 if (!m_maxAsyncCallStackDepth) return; |
869 v8::HandleScope scope(m_isolate); | 896 v8::HandleScope scope(m_isolate); |
870 int contextGroupId = | 897 int contextGroupId = |
871 m_isolate->InContext() | 898 m_isolate->InContext() |
872 ? m_inspector->contextGroupId(m_isolate->GetCurrentContext()) | 899 ? m_inspector->contextGroupId(m_isolate->GetCurrentContext()) |
873 : 0; | 900 : 0; |
| 901 auto itCreation = m_asyncTaskCreatedStacks.find(task); |
874 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture( | 902 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture( |
875 this, contextGroupId, V8StackTraceImpl::maxCallStackSizeToCapture, | 903 this, contextGroupId, V8StackTraceImpl::maxCallStackSizeToCapture, |
876 taskName); | 904 taskName, itCreation != m_asyncTaskCreatedStacks.end() |
| 905 ? itCreation->second->cloneImpl() |
| 906 : nullptr); |
877 if (chain) { | 907 if (chain) { |
878 m_asyncTaskStacks[task] = std::move(chain); | 908 m_asyncTaskStacks[task] = std::move(chain); |
879 if (recurring) m_recurringTasks.insert(task); | 909 if (recurring) m_recurringTasks.insert(task); |
880 int id = ++m_lastTaskId; | 910 registerAsyncTaskIfNeeded(task); |
881 m_taskToId[task] = id; | |
882 m_idToTask[id] = task; | |
883 if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) { | |
884 void* taskToRemove = m_idToTask.begin()->second; | |
885 asyncTaskCanceled(taskToRemove); | |
886 } | |
887 } | 911 } |
888 } | 912 } |
889 | 913 |
890 void V8Debugger::asyncTaskCanceled(void* task) { | 914 void V8Debugger::asyncTaskCanceled(void* task) { |
891 if (!m_maxAsyncCallStackDepth) return; | 915 if (!m_maxAsyncCallStackDepth) return; |
892 m_asyncTaskStacks.erase(task); | 916 m_asyncTaskStacks.erase(task); |
| 917 m_asyncTaskCreatedStacks.erase(task); |
893 m_recurringTasks.erase(task); | 918 m_recurringTasks.erase(task); |
894 auto it = m_taskToId.find(task); | 919 auto it = m_taskToId.find(task); |
895 if (it == m_taskToId.end()) return; | 920 if (it == m_taskToId.end()) return; |
896 m_idToTask.erase(it->second); | 921 m_idToTask.erase(it->second); |
897 m_taskToId.erase(it); | 922 m_taskToId.erase(it); |
898 } | 923 } |
899 | 924 |
900 void V8Debugger::asyncTaskStarted(void* task) { | 925 void V8Debugger::asyncTaskStarted(void* task) { |
901 if (!m_maxAsyncCallStackDepth) return; | 926 if (!m_maxAsyncCallStackDepth) return; |
902 m_currentTasks.push_back(task); | 927 m_currentTasks.push_back(task); |
(...skipping 15 matching lines...) Expand all Loading... |
918 if (!m_maxAsyncCallStackDepth) return; | 943 if (!m_maxAsyncCallStackDepth) return; |
919 // We could start instrumenting half way and the stack is empty. | 944 // We could start instrumenting half way and the stack is empty. |
920 if (!m_currentStacks.size()) return; | 945 if (!m_currentStacks.size()) return; |
921 | 946 |
922 DCHECK(m_currentTasks.back() == task); | 947 DCHECK(m_currentTasks.back() == task); |
923 m_currentTasks.pop_back(); | 948 m_currentTasks.pop_back(); |
924 | 949 |
925 m_currentStacks.pop_back(); | 950 m_currentStacks.pop_back(); |
926 if (m_recurringTasks.find(task) == m_recurringTasks.end()) { | 951 if (m_recurringTasks.find(task) == m_recurringTasks.end()) { |
927 m_asyncTaskStacks.erase(task); | 952 m_asyncTaskStacks.erase(task); |
| 953 m_asyncTaskCreatedStacks.erase(task); |
928 auto it = m_taskToId.find(task); | 954 auto it = m_taskToId.find(task); |
929 if (it == m_taskToId.end()) return; | 955 if (it == m_taskToId.end()) return; |
930 m_idToTask.erase(it->second); | 956 m_idToTask.erase(it->second); |
931 m_taskToId.erase(it); | 957 m_taskToId.erase(it); |
932 } | 958 } |
933 } | 959 } |
934 | 960 |
935 void V8Debugger::allAsyncTasksCanceled() { | 961 void V8Debugger::allAsyncTasksCanceled() { |
936 m_asyncTaskStacks.clear(); | 962 m_asyncTaskStacks.clear(); |
| 963 m_asyncTaskCreatedStacks.clear(); |
937 m_recurringTasks.clear(); | 964 m_recurringTasks.clear(); |
938 m_currentStacks.clear(); | 965 m_currentStacks.clear(); |
939 m_currentTasks.clear(); | 966 m_currentTasks.clear(); |
940 m_idToTask.clear(); | 967 m_idToTask.clear(); |
941 m_taskToId.clear(); | 968 m_taskToId.clear(); |
942 m_lastTaskId = 0; | 969 m_lastTaskId = 0; |
943 } | 970 } |
944 | 971 |
945 void V8Debugger::muteScriptParsedEvents() { | 972 void V8Debugger::muteScriptParsedEvents() { |
946 ++m_ignoreScriptParsedEventsCounter; | 973 ++m_ignoreScriptParsedEventsCounter; |
(...skipping 15 matching lines...) Expand all Loading... |
962 | 989 |
963 size_t stackSize = | 990 size_t stackSize = |
964 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; | 991 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; |
965 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) | 992 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) |
966 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; | 993 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; |
967 | 994 |
968 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); | 995 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); |
969 } | 996 } |
970 | 997 |
971 } // namespace v8_inspector | 998 } // namespace v8_inspector |
OLD | NEW |