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 895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
906 void V8Debugger::asyncTaskCanceledForStack(void* task) { | 906 void V8Debugger::asyncTaskCanceledForStack(void* task) { |
907 if (!m_maxAsyncCallStackDepth) return; | 907 if (!m_maxAsyncCallStackDepth) return; |
908 m_asyncTaskStacks.erase(task); | 908 m_asyncTaskStacks.erase(task); |
909 m_recurringTasks.erase(task); | 909 m_recurringTasks.erase(task); |
910 m_parentTask.erase(task); | 910 m_parentTask.erase(task); |
911 m_asyncTaskCreationStacks.erase(task); | 911 m_asyncTaskCreationStacks.erase(task); |
912 } | 912 } |
913 | 913 |
914 void V8Debugger::asyncTaskStartedForStack(void* task) { | 914 void V8Debugger::asyncTaskStartedForStack(void* task) { |
915 if (!m_maxAsyncCallStackDepth) return; | 915 if (!m_maxAsyncCallStackDepth) return; |
916 m_currentTasks.push_back(task); | |
917 auto parentIt = m_parentTask.find(task); | |
918 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find( | |
919 parentIt == m_parentTask.end() ? task : parentIt->second); | |
920 // Needs to support following order of events: | 916 // Needs to support following order of events: |
921 // - asyncTaskScheduled | 917 // - asyncTaskScheduled |
922 // <-- attached here --> | 918 // <-- attached here --> |
923 // - asyncTaskStarted | 919 // - asyncTaskStarted |
924 // - asyncTaskCanceled <-- canceled before finished | 920 // - asyncTaskCanceled <-- canceled before finished |
925 // <-- async stack requested here --> | 921 // <-- async stack requested here --> |
926 // - asyncTaskFinished | 922 // - asyncTaskFinished |
927 std::weak_ptr<AsyncStackTrace> asyncParent; | 923 m_currentTasks.push_back(task); |
928 if (stackIt != m_asyncTaskStacks.end()) asyncParent = stackIt->second; | 924 auto parentIt = m_parentTask.find(task); |
925 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find( | |
926 parentIt == m_parentTask.end() ? task : parentIt->second); | |
927 if (stackIt != m_asyncTaskStacks.end()) { | |
928 m_currentAsyncParent.push_back(stackIt->second.lock()); | |
929 } else { | |
930 m_currentAsyncParent.emplace_back(); | |
931 } | |
929 auto itCreation = m_asyncTaskCreationStacks.find(task); | 932 auto itCreation = m_asyncTaskCreationStacks.find(task); |
930 if (asyncParent.lock() && itCreation != m_asyncTaskCreationStacks.end()) { | 933 if (itCreation != m_asyncTaskCreationStacks.end()) { |
kozy
2017/04/27 18:35:31
this change is essential of this CL.
| |
931 m_currentAsyncCreation.push_back(itCreation->second.lock()); | 934 m_currentAsyncCreation.push_back(itCreation->second.lock()); |
932 } else { | 935 } else { |
933 m_currentAsyncCreation.emplace_back(); | 936 m_currentAsyncCreation.emplace_back(); |
934 } | 937 } |
935 m_currentAsyncParent.push_back(asyncParent.lock()); | |
936 } | 938 } |
937 | 939 |
938 void V8Debugger::asyncTaskFinishedForStack(void* task) { | 940 void V8Debugger::asyncTaskFinishedForStack(void* task) { |
939 if (!m_maxAsyncCallStackDepth) return; | 941 if (!m_maxAsyncCallStackDepth) return; |
940 // We could start instrumenting half way and the stack is empty. | 942 // We could start instrumenting half way and the stack is empty. |
941 if (!m_currentTasks.size()) return; | 943 if (!m_currentTasks.size()) return; |
942 DCHECK(m_currentTasks.back() == task); | 944 DCHECK(m_currentTasks.back() == task); |
943 m_currentTasks.pop_back(); | 945 m_currentTasks.pop_back(); |
944 | 946 |
945 DCHECK(m_currentAsyncParent.size() == m_currentAsyncCreation.size()); | 947 DCHECK(m_currentAsyncParent.size() == m_currentAsyncCreation.size()); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1032 } | 1034 } |
1033 cleanupExpiredWeakPointers(m_asyncTaskStacks); | 1035 cleanupExpiredWeakPointers(m_asyncTaskStacks); |
1034 cleanupExpiredWeakPointers(m_asyncTaskCreationStacks); | 1036 cleanupExpiredWeakPointers(m_asyncTaskCreationStacks); |
1035 for (auto it = m_recurringTasks.begin(); it != m_recurringTasks.end();) { | 1037 for (auto it = m_recurringTasks.begin(); it != m_recurringTasks.end();) { |
1036 if (m_asyncTaskStacks.find(*it) == m_asyncTaskStacks.end()) { | 1038 if (m_asyncTaskStacks.find(*it) == m_asyncTaskStacks.end()) { |
1037 it = m_recurringTasks.erase(it); | 1039 it = m_recurringTasks.erase(it); |
1038 } else { | 1040 } else { |
1039 ++it; | 1041 ++it; |
1040 } | 1042 } |
1041 } | 1043 } |
1044 // We use parent information to provide correct parent stack for promises, | |
1045 // Promise.resolve().then(...).then(...) | |
1046 // created task#1 - stack#1 | |
1047 // scheduled task#1 - stack#2 | |
1048 // created task#2 -> task#1 - stack#3 | |
1049 // created task#3 -> task#2 - stack#4 | |
1050 // ... | |
1051 // started task#2 - use stack(parent(task#2)) == stack(task#1) == stack#2 | |
1052 // ... | |
1053 // scheduled task#2 - stack#5 | |
dgozman
2017/04/27 17:26:34
scheduled after started?
kozy
2017/04/27 18:35:31
yes, it's how our promise instrumentation works an
| |
1054 // finished task#2 | |
1055 // started task#3 - use stack(parent(task#3)) == stack(task#2) == stack#5 | |
1056 // ... | |
1057 // scheduled task#3 - stack#6 | |
1058 // finished task#3 | |
1059 // Let's consider what parent link is obsolete when we collect stacks: | |
1060 // stack#1 - (task#2 -> task#1, task#3 -> task#2) | |
1061 // stack#2 - (task#3 -> task#2) | |
1062 // stack#3 - (task#3 -> task#2) | |
1063 // stack#4 - (task#3 -> task#2) | |
1064 // stack#5 - () | |
1065 // stack#6 - () | |
1066 // But in case when we start collecting stacks after getting stack#4 but | |
1067 // before stack#5 is added we should preserve parent link since original task | |
1068 // can be scheduled at any time in future and this link will be required to | |
1069 // get correct parent stack later. It means that we should collect parent link | |
1070 // in case when there is no creation or schedule stack for parent. | |
1042 for (auto it = m_parentTask.begin(); it != m_parentTask.end();) { | 1071 for (auto it = m_parentTask.begin(); it != m_parentTask.end();) { |
1043 if (m_asyncTaskCreationStacks.find(it->second) == | 1072 if (m_asyncTaskCreationStacks.find(it->second) == |
1044 m_asyncTaskCreationStacks.end()) { | 1073 m_asyncTaskCreationStacks.end() && |
1074 m_asyncTaskStacks.find(it->second) == m_asyncTaskStacks.end()) { | |
1045 it = m_parentTask.erase(it); | 1075 it = m_parentTask.erase(it); |
1046 } else { | 1076 } else { |
1047 ++it; | 1077 ++it; |
1048 } | 1078 } |
1049 } | 1079 } |
1050 cleanupExpiredWeakPointers(m_framesCache); | 1080 cleanupExpiredWeakPointers(m_framesCache); |
1051 } | 1081 } |
1052 | 1082 |
1053 std::shared_ptr<StackFrame> V8Debugger::symbolize( | 1083 std::shared_ptr<StackFrame> V8Debugger::symbolize( |
1054 v8::Local<v8::StackFrame> v8Frame) { | 1084 v8::Local<v8::StackFrame> v8Frame) { |
(...skipping 24 matching lines...) Expand all Loading... | |
1079 fprintf(stdout, "Async stacks count: %d\n", m_asyncStacksCount); | 1109 fprintf(stdout, "Async stacks count: %d\n", m_asyncStacksCount); |
1080 fprintf(stdout, "Scheduled async tasks: %zu\n", m_asyncTaskStacks.size()); | 1110 fprintf(stdout, "Scheduled async tasks: %zu\n", m_asyncTaskStacks.size()); |
1081 fprintf(stdout, "Created async tasks: %zu\n", | 1111 fprintf(stdout, "Created async tasks: %zu\n", |
1082 m_asyncTaskCreationStacks.size()); | 1112 m_asyncTaskCreationStacks.size()); |
1083 fprintf(stdout, "Async tasks with parent: %zu\n", m_parentTask.size()); | 1113 fprintf(stdout, "Async tasks with parent: %zu\n", m_parentTask.size()); |
1084 fprintf(stdout, "Recurring async tasks: %zu\n", m_recurringTasks.size()); | 1114 fprintf(stdout, "Recurring async tasks: %zu\n", m_recurringTasks.size()); |
1085 fprintf(stdout, "\n"); | 1115 fprintf(stdout, "\n"); |
1086 } | 1116 } |
1087 | 1117 |
1088 } // namespace v8_inspector | 1118 } // namespace v8_inspector |
OLD | NEW |