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 |