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

Unified Diff: third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp

Issue 1857713004: DevTools: simplify the async instrumentation harness. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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
Index: third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
index c039c1cfcaa2fa17eafda0bd727749556fba4898..ec799ee715b0ca71b704ef0b6e0ff13ba92b58a1 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
@@ -13,7 +13,6 @@
#include "platform/v8_inspector/MuteConsoleScope.h"
#include "platform/v8_inspector/RemoteObjectId.h"
#include "platform/v8_inspector/ScriptBreakpoint.h"
-#include "platform/v8_inspector/V8AsyncCallTracker.h"
#include "platform/v8_inspector/V8InspectorConnectionImpl.h"
#include "platform/v8_inspector/V8Regex.h"
#include "platform/v8_inspector/V8RuntimeAgentImpl.h"
@@ -36,6 +35,12 @@ using blink::protocol::Runtime::ScriptId;
using blink::protocol::Runtime::StackTrace;
using blink::protocol::Runtime::RemoteObject;
+namespace {
+static const char v8AsyncTaskEventEnqueue[] = "enqueue";
+static const char v8AsyncTaskEventWillHandle[] = "willHandle";
+static const char v8AsyncTaskEventDidHandle[] = "didHandle";
+}
+
namespace blink {
namespace DebuggerAgentState {
@@ -57,8 +62,6 @@ static const int maxSkipStepFrameCount = 128;
const char V8DebuggerAgent::backtraceObjectGroup[] = "backtrace";
-const int V8DebuggerAgent::unknownAsyncOperationId = 0;
-
static String16 breakpointIdSuffix(V8DebuggerAgentImpl::BreakpointSource source)
{
switch (source) {
@@ -177,17 +180,9 @@ V8DebuggerAgentImpl::V8DebuggerAgentImpl(V8InspectorConnectionImpl* connection,
, m_recursionLevelForStepOut(0)
, m_recursionLevelForStepFrame(0)
, m_skipAllPauses(false)
- , m_lastAsyncOperationId(0)
, m_maxAsyncCallStackDepth(0)
- , m_currentAsyncCallChain(nullptr)
- , m_nestedAsyncCallCount(0)
- , m_currentAsyncOperationId(unknownAsyncOperationId)
- , m_pendingTraceAsyncOperationCompleted(false)
{
m_connection->setDebuggerAgent(this);
-
- // FIXME: remove once InjectedScriptManager moves to v8.
- m_v8AsyncCallTracker = V8AsyncCallTracker::create(this);
clearBreakDetails();
}
@@ -263,11 +258,10 @@ void V8DebuggerAgentImpl::internalSetAsyncCallStackDepth(int depth)
{
if (depth <= 0) {
m_maxAsyncCallStackDepth = 0;
- resetAsyncCallTracker();
+ allAsyncTasksCanceled();
} else {
m_maxAsyncCallStackDepth = depth;
}
- m_v8AsyncCallTracker->asyncCallTrackingStateChanged(m_maxAsyncCallStackDepth);
}
void V8DebuggerAgentImpl::setInspectorState(protocol::DictionaryValue* state)
@@ -845,13 +839,22 @@ void V8DebuggerAgentImpl::cancelPauseOnNextStatement()
bool V8DebuggerAgentImpl::v8AsyncTaskEventsEnabled() const
{
- return trackingAsyncCalls();
+ return m_maxAsyncCallStackDepth;
}
void V8DebuggerAgentImpl::didReceiveV8AsyncTaskEvent(v8::Local<v8::Context> context, const String16& eventType, const String16& eventName, int id)
{
- ASSERT(trackingAsyncCalls());
- m_v8AsyncCallTracker->didReceiveV8AsyncTaskEvent(context, eventType, eventName, id);
+ ASSERT(m_maxAsyncCallStackDepth);
+ // The scopes for the ids are defined by the eventName namespaces. There are currently two namespaces: "Object." and "Promise.".
+ void* ptr = reinterpret_cast<void*>(id * 4 + (eventName[0] == 'P' ? 2 : 0) + 1);
+ if (eventType == v8AsyncTaskEventEnqueue)
+ asyncTaskScheduled(eventName, ptr, false);
+ else if (eventType == v8AsyncTaskEventWillHandle)
+ asyncTaskStarted(ptr);
+ else if (eventType == v8AsyncTaskEventDidHandle)
+ asyncTaskFinished(ptr);
+ else
+ ASSERT_NOT_REACHED();
}
void V8DebuggerAgentImpl::pause(ErrorString* errorString)
@@ -1049,98 +1052,64 @@ void V8DebuggerAgentImpl::setAsyncCallStackDepth(ErrorString* errorString, int d
internalSetAsyncCallStackDepth(depth);
}
-int V8DebuggerAgentImpl::traceAsyncOperationStarting(const String16& description)
+void V8DebuggerAgentImpl::asyncTaskScheduled(const String16& taskName, void* task, bool recurring)
{
+ if (!m_maxAsyncCallStackDepth)
+ return;
v8::HandleScope scope(m_isolate);
- OwnPtr<V8StackTraceImpl> chain = V8StackTraceImpl::capture(this, V8StackTrace::maxCallStackSizeToCapture, description);
-
- do {
- ++m_lastAsyncOperationId;
- if (m_lastAsyncOperationId <= 0)
- m_lastAsyncOperationId = 1;
- } while (m_asyncOperations.contains(m_lastAsyncOperationId));
-
- if (chain)
- m_asyncOperations.set(m_lastAsyncOperationId, chain.release());
-
- return m_lastAsyncOperationId;
-}
-
-void V8DebuggerAgentImpl::traceAsyncCallbackStarting(int operationId)
-{
- ASSERT(operationId > 0 || operationId == unknownAsyncOperationId);
- V8StackTraceImpl* chain = operationId > 0 ? m_asyncOperations.get(operationId) : nullptr;
- // FIXME: extract recursion check into a delegate.
- bool hasRecursionLevel = m_debugger->client()->hasRecursionLevel();
- if (chain && !hasRecursionLevel) {
- // There can be still an old m_currentAsyncCallChain set if we start running Microtasks
- // right after executing a JS callback but before the corresponding traceAsyncCallbackCompleted().
- // In this case just call traceAsyncCallbackCompleted() now, and the subsequent ones will be ignored.
- //
- // The nested levels count may be greater than 1, for example, when events are guarded via custom
- // traceAsync* calls, like in window.postMessage(). In this case there will be a willHandleEvent
- // instrumentation with unknownAsyncOperationId bumping up the nested levels count.
- if (m_currentAsyncCallChain) {
- ASSERT(m_nestedAsyncCallCount >= 1);
- m_nestedAsyncCallCount = 1;
- traceAsyncCallbackCompleted();
- }
-
- // Current AsyncCallChain corresponds to the bottommost JS call frame.
- ASSERT(!m_currentAsyncCallChain);
- m_currentAsyncCallChain = chain->clone();
- m_currentAsyncOperationId = operationId;
- m_pendingTraceAsyncOperationCompleted = false;
- m_nestedAsyncCallCount = 1;
- } else {
- if (m_currentAsyncCallChain)
- ++m_nestedAsyncCallCount;
+ OwnPtr<V8StackTraceImpl> chain = V8StackTraceImpl::capture(this, V8StackTrace::maxCallStackSizeToCapture, taskName);
+ if (chain) {
+ m_asyncTaskStacks.set(task, chain.release());
+ if (recurring)
+ m_recurringTasks.add(task);
}
}
-void V8DebuggerAgentImpl::traceAsyncCallbackCompleted()
+void V8DebuggerAgentImpl::asyncTaskCanceled(void* task)
{
- if (!m_nestedAsyncCallCount)
+ if (!m_maxAsyncCallStackDepth)
return;
- ASSERT(m_currentAsyncCallChain);
- --m_nestedAsyncCallCount;
- if (!m_nestedAsyncCallCount)
- clearCurrentAsyncOperation();
+ m_asyncTaskStacks.remove(task);
+ m_recurringTasks.remove(task);
}
-void V8DebuggerAgentImpl::traceAsyncOperationCompleted(int operationId)
+void V8DebuggerAgentImpl::asyncTaskStarted(void* task)
{
- ASSERT(operationId > 0 || operationId == unknownAsyncOperationId);
- if (operationId > 0) {
- if (m_currentAsyncOperationId == operationId) {
- if (m_pendingTraceAsyncOperationCompleted) {
- m_pendingTraceAsyncOperationCompleted = false;
- } else {
- // Delay traceAsyncOperationCompleted() until the last async callback (being currently executed) is done.
- m_pendingTraceAsyncOperationCompleted = true;
- return;
- }
- }
- m_asyncOperations.remove(operationId);
- }
+ // Not enabled, return.
+ if (!m_maxAsyncCallStackDepth)
+ return;
+ m_currentTasks.append(task);
+ V8StackTraceImpl* stack = m_asyncTaskStacks.get(task);
+ // Needs to support following order of events:
+ // - asyncTaskScheduled
+ // <-- attached here -->
+ // - asyncTaskStarted
+ // - asyncTaskCanceled <-- canceled before finished
dgozman 2016/04/06 16:04:11 This is surprising.
pfeldman 2016/04/06 18:25:19 var a = setInterval(function() { clearInterval(a);
+ // <-- async stack requested here -->
+ // - asyncTaskFinished
+ m_currentStacks.append(stack ? stack->clone() : nullptr);
}
-void V8DebuggerAgentImpl::clearCurrentAsyncOperation()
+void V8DebuggerAgentImpl::asyncTaskFinished(void* task)
{
- if (m_pendingTraceAsyncOperationCompleted && m_currentAsyncOperationId != unknownAsyncOperationId)
- traceAsyncOperationCompleted(m_currentAsyncOperationId);
-
- m_currentAsyncOperationId = unknownAsyncOperationId;
- m_pendingTraceAsyncOperationCompleted = false;
- m_nestedAsyncCallCount = 0;
- m_currentAsyncCallChain.clear();
+ if (!m_maxAsyncCallStackDepth)
+ return;
+ // We could start instrumenting half way and the stack is empty.
+ if (!m_currentTasks.size())
+ return;
+ ASSERT(m_currentTasks.last() == task);
dgozman 2016/04/06 16:04:12 Looks like we keep current tasks only for this ass
pfeldman 2016/04/06 18:25:19 Done.
+ m_currentTasks.removeLast();
+ m_currentStacks.removeLast();
+ if (!m_recurringTasks.contains(task))
+ m_asyncTaskStacks.remove(task);
}
-void V8DebuggerAgentImpl::resetAsyncCallTracker()
+void V8DebuggerAgentImpl::allAsyncTasksCanceled()
{
- clearCurrentAsyncOperation();
- m_v8AsyncCallTracker->resetAsyncOperations();
- m_asyncOperations.clear();
+ m_asyncTaskStacks.clear();
+ m_recurringTasks.clear();
+ m_currentTasks.clear();
+ m_currentStacks.clear();
}
void V8DebuggerAgentImpl::setBlackboxedRanges(ErrorString* error, const String16& scriptId, PassOwnPtr<protocol::Array<protocol::Debugger::ScriptPosition>> inPositions)
@@ -1292,15 +1261,17 @@ PassOwnPtr<Array<CallFrame>> V8DebuggerAgentImpl::currentCallFrames(ErrorString*
PassOwnPtr<StackTrace> V8DebuggerAgentImpl::currentAsyncStackTrace()
{
- if (m_pausedContext.IsEmpty() || !trackingAsyncCalls() || !m_currentAsyncCallChain)
+ if (m_pausedContext.IsEmpty() || !m_maxAsyncCallStackDepth || !m_currentStacks.size() || !m_currentStacks.last())
return nullptr;
- return m_currentAsyncCallChain->buildInspectorObjectForTail(this);
+ return m_currentStacks.last()->buildInspectorObjectForTail(this);
}
V8StackTraceImpl* V8DebuggerAgentImpl::currentAsyncCallChain()
{
- return trackingAsyncCalls() ? m_currentAsyncCallChain.get() : nullptr;
+ if (!m_currentStacks.size())
+ return nullptr;
+ return m_currentStacks.last().get();
}
void V8DebuggerAgentImpl::didParseSource(const V8DebuggerParsedScript& parsedScript)
@@ -1510,7 +1481,7 @@ void V8DebuggerAgentImpl::reset()
m_scripts.clear();
m_blackboxedPositions.clear();
m_breakpointIdToDebuggerBreakpointIds.clear();
- resetAsyncCallTracker();
+ allAsyncTasksCanceled();
}
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698