diff options
author | Michaël Zasso <targos@protonmail.com> | 2019-11-08 15:39:11 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2019-11-08 15:46:25 +0100 |
commit | 6ca81ad72a3c6fdf16c683335be748f22aaa9a0d (patch) | |
tree | 33c8ee75f729aed76c2c0b89c63f9bf1b4dd66aa /deps/v8/src/inspector/v8-debugger.cc | |
parent | 1eee0b8bf8bba39b600fb16a9223e545e3bac2bc (diff) | |
download | android-node-v8-6ca81ad72a3c6fdf16c683335be748f22aaa9a0d.tar.gz android-node-v8-6ca81ad72a3c6fdf16c683335be748f22aaa9a0d.tar.bz2 android-node-v8-6ca81ad72a3c6fdf16c683335be748f22aaa9a0d.zip |
deps: update V8 to 7.9.317.20
PR-URL: https://github.com/nodejs/node/pull/30020
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'deps/v8/src/inspector/v8-debugger.cc')
-rw-r--r-- | deps/v8/src/inspector/v8-debugger.cc | 226 |
1 files changed, 121 insertions, 105 deletions
diff --git a/deps/v8/src/inspector/v8-debugger.cc b/deps/v8/src/inspector/v8-debugger.cc index 5ddc375a80..bd127b2c1c 100644 --- a/deps/v8/src/inspector/v8-debugger.cc +++ b/deps/v8/src/inspector/v8-debugger.cc @@ -64,6 +64,42 @@ class MatchPrototypePredicate : public v8::debug::QueryObjectPredicate { } // namespace +V8DebuggerId::V8DebuggerId(std::pair<int64_t, int64_t> pair) + : m_first(pair.first), m_second(pair.second) {} + +// static +V8DebuggerId V8DebuggerId::generate(v8::Isolate* isolate) { + V8DebuggerId debuggerId; + debuggerId.m_first = v8::debug::GetNextRandomInt64(isolate); + debuggerId.m_second = v8::debug::GetNextRandomInt64(isolate); + if (!debuggerId.m_first && !debuggerId.m_second) ++debuggerId.m_first; + return debuggerId; +} + +V8DebuggerId::V8DebuggerId(const String16& debuggerId) { + const UChar dot = '.'; + size_t pos = debuggerId.find(dot); + if (pos == String16::kNotFound) return; + bool ok = false; + int64_t first = debuggerId.substring(0, pos).toInteger64(&ok); + if (!ok) return; + int64_t second = debuggerId.substring(pos + 1).toInteger64(&ok); + if (!ok) return; + m_first = first; + m_second = second; +} + +String16 V8DebuggerId::toString() const { + return String16::fromInteger64(m_first) + "." + + String16::fromInteger64(m_second); +} + +bool V8DebuggerId::isValid() const { return m_first || m_second; } + +std::pair<int64_t, int64_t> V8DebuggerId::pair() const { + return std::make_pair(m_first, m_second); +} + V8Debugger::V8Debugger(v8::Isolate* isolate, V8InspectorImpl* inspector) : m_isolate(isolate), m_inspector(inspector), @@ -107,7 +143,9 @@ void V8Debugger::disable() { if (--m_enableCount) return; clearContinueToLocation(); m_taskWithScheduledBreak = nullptr; - m_taskWithScheduledBreakDebuggerId = String16(); + m_externalAsyncTaskPauseRequested = false; + m_taskWithScheduledBreakPauseRequested = false; + m_pauseOnNextCallRequested = false; m_pauseOnAsyncCall = false; m_wasmTranslation.Clear(); v8::debug::SetDebugDelegate(m_isolate, nullptr); @@ -171,12 +209,19 @@ void V8Debugger::setPauseOnNextCall(bool pause, int targetContextGroupId) { m_targetContextGroupId != targetContextGroupId) { return; } - m_targetContextGroupId = targetContextGroupId; - m_breakRequested = pause; - if (pause) - v8::debug::SetBreakOnNextFunctionCall(m_isolate); - else - v8::debug::ClearBreakOnNextFunctionCall(m_isolate); + if (pause) { + bool didHaveBreak = hasScheduledBreakOnNextFunctionCall(); + m_pauseOnNextCallRequested = true; + if (!didHaveBreak) { + m_targetContextGroupId = targetContextGroupId; + v8::debug::SetBreakOnNextFunctionCall(m_isolate); + } + } else { + m_pauseOnNextCallRequested = false; + if (!hasScheduledBreakOnNextFunctionCall()) { + v8::debug::ClearBreakOnNextFunctionCall(m_isolate); + } + } } bool V8Debugger::canBreakProgram() { @@ -275,21 +320,12 @@ bool V8Debugger::asyncStepOutOfFunction(int targetContextGroupId, void* parentTask = std::shared_ptr<AsyncStackTrace>(parent)->suspendedTaskId(); if (!parentTask) return false; - pauseOnAsyncCall(targetContextGroupId, - reinterpret_cast<uintptr_t>(parentTask), String16()); + m_targetContextGroupId = targetContextGroupId; + m_taskWithScheduledBreak = parentTask; continueProgram(targetContextGroupId); return true; } -void V8Debugger::pauseOnAsyncCall(int targetContextGroupId, uintptr_t task, - const String16& debuggerId) { - DCHECK(targetContextGroupId); - m_targetContextGroupId = targetContextGroupId; - - m_taskWithScheduledBreak = reinterpret_cast<void*>(task); - m_taskWithScheduledBreakDebuggerId = debuggerId; -} - void V8Debugger::terminateExecution( std::unique_ptr<TerminateExecutionCallback> callback) { if (m_terminateExecutionCallback) { @@ -390,10 +426,11 @@ void V8Debugger::handleProgramBreak( return; } m_targetContextGroupId = 0; - m_breakRequested = false; + m_pauseOnNextCallRequested = false; m_pauseOnAsyncCall = false; m_taskWithScheduledBreak = nullptr; - m_taskWithScheduledBreakDebuggerId = String16(); + m_externalAsyncTaskPauseRequested = false; + m_taskWithScheduledBreakPauseRequested = false; bool scheduledOOMBreak = m_scheduledOOMBreak; bool scheduledAssertBreak = m_scheduledAssertBreak; @@ -470,31 +507,30 @@ size_t V8Debugger::nearHeapLimitCallback(void* data, size_t current_heap_limit, void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script, bool is_live_edited, bool has_compile_error) { + if (m_ignoreScriptParsedEventsCounter != 0) return; + int contextId; if (!script->ContextId().To(&contextId)) return; - if (script->IsWasm() && script->SourceMappingURL().IsEmpty()) { - WasmTranslation* wasmTranslation = &m_wasmTranslation; - m_inspector->forEachSession( - m_inspector->contextGroupId(contextId), - [&script, &wasmTranslation](V8InspectorSessionImpl* session) { - if (!session->debuggerAgent()->enabled()) return; - wasmTranslation->AddScript(script.As<v8::debug::WasmScript>(), - session->debuggerAgent()); - }); - } else if (m_ignoreScriptParsedEventsCounter == 0) { - v8::Isolate* isolate = m_isolate; - V8InspectorClient* client = m_inspector->client(); - m_inspector->forEachSession( - m_inspector->contextGroupId(contextId), - [&isolate, &script, &has_compile_error, &is_live_edited, - &client](V8InspectorSessionImpl* session) { - if (!session->debuggerAgent()->enabled()) return; - session->debuggerAgent()->didParseSource( - V8DebuggerScript::Create(isolate, script, is_live_edited, - session->debuggerAgent(), client), + + v8::Isolate* isolate = m_isolate; + V8InspectorClient* client = m_inspector->client(); + WasmTranslation& wasmTranslation = m_wasmTranslation; + + m_inspector->forEachSession( + m_inspector->contextGroupId(contextId), + [isolate, &script, has_compile_error, is_live_edited, client, + &wasmTranslation](V8InspectorSessionImpl* session) { + auto agent = session->debuggerAgent(); + if (!agent->enabled()) return; + if (script->IsWasm() && script->SourceMappingURL().IsEmpty()) { + wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(), agent); + } else { + agent->didParseSource( + V8DebuggerScript::Create(isolate, script, is_live_edited, agent, + client), !has_compile_error); - }); - } + } + }); } void V8Debugger::BreakProgramRequested( @@ -540,15 +576,15 @@ void V8Debugger::AsyncEventOccurred(v8::debug::DebugAsyncActionType type, switch (type) { case v8::debug::kDebugPromiseThen: asyncTaskScheduledForStack("Promise.then", task, false); - if (!isBlackboxed) asyncTaskCandidateForStepping(task, true); + if (!isBlackboxed) asyncTaskCandidateForStepping(task); break; case v8::debug::kDebugPromiseCatch: asyncTaskScheduledForStack("Promise.catch", task, false); - if (!isBlackboxed) asyncTaskCandidateForStepping(task, true); + if (!isBlackboxed) asyncTaskCandidateForStepping(task); break; case v8::debug::kDebugPromiseFinally: asyncTaskScheduledForStack("Promise.finally", task, false); - if (!isBlackboxed) asyncTaskCandidateForStepping(task, true); + if (!isBlackboxed) asyncTaskCandidateForStepping(task); break; case v8::debug::kDebugWillHandle: asyncTaskStartedForStack(task); @@ -786,7 +822,7 @@ void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) { std::shared_ptr<AsyncStackTrace> V8Debugger::stackTraceFor( int contextGroupId, const V8StackTraceId& id) { - if (debuggerIdFor(contextGroupId) != id.debugger_id) return nullptr; + if (debuggerIdFor(contextGroupId).pair() != id.debugger_id) return nullptr; auto it = m_storedStackTraces.find(id.id); if (it == m_storedStackTraces.end()) return nullptr; return it->second.lock(); @@ -811,9 +847,13 @@ V8StackTraceId V8Debugger::storeCurrentStackTrace( ++m_asyncStacksCount; collectOldAsyncStacksIfNeeded(); - asyncTaskCandidateForStepping(reinterpret_cast<void*>(id), false); - - return V8StackTraceId(id, debuggerIdFor(contextGroupId)); + bool shouldPause = + m_pauseOnAsyncCall && contextGroupId == m_targetContextGroupId; + if (shouldPause) { + m_pauseOnAsyncCall = false; + v8::debug::ClearStepping(m_isolate); // Cancel step into. + } + return V8StackTraceId(id, debuggerIdFor(contextGroupId).pair(), shouldPause); } uintptr_t V8Debugger::storeStackTrace( @@ -829,13 +869,12 @@ void V8Debugger::externalAsyncTaskStarted(const V8StackTraceId& parent) { m_currentAsyncParent.emplace_back(); m_currentTasks.push_back(reinterpret_cast<void*>(parent.id)); - if (m_breakRequested) return; - if (!m_taskWithScheduledBreakDebuggerId.isEmpty() && - reinterpret_cast<uintptr_t>(m_taskWithScheduledBreak) == parent.id && - m_taskWithScheduledBreakDebuggerId == - debuggerIdToString(parent.debugger_id)) { - v8::debug::SetBreakOnNextFunctionCall(m_isolate); - } + if (!parent.should_pause) return; + bool didHaveBreak = hasScheduledBreakOnNextFunctionCall(); + m_externalAsyncTaskPauseRequested = true; + if (didHaveBreak) return; + m_targetContextGroupId = currentContextGroupId(); + v8::debug::SetBreakOnNextFunctionCall(m_isolate); } void V8Debugger::externalAsyncTaskFinished(const V8StackTraceId& parent) { @@ -845,22 +884,16 @@ void V8Debugger::externalAsyncTaskFinished(const V8StackTraceId& parent) { DCHECK(m_currentTasks.back() == reinterpret_cast<void*>(parent.id)); m_currentTasks.pop_back(); - if (m_taskWithScheduledBreakDebuggerId.isEmpty() || - reinterpret_cast<uintptr_t>(m_taskWithScheduledBreak) != parent.id || - m_taskWithScheduledBreakDebuggerId != - debuggerIdToString(parent.debugger_id)) { - return; - } - m_taskWithScheduledBreak = nullptr; - m_taskWithScheduledBreakDebuggerId = String16(); - if (m_breakRequested) return; + if (!parent.should_pause) return; + m_externalAsyncTaskPauseRequested = false; + if (hasScheduledBreakOnNextFunctionCall()) return; v8::debug::ClearBreakOnNextFunctionCall(m_isolate); } void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, bool recurring) { asyncTaskScheduledForStack(toString16(taskName), task, recurring); - asyncTaskCandidateForStepping(task, true); + asyncTaskCandidateForStepping(task); } void V8Debugger::asyncTaskCanceled(void* task) { @@ -936,46 +969,36 @@ void V8Debugger::asyncTaskFinishedForStack(void* task) { } } -void V8Debugger::asyncTaskCandidateForStepping(void* task, bool isLocal) { +void V8Debugger::asyncTaskCandidateForStepping(void* task) { if (!m_pauseOnAsyncCall) return; int contextGroupId = currentContextGroupId(); if (contextGroupId != m_targetContextGroupId) return; - if (isLocal) { - m_scheduledAsyncCall = v8_inspector::V8StackTraceId( - reinterpret_cast<uintptr_t>(task), std::make_pair(0, 0)); - } else { - m_scheduledAsyncCall = v8_inspector::V8StackTraceId( - reinterpret_cast<uintptr_t>(task), debuggerIdFor(contextGroupId)); - } - breakProgram(m_targetContextGroupId); - m_scheduledAsyncCall = v8_inspector::V8StackTraceId(); + m_taskWithScheduledBreak = task; + m_pauseOnAsyncCall = false; + v8::debug::ClearStepping(m_isolate); // Cancel step into. } void V8Debugger::asyncTaskStartedForStepping(void* task) { - if (m_breakRequested) return; // TODO(kozyatinskiy): we should search task in async chain to support // blackboxing. - if (m_taskWithScheduledBreakDebuggerId.isEmpty() && - task == m_taskWithScheduledBreak) { - v8::debug::SetBreakOnNextFunctionCall(m_isolate); - } + if (task != m_taskWithScheduledBreak) return; + bool didHaveBreak = hasScheduledBreakOnNextFunctionCall(); + m_taskWithScheduledBreakPauseRequested = true; + if (didHaveBreak) return; + m_targetContextGroupId = currentContextGroupId(); + v8::debug::SetBreakOnNextFunctionCall(m_isolate); } void V8Debugger::asyncTaskFinishedForStepping(void* task) { - if (!m_taskWithScheduledBreakDebuggerId.isEmpty() || - task != m_taskWithScheduledBreak) { - return; - } + if (task != m_taskWithScheduledBreak) return; m_taskWithScheduledBreak = nullptr; - if (m_breakRequested) return; + m_taskWithScheduledBreakPauseRequested = false; + if (hasScheduledBreakOnNextFunctionCall()) return; v8::debug::ClearBreakOnNextFunctionCall(m_isolate); } void V8Debugger::asyncTaskCanceledForStepping(void* task) { - if (!m_taskWithScheduledBreakDebuggerId.isEmpty() || - task != m_taskWithScheduledBreak) - return; - m_taskWithScheduledBreak = nullptr; + asyncTaskFinishedForStepping(task); } void V8Debugger::allAsyncTasksCanceled() { @@ -1058,7 +1081,7 @@ std::shared_ptr<StackFrame> V8Debugger::symbolize( return std::shared_ptr<StackFrame>(it->second); } std::shared_ptr<StackFrame> frame(new StackFrame(isolate(), v8Frame)); - // TODO(clemensh): Figure out a way to do this translation only right before + // TODO(clemensb): Figure out a way to do this translation only right before // sending the stack trace over wire. if (v8Frame->IsWasm()) frame->translate(&m_wasmTranslation); if (m_maxAsyncCallStackDepth) { @@ -1073,27 +1096,15 @@ void V8Debugger::setMaxAsyncTaskStacksForTest(int limit) { m_maxAsyncCallStacks = limit; } -std::pair<int64_t, int64_t> V8Debugger::debuggerIdFor(int contextGroupId) { +V8DebuggerId V8Debugger::debuggerIdFor(int contextGroupId) { auto it = m_contextGroupIdToDebuggerId.find(contextGroupId); if (it != m_contextGroupIdToDebuggerId.end()) return it->second; - std::pair<int64_t, int64_t> debuggerId( - v8::debug::GetNextRandomInt64(m_isolate), - v8::debug::GetNextRandomInt64(m_isolate)); - if (!debuggerId.first && !debuggerId.second) ++debuggerId.first; + V8DebuggerId debuggerId = V8DebuggerId::generate(m_isolate); m_contextGroupIdToDebuggerId.insert( it, std::make_pair(contextGroupId, debuggerId)); - m_serializedDebuggerIdToDebuggerId.insert( - std::make_pair(debuggerIdToString(debuggerId), debuggerId)); return debuggerId; } -std::pair<int64_t, int64_t> V8Debugger::debuggerIdFor( - const String16& serializedDebuggerId) { - auto it = m_serializedDebuggerIdToDebuggerId.find(serializedDebuggerId); - if (it != m_serializedDebuggerIdToDebuggerId.end()) return it->second; - return std::make_pair(0, 0); -} - bool V8Debugger::addInternalObject(v8::Local<v8::Context> context, v8::Local<v8::Object> object, V8InternalValueType type) { @@ -1110,4 +1121,9 @@ void V8Debugger::dumpAsyncTaskStacksStateForTest() { fprintf(stdout, "\n"); } +bool V8Debugger::hasScheduledBreakOnNextFunctionCall() const { + return m_pauseOnNextCallRequested || m_taskWithScheduledBreakPauseRequested || + m_externalAsyncTaskPauseRequested; +} + } // namespace v8_inspector |