aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/inspector/v8-debugger.cc
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2019-11-08 15:39:11 +0100
committerMichaël Zasso <targos@protonmail.com>2019-11-08 15:46:25 +0100
commit6ca81ad72a3c6fdf16c683335be748f22aaa9a0d (patch)
tree33c8ee75f729aed76c2c0b89c63f9bf1b4dd66aa /deps/v8/src/inspector/v8-debugger.cc
parent1eee0b8bf8bba39b600fb16a9223e545e3bac2bc (diff)
downloadandroid-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.cc226
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