Chromium Code Reviews| 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" |
| 11 #include "src/inspector/string-util.h" | 11 #include "src/inspector/string-util.h" |
| 12 #include "src/inspector/v8-debugger-agent-impl.h" | 12 #include "src/inspector/v8-debugger-agent-impl.h" |
| 13 #include "src/inspector/v8-inspector-impl.h" | 13 #include "src/inspector/v8-inspector-impl.h" |
| 14 #include "src/inspector/v8-internal-value-type.h" | 14 #include "src/inspector/v8-internal-value-type.h" |
| 15 #include "src/inspector/v8-stack-trace-impl.h" | 15 #include "src/inspector/v8-stack-trace-impl.h" |
| 16 #include "src/inspector/v8-value-copier.h" | 16 #include "src/inspector/v8-value-copier.h" |
| 17 | 17 |
| 18 #include "include/v8-util.h" | 18 #include "include/v8-util.h" |
| 19 | 19 |
| 20 namespace v8_inspector { | 20 namespace v8_inspector { |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 static const int kMaxAsyncTaskStacks = 1024 * 1024; | 24 static const int kMaxAsyncTaskStacks = 128 * 1024; |
| 25 | 25 |
| 26 inline v8::Local<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) { | 26 inline v8::Local<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) { |
| 27 return value ? v8::True(isolate) : v8::False(isolate); | 27 return value ? v8::True(isolate) : v8::False(isolate); |
| 28 } | 28 } |
| 29 | 29 |
| 30 V8DebuggerAgentImpl* agentForScript(V8InspectorImpl* inspector, | 30 V8DebuggerAgentImpl* agentForScript(V8InspectorImpl* inspector, |
| 31 v8::Local<v8::debug::Script> script) { | 31 v8::Local<v8::debug::Script> script) { |
| 32 v8::Local<v8::Value> contextData; | 32 v8::Local<v8::Value> contextData; |
| 33 if (!script->ContextData().ToLocal(&contextData) || !contextData->IsInt32()) { | 33 if (!script->ContextData().ToLocal(&contextData) || !contextData->IsInt32()) { |
| 34 return nullptr; | 34 return nullptr; |
| (...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 844 | 844 |
| 845 void V8Debugger::asyncTaskCreatedForStack(void* task, void* parentTask) { | 845 void V8Debugger::asyncTaskCreatedForStack(void* task, void* parentTask) { |
| 846 if (!m_maxAsyncCallStackDepth) return; | 846 if (!m_maxAsyncCallStackDepth) return; |
| 847 if (parentTask) m_parentTask[task] = parentTask; | 847 if (parentTask) m_parentTask[task] = parentTask; |
| 848 v8::HandleScope scope(m_isolate); | 848 v8::HandleScope scope(m_isolate); |
| 849 std::shared_ptr<AsyncStackTrace> asyncCreation = | 849 std::shared_ptr<AsyncStackTrace> asyncCreation = |
| 850 AsyncStackTrace::capture(this, currentContextGroupId(), String16(), 1); | 850 AsyncStackTrace::capture(this, currentContextGroupId(), String16(), 1); |
| 851 // Passing one as maxStackSize forces no async chain for the new stack. | 851 // Passing one as maxStackSize forces no async chain for the new stack. |
| 852 if (asyncCreation && !asyncCreation->isEmpty()) { | 852 if (asyncCreation && !asyncCreation->isEmpty()) { |
| 853 m_asyncTaskCreationStacks[task] = asyncCreation; | 853 m_asyncTaskCreationStacks[task] = asyncCreation; |
| 854 m_allAsyncStacks.push_back(asyncCreation); | 854 m_allAsyncStacks.push_back(std::move(asyncCreation)); |
| 855 ++m_asyncStacksCount; | 855 ++m_asyncStacksCount; |
| 856 collectOldAsyncStacksIfNeeded(); | 856 collectOldAsyncStacksIfNeeded(); |
| 857 } | 857 } |
| 858 } | 858 } |
| 859 | 859 |
| 860 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, | 860 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, |
| 861 bool recurring) { | 861 bool recurring) { |
| 862 asyncTaskScheduledForStack(toString16(taskName), task, recurring); | 862 asyncTaskScheduledForStack(toString16(taskName), task, recurring); |
| 863 asyncTaskCandidateForStepping(task); | 863 asyncTaskCandidateForStepping(task); |
| 864 } | 864 } |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 881 void V8Debugger::asyncTaskScheduledForStack(const String16& taskName, | 881 void V8Debugger::asyncTaskScheduledForStack(const String16& taskName, |
| 882 void* task, bool recurring) { | 882 void* task, bool recurring) { |
| 883 if (!m_maxAsyncCallStackDepth) return; | 883 if (!m_maxAsyncCallStackDepth) return; |
| 884 v8::HandleScope scope(m_isolate); | 884 v8::HandleScope scope(m_isolate); |
| 885 std::shared_ptr<AsyncStackTrace> asyncStack = | 885 std::shared_ptr<AsyncStackTrace> asyncStack = |
| 886 AsyncStackTrace::capture(this, currentContextGroupId(), taskName, | 886 AsyncStackTrace::capture(this, currentContextGroupId(), taskName, |
| 887 V8StackTraceImpl::maxCallStackSizeToCapture); | 887 V8StackTraceImpl::maxCallStackSizeToCapture); |
| 888 if (asyncStack) { | 888 if (asyncStack) { |
| 889 m_asyncTaskStacks[task] = asyncStack; | 889 m_asyncTaskStacks[task] = asyncStack; |
| 890 if (recurring) m_recurringTasks.insert(task); | 890 if (recurring) m_recurringTasks.insert(task); |
| 891 | 891 m_allAsyncStacks.push_back(std::move(asyncStack)); |
| 892 m_allAsyncStacks.push_back(asyncStack); | |
| 893 ++m_asyncStacksCount; | 892 ++m_asyncStacksCount; |
| 894 collectOldAsyncStacksIfNeeded(); | 893 collectOldAsyncStacksIfNeeded(); |
| 895 } | 894 } |
| 896 } | 895 } |
| 897 | 896 |
| 898 void V8Debugger::asyncTaskCanceledForStack(void* task) { | 897 void V8Debugger::asyncTaskCanceledForStack(void* task) { |
| 899 if (!m_maxAsyncCallStackDepth) return; | 898 if (!m_maxAsyncCallStackDepth) return; |
| 900 m_asyncTaskStacks.erase(task); | 899 m_asyncTaskStacks.erase(task); |
| 901 m_recurringTasks.erase(task); | 900 m_recurringTasks.erase(task); |
| 902 m_parentTask.erase(task); | 901 m_parentTask.erase(task); |
| 903 m_asyncTaskCreationStacks.erase(task); | 902 m_asyncTaskCreationStacks.erase(task); |
| 904 } | 903 } |
| 905 | 904 |
| 906 void V8Debugger::asyncTaskStartedForStack(void* task) { | 905 void V8Debugger::asyncTaskStartedForStack(void* task) { |
| 907 if (!m_maxAsyncCallStackDepth) return; | 906 if (!m_maxAsyncCallStackDepth) return; |
| 908 m_currentTasks.push_back(task); | 907 m_currentTasks.push_back(task); |
| 909 auto parentIt = m_parentTask.find(task); | 908 auto parentIt = m_parentTask.find(task); |
| 910 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find( | 909 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find( |
| 911 parentIt == m_parentTask.end() ? task : parentIt->second); | 910 parentIt == m_parentTask.end() ? task : parentIt->second); |
| 912 // Needs to support following order of events: | 911 // Needs to support following order of events: |
| 913 // - asyncTaskScheduled | 912 // - asyncTaskScheduled |
| 914 // <-- attached here --> | 913 // <-- attached here --> |
| 915 // - asyncTaskStarted | 914 // - asyncTaskStarted |
| 916 // - asyncTaskCanceled <-- canceled before finished | 915 // - asyncTaskCanceled <-- canceled before finished |
| 917 // <-- async stack requested here --> | 916 // <-- async stack requested here --> |
| 918 // - asyncTaskFinished | 917 // - asyncTaskFinished |
| 919 std::shared_ptr<AsyncStackTrace> asyncParent; | 918 std::weak_ptr<AsyncStackTrace> asyncParent; |
| 920 if (stackIt != m_asyncTaskStacks.end()) asyncParent = stackIt->second.lock(); | 919 if (stackIt != m_asyncTaskStacks.end()) asyncParent = stackIt->second; |
| 921 auto itCreation = m_asyncTaskCreationStacks.find(task); | 920 auto itCreation = m_asyncTaskCreationStacks.find(task); |
| 922 if (asyncParent && itCreation != m_asyncTaskCreationStacks.end()) { | 921 if (asyncParent.lock() && itCreation != m_asyncTaskCreationStacks.end()) { |
| 923 m_currentAsyncCreation.push_back(itCreation->second.lock()); | 922 m_currentAsyncCreation.push_back(itCreation->second.lock()); |
| 924 } else { | 923 } else { |
| 925 m_currentAsyncCreation.push_back(nullptr); | 924 m_currentAsyncCreation.emplace_back(); |
| 926 } | 925 } |
| 927 m_currentAsyncParent.push_back(asyncParent); | 926 m_currentAsyncParent.push_back(asyncParent.lock()); |
| 928 } | 927 } |
| 929 | 928 |
| 930 void V8Debugger::asyncTaskFinishedForStack(void* task) { | 929 void V8Debugger::asyncTaskFinishedForStack(void* task) { |
| 931 if (!m_maxAsyncCallStackDepth) return; | 930 if (!m_maxAsyncCallStackDepth) return; |
| 932 // We could start instrumenting half way and the stack is empty. | 931 // We could start instrumenting half way and the stack is empty. |
| 933 if (!m_currentTasks.size()) return; | 932 if (!m_currentTasks.size()) return; |
| 934 DCHECK(m_currentTasks.back() == task); | 933 DCHECK(m_currentTasks.back() == task); |
| 935 m_currentTasks.pop_back(); | 934 m_currentTasks.pop_back(); |
| 936 | 935 |
| 937 DCHECK(m_currentAsyncParent.size() == m_currentAsyncCreation.size()); | 936 DCHECK(m_currentAsyncParent.size() == m_currentAsyncCreation.size()); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1016 void V8Debugger::collectOldAsyncStacksIfNeeded() { | 1015 void V8Debugger::collectOldAsyncStacksIfNeeded() { |
| 1017 if (m_asyncStacksCount <= m_maxAsyncCallStacks) return; | 1016 if (m_asyncStacksCount <= m_maxAsyncCallStacks) return; |
| 1018 int halfOfLimitRoundedUp = | 1017 int halfOfLimitRoundedUp = |
| 1019 m_maxAsyncCallStacks / 2 + m_maxAsyncCallStacks % 2; | 1018 m_maxAsyncCallStacks / 2 + m_maxAsyncCallStacks % 2; |
| 1020 while (m_asyncStacksCount > halfOfLimitRoundedUp) { | 1019 while (m_asyncStacksCount > halfOfLimitRoundedUp) { |
| 1021 m_allAsyncStacks.pop_front(); | 1020 m_allAsyncStacks.pop_front(); |
| 1022 --m_asyncStacksCount; | 1021 --m_asyncStacksCount; |
| 1023 } | 1022 } |
| 1024 removeOldAsyncTasks(m_asyncTaskStacks); | 1023 removeOldAsyncTasks(m_asyncTaskStacks); |
| 1025 removeOldAsyncTasks(m_asyncTaskCreationStacks); | 1024 removeOldAsyncTasks(m_asyncTaskCreationStacks); |
| 1025 protocol::HashSet<void*> recurringLeft; | |
| 1026 for (auto task : m_recurringTasks) { | |
| 1027 if (m_asyncTaskStacks.find(task) == m_asyncTaskStacks.end()) continue; | |
| 1028 recurringLeft.insert(task); | |
| 1029 } | |
| 1030 m_recurringTasks.swap(recurringLeft); | |
| 1031 protocol::HashMap<void*, void*> parentLeft; | |
| 1032 for (auto it : m_parentTask) { | |
| 1033 if (m_asyncTaskCreationStacks.find(it.second) == m_asyncTaskStacks.end()) { | |
|
dgozman
2017/04/20 00:42:23
You are comparing iterator from one map to another
kozy
2017/04/20 00:59:02
C++ is my best friend since it allows it :)
fixed:
| |
| 1034 continue; | |
| 1035 } | |
| 1036 parentLeft.insert(it); | |
| 1037 } | |
| 1038 m_parentTask.swap(parentLeft); | |
| 1026 } | 1039 } |
| 1027 | 1040 |
| 1028 void V8Debugger::removeOldAsyncTasks(AsyncTaskToStackTrace& map) { | 1041 void V8Debugger::removeOldAsyncTasks(AsyncTaskToStackTrace& map) { |
| 1029 AsyncTaskToStackTrace cleanCopy; | 1042 AsyncTaskToStackTrace cleanCopy; |
| 1030 for (auto it : map) { | 1043 for (auto it : map) { |
| 1031 if (!it.second.expired()) cleanCopy.insert(it); | 1044 if (!it.second.expired()) cleanCopy.insert(it); |
| 1032 } | 1045 } |
| 1033 map.swap(cleanCopy); | 1046 map.swap(cleanCopy); |
| 1034 } | 1047 } |
| 1035 | 1048 |
| 1036 void V8Debugger::setMaxAsyncTaskStacksForTest(int limit) { | 1049 void V8Debugger::setMaxAsyncTaskStacksForTest(int limit) { |
| 1037 m_maxAsyncCallStacks = 0; | 1050 m_maxAsyncCallStacks = 0; |
| 1038 collectOldAsyncStacksIfNeeded(); | 1051 collectOldAsyncStacksIfNeeded(); |
| 1039 m_maxAsyncCallStacks = limit; | 1052 m_maxAsyncCallStacks = limit; |
| 1040 } | 1053 } |
| 1041 | 1054 |
| 1042 } // namespace v8_inspector | 1055 } // namespace v8_inspector |
| OLD | NEW |