 Chromium Code Reviews
 Chromium Code Reviews Issue 2648873002:
  [inspector] added creation frame for async call chains for promises  (Closed)
    
  
    Issue 2648873002:
  [inspector] added creation frame for async call chains for promises  (Closed) 
  | 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 = | |
| 
dgozman
2017/01/24 23:57:44
chain -> creationStack
 
kozy
2017/01/25 00:45:43
Done.
 | |
| 880 V8StackTraceImpl::capture(this, 0, 1, String16()); | |
| 
dgozman
2017/01/24 23:57:44
Let's comment that passing 1 here force no async c
 
kozy
2017/01/25 00:45:43
Done.
 | |
| 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 |