Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(652)

Unified Diff: src/inspector/v8-debugger.cc

Issue 2825713002: Revert of [inspector] avoid cloning of async call chains (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/inspector/v8-debugger.h ('k') | src/inspector/v8-debugger-agent-impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/inspector/v8-debugger.cc
diff --git a/src/inspector/v8-debugger.cc b/src/inspector/v8-debugger.cc
index 91d37b10881db7939ce298a5fcd649988a841f85..3fa2061077435bc25ef3b223929f5c0fd096104d 100644
--- a/src/inspector/v8-debugger.cc
+++ b/src/inspector/v8-debugger.cc
@@ -21,7 +21,10 @@
namespace {
-static const int kMaxAsyncTaskStacks = 1024 * 1024;
+// Based on DevTools frontend measurement, with asyncCallStackDepth = 4,
+// average async call stack tail requires ~1 Kb. Let's reserve ~ 128 Mb
+// for async stacks.
+static const int kMaxAsyncTaskStacks = 128 * 1024;
inline v8::Local<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) {
return value ? v8::True(isolate) : v8::False(isolate);
@@ -164,6 +167,7 @@
m_runningNestedMessageLoop(false),
m_ignoreScriptParsedEventsCounter(0),
m_maxAsyncCallStacks(kMaxAsyncTaskStacks),
+ m_lastTaskId(0),
m_maxAsyncCallStackDepth(0),
m_pauseOnExceptionsState(v8::debug::NoBreakOnException),
m_wasmTranslation(isolate) {}
@@ -658,6 +662,10 @@
case v8::debug::kDebugEnqueuePromiseReject:
asyncTaskScheduledForStack("Promise.reject", task, true);
break;
+ case v8::debug::kDebugPromiseCollected:
+ asyncTaskCanceledForStack(task);
+ asyncTaskCanceledForStepping(task);
+ break;
case v8::debug::kDebugWillHandle:
asyncTaskStartedForStack(task);
asyncTaskStartedForStepping(task);
@@ -666,20 +674,17 @@
asyncTaskFinishedForStack(task);
asyncTaskFinishedForStepping(task);
break;
- case v8::debug::kDebugPromiseCollected:
- asyncTaskCanceledForStack(task);
- asyncTaskCanceledForStepping(task);
- break;
- }
-}
-
-std::shared_ptr<AsyncStackTrace> V8Debugger::currentAsyncParent() {
- return m_currentAsyncParent.empty() ? nullptr : m_currentAsyncParent.back();
-}
-
-std::shared_ptr<AsyncStackTrace> V8Debugger::currentAsyncCreation() {
- return m_currentAsyncCreation.empty() ? nullptr
- : m_currentAsyncCreation.back();
+ }
+}
+
+V8StackTraceImpl* V8Debugger::currentAsyncCallChain() {
+ if (!m_currentStacks.size()) return nullptr;
+ return m_currentStacks.back().get();
+}
+
+V8StackTraceImpl* V8Debugger::currentAsyncTaskCreationStack() {
+ if (!m_currentCreationStacks.size()) return nullptr;
+ return m_currentCreationStacks.back().get();
}
void V8Debugger::compileDebuggerScript() {
@@ -820,8 +825,8 @@
}
std::unique_ptr<V8StackTraceImpl> V8Debugger::createStackTrace(
- v8::Local<v8::StackTrace> v8StackTrace) {
- return V8StackTraceImpl::create(this, currentContextGroupId(), v8StackTrace,
+ v8::Local<v8::StackTrace> stackTrace) {
+ return V8StackTraceImpl::create(this, currentContextGroupId(), stackTrace,
V8StackTraceImpl::maxCallStackSizeToCapture);
}
@@ -842,18 +847,31 @@
if (!maxAsyncCallStackDepth) allAsyncTasksCanceled();
}
+void V8Debugger::registerAsyncTaskIfNeeded(void* task) {
+ if (m_taskToId.find(task) != m_taskToId.end()) return;
+
+ int id = ++m_lastTaskId;
+ m_taskToId[task] = id;
+ m_idToTask[id] = task;
+ if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) {
+ void* taskToRemove = m_idToTask.begin()->second;
+ asyncTaskCanceledForStack(taskToRemove);
+ }
+}
+
void V8Debugger::asyncTaskCreatedForStack(void* task, void* parentTask) {
if (!m_maxAsyncCallStackDepth) return;
if (parentTask) m_parentTask[task] = parentTask;
v8::HandleScope scope(m_isolate);
- std::shared_ptr<AsyncStackTrace> asyncCreation =
- AsyncStackTrace::capture(this, currentContextGroupId(), String16(), 1);
- // Passing one as maxStackSize forces no async chain for the new stack.
- if (asyncCreation && !asyncCreation->isEmpty()) {
- m_asyncTaskCreationStacks[task] = asyncCreation;
- m_allAsyncStacks.push_back(asyncCreation);
- ++m_asyncStacksCount;
- collectOldAsyncStacksIfNeeded();
+ // We don't need to pass context group id here because we get this callback
+ // from V8 for promise events only.
+ // Passing one as maxStackSize forces no async chain for the new stack and
+ // allows us to not grow exponentially.
+ std::unique_ptr<V8StackTraceImpl> creationStack =
+ V8StackTraceImpl::capture(this, 0, 1, String16());
+ if (creationStack && !creationStack->isEmpty()) {
+ m_asyncTaskCreationStacks[task] = std::move(creationStack);
+ registerAsyncTaskIfNeeded(task);
}
}
@@ -882,16 +900,13 @@
void* task, bool recurring) {
if (!m_maxAsyncCallStackDepth) return;
v8::HandleScope scope(m_isolate);
- std::shared_ptr<AsyncStackTrace> asyncStack =
- AsyncStackTrace::capture(this, currentContextGroupId(), taskName,
- V8StackTraceImpl::maxCallStackSizeToCapture);
- if (asyncStack) {
- m_asyncTaskStacks[task] = asyncStack;
+ std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture(
+ this, currentContextGroupId(),
+ V8StackTraceImpl::maxCallStackSizeToCapture, taskName);
+ if (chain) {
+ m_asyncTaskStacks[task] = std::move(chain);
if (recurring) m_recurringTasks.insert(task);
-
- m_allAsyncStacks.push_back(asyncStack);
- ++m_asyncStacksCount;
- collectOldAsyncStacksIfNeeded();
+ registerAsyncTaskIfNeeded(task);
}
}
@@ -901,6 +916,10 @@
m_recurringTasks.erase(task);
m_parentTask.erase(task);
m_asyncTaskCreationStacks.erase(task);
+ auto it = m_taskToId.find(task);
+ if (it == m_taskToId.end()) return;
+ m_idToTask.erase(it->second);
+ m_taskToId.erase(it);
}
void V8Debugger::asyncTaskStartedForStack(void* task) {
@@ -916,28 +935,28 @@
// - asyncTaskCanceled <-- canceled before finished
// <-- async stack requested here -->
// - asyncTaskFinished
- std::shared_ptr<AsyncStackTrace> asyncParent;
- if (stackIt != m_asyncTaskStacks.end()) asyncParent = stackIt->second.lock();
+ std::unique_ptr<V8StackTraceImpl> stack;
+ if (stackIt != m_asyncTaskStacks.end() && stackIt->second)
+ stack = stackIt->second->cloneImpl();
auto itCreation = m_asyncTaskCreationStacks.find(task);
- if (asyncParent && itCreation != m_asyncTaskCreationStacks.end()) {
- m_currentAsyncCreation.push_back(itCreation->second.lock());
+ if (stack && itCreation != m_asyncTaskCreationStacks.end()) {
+ m_currentCreationStacks.push_back(itCreation->second->cloneImpl());
} else {
- m_currentAsyncCreation.push_back(nullptr);
- }
- m_currentAsyncParent.push_back(asyncParent);
+ m_currentCreationStacks.push_back(nullptr);
+ }
+ m_currentStacks.push_back(std::move(stack));
}
void V8Debugger::asyncTaskFinishedForStack(void* task) {
if (!m_maxAsyncCallStackDepth) return;
// We could start instrumenting half way and the stack is empty.
- if (!m_currentTasks.size()) return;
+ if (!m_currentStacks.size()) return;
DCHECK(m_currentTasks.back() == task);
m_currentTasks.pop_back();
- DCHECK(m_currentAsyncParent.size() == m_currentAsyncCreation.size());
- m_currentAsyncParent.pop_back();
- m_currentAsyncCreation.pop_back();
-
+ DCHECK(m_currentStacks.size() == m_currentCreationStacks.size());
+ m_currentStacks.pop_back();
+ m_currentCreationStacks.pop_back();
if (m_recurringTasks.find(task) == m_recurringTasks.end()) {
asyncTaskCanceledForStack(task);
}
@@ -974,14 +993,14 @@
void V8Debugger::allAsyncTasksCanceled() {
m_asyncTaskStacks.clear();
m_recurringTasks.clear();
- m_currentAsyncParent.clear();
- m_currentAsyncCreation.clear();
+ m_currentStacks.clear();
+ m_currentCreationStacks.clear();
m_currentTasks.clear();
m_parentTask.clear();
m_asyncTaskCreationStacks.clear();
-
- m_allAsyncStacks.clear();
- m_asyncStacksCount = 0;
+ m_idToTask.clear();
+ m_taskToId.clear();
+ m_lastTaskId = 0;
}
void V8Debugger::muteScriptParsedEvents() {
@@ -1001,10 +1020,11 @@
int contextGroupId = currentContextGroupId();
if (!contextGroupId) return nullptr;
- int stackSize = 1;
- if (fullStack || m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) {
+ size_t stackSize =
+ fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1;
+ if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId))
stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
- }
+
return V8StackTraceImpl::capture(this, contextGroupId, stackSize);
}
@@ -1013,30 +1033,4 @@
return m_inspector->contextGroupId(m_isolate->GetCurrentContext());
}
-void V8Debugger::collectOldAsyncStacksIfNeeded() {
- if (m_asyncStacksCount <= m_maxAsyncCallStacks) return;
- int halfOfLimitRoundedUp =
- m_maxAsyncCallStacks / 2 + m_maxAsyncCallStacks % 2;
- while (m_asyncStacksCount > halfOfLimitRoundedUp) {
- m_allAsyncStacks.pop_front();
- --m_asyncStacksCount;
- }
- removeOldAsyncTasks(m_asyncTaskStacks);
- removeOldAsyncTasks(m_asyncTaskCreationStacks);
-}
-
-void V8Debugger::removeOldAsyncTasks(AsyncTaskToStackTrace& map) {
- AsyncTaskToStackTrace cleanCopy;
- for (auto it : map) {
- if (!it.second.expired()) cleanCopy.insert(it);
- }
- map.swap(cleanCopy);
-}
-
-void V8Debugger::setMaxAsyncTaskStacksForTest(int limit) {
- m_maxAsyncCallStacks = 0;
- collectOldAsyncStacksIfNeeded();
- m_maxAsyncCallStacks = limit;
-}
-
} // namespace v8_inspector
« no previous file with comments | « src/inspector/v8-debugger.h ('k') | src/inspector/v8-debugger-agent-impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698