Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deps: v8, backport b901591 #27720

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions deps/v8/src/api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9430,6 +9430,19 @@ bool debug::Script::SetBreakpoint(v8::Local<v8::String> condition,
return true;
}

bool debug::Script::SetBreakpointOnScriptEntry(BreakpointId* id) const {
i::Handle<i::Script> script = Utils::OpenHandle(this);
i::Isolate* isolate = script->GetIsolate();
i::SharedFunctionInfo::ScriptIterator it(isolate, *script);
for (i::SharedFunctionInfo sfi = it.Next(); !sfi.is_null(); sfi = it.Next()) {
if (sfi->is_toplevel()) {
return isolate->debug()->SetBreakpointForFunction(
handle(sfi, isolate), isolate->factory()->empty_string(), id);
}
}
return false;
}

void debug::RemoveBreakpoint(Isolate* v8_isolate, BreakpointId id) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
i::HandleScope handle_scope(isolate);
Expand Down Expand Up @@ -9823,8 +9836,8 @@ bool debug::SetFunctionBreakpoint(v8::Local<v8::Function> function,
i::Handle<i::String> condition_string =
condition.IsEmpty() ? isolate->factory()->empty_string()
: Utils::OpenHandle(*condition);
return isolate->debug()->SetBreakpointForFunction(jsfunction,
condition_string, id);
return isolate->debug()->SetBreakpointForFunction(
handle(jsfunction->shared(), isolate), condition_string, id);
}

debug::PostponeInterruptsScope::PostponeInterruptsScope(v8::Isolate* isolate)
Expand Down
1 change: 1 addition & 0 deletions deps/v8/src/debug/debug-interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ class V8_EXPORT_PRIVATE Script {
LiveEditResult* result) const;
bool SetBreakpoint(v8::Local<v8::String> condition, debug::Location* location,
BreakpointId* id) const;
bool SetBreakpointOnScriptEntry(BreakpointId* id) const;
};

// Specialization for wasm Scripts.
Expand Down
7 changes: 3 additions & 4 deletions deps/v8/src/debug/debug.cc
Original file line number Diff line number Diff line change
Expand Up @@ -589,13 +589,12 @@ bool Debug::CheckBreakPoint(Handle<BreakPoint> break_point,
return result->BooleanValue(isolate_);
}

bool Debug::SetBreakPoint(Handle<JSFunction> function,
bool Debug::SetBreakpoint(Handle<SharedFunctionInfo> shared,
Handle<BreakPoint> break_point,
int* source_position) {
HandleScope scope(isolate_);

// Make sure the function is compiled and has set up the debug info.
Handle<SharedFunctionInfo> shared(function->shared(), isolate_);
if (!EnsureBreakInfo(shared)) return false;
PrepareFunctionForDebugExecution(shared);

Expand Down Expand Up @@ -750,13 +749,13 @@ int Debug::GetFunctionDebuggingId(Handle<JSFunction> function) {
return id;
}

bool Debug::SetBreakpointForFunction(Handle<JSFunction> function,
bool Debug::SetBreakpointForFunction(Handle<SharedFunctionInfo> shared,
Handle<String> condition, int* id) {
*id = ++thread_local_.last_breakpoint_id_;
Handle<BreakPoint> breakpoint =
isolate_->factory()->NewBreakPoint(*id, condition);
int source_position = 0;
return SetBreakPoint(function, breakpoint, &source_position);
return SetBreakpoint(shared, breakpoint, &source_position);
}

void Debug::RemoveBreakpoint(int id) {
Expand Down
4 changes: 2 additions & 2 deletions deps/v8/src/debug/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,15 +227,15 @@ class V8_EXPORT_PRIVATE Debug {
Handle<FixedArray> GetLoadedScripts();

// Break point handling.
bool SetBreakPoint(Handle<JSFunction> function,
bool SetBreakpoint(Handle<SharedFunctionInfo> shared,
Handle<BreakPoint> break_point, int* source_position);
void ClearBreakPoint(Handle<BreakPoint> break_point);
void ChangeBreakOnException(ExceptionBreakType type, bool enable);
bool IsBreakOnException(ExceptionBreakType type);

bool SetBreakPointForScript(Handle<Script> script, Handle<String> condition,
int* source_position, int* id);
bool SetBreakpointForFunction(Handle<JSFunction> function,
bool SetBreakpointForFunction(Handle<SharedFunctionInfo> shared,
Handle<String> condition, int* id);
void RemoveBreakpoint(int id);

Expand Down
22 changes: 17 additions & 5 deletions deps/v8/src/inspector/js_protocol.pdl
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,17 @@ domain Debugger
# Location this breakpoint resolved into.
Location actualLocation

# Sets instrumentation breakpoint.
command setInstrumentationBreakpoint
parameters
# Instrumentation name.
enum instrumentation
beforeScriptExecution
beforeScriptWithSourceMapExecution
returns
# Id of the created breakpoint for further reference.
BreakpointId breakpointId

# Sets JavaScript breakpoint at given location specified either by URL or URL regex. Once this
# command is issued, all existing parsed scripts will have breakpoints resolved and returned in
# `locations` property. Further matching script parsing will result in subsequent
Expand Down Expand Up @@ -449,16 +460,17 @@ domain Debugger
array of CallFrame callFrames
# Pause reason.
enum reason
XHR
ambiguous
assert
debugCommand
DOM
EventListener
exception
assert
debugCommand
promiseRejection
instrumentation
OOM
other
ambiguous
promiseRejection
XHR
# Object containing break-specific auxiliary properties.
optional object data
# Hit breakpoints IDs
Expand Down
88 changes: 82 additions & 6 deletions deps/v8/src/inspector/v8-debugger-agent-impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,13 @@ using protocol::Array;
using protocol::Maybe;
using protocol::Debugger::BreakpointId;
using protocol::Debugger::CallFrame;
using protocol::Debugger::Scope;
using protocol::Runtime::ExceptionDetails;
using protocol::Runtime::ScriptId;
using protocol::Runtime::RemoteObject;
using protocol::Debugger::Scope;
using protocol::Runtime::ScriptId;

namespace InstrumentationEnum =
protocol::Debugger::SetInstrumentationBreakpoint::InstrumentationEnum;

namespace DebuggerAgentState {
static const char pauseOnExceptionsState[] = "pauseOnExceptionsState";
Expand All @@ -47,6 +50,7 @@ static const char breakpointsByRegex[] = "breakpointsByRegex";
static const char breakpointsByUrl[] = "breakpointsByUrl";
static const char breakpointsByScriptHash[] = "breakpointsByScriptHash";
static const char breakpointHints[] = "breakpointHints";
static const char instrumentationBreakpoints[] = "instrumentationBreakpoints";

} // namespace DebuggerAgentState

Expand Down Expand Up @@ -80,7 +84,8 @@ enum class BreakpointType {
kByScriptId,
kDebugCommand,
kMonitorCommand,
kBreakpointAtEntry
kBreakpointAtEntry,
kInstrumentationBreakpoint
};

String16 generateBreakpointId(BreakpointType type,
Expand All @@ -106,6 +111,15 @@ String16 generateBreakpointId(BreakpointType type,
return builder.toString();
}

String16 generateInstrumentationBreakpointId(const String16& instrumentation) {
String16Builder builder;
builder.appendNumber(
static_cast<int>(BreakpointType::kInstrumentationBreakpoint));
builder.append(':');
builder.append(instrumentation);
return builder.toString();
}

bool parseBreakpointId(const String16& breakpointId, BreakpointType* type,
String16* scriptSelector = nullptr,
int* lineNumber = nullptr, int* columnNumber = nullptr) {
Expand All @@ -114,14 +128,15 @@ bool parseBreakpointId(const String16& breakpointId, BreakpointType* type,

int rawType = breakpointId.substring(0, typeLineSeparator).toInteger();
if (rawType < static_cast<int>(BreakpointType::kByUrl) ||
rawType > static_cast<int>(BreakpointType::kBreakpointAtEntry)) {
rawType > static_cast<int>(BreakpointType::kInstrumentationBreakpoint)) {
return false;
}
if (type) *type = static_cast<BreakpointType>(rawType);
if (rawType == static_cast<int>(BreakpointType::kDebugCommand) ||
rawType == static_cast<int>(BreakpointType::kMonitorCommand) ||
rawType == static_cast<int>(BreakpointType::kBreakpointAtEntry)) {
// The script and source position is not encoded in this case.
rawType == static_cast<int>(BreakpointType::kBreakpointAtEntry) ||
rawType == static_cast<int>(BreakpointType::kInstrumentationBreakpoint)) {
// The script and source position are not encoded in this case.
return true;
}

Expand Down Expand Up @@ -356,6 +371,7 @@ Response V8DebuggerAgentImpl::disable() {
m_state->remove(DebuggerAgentState::breakpointsByUrl);
m_state->remove(DebuggerAgentState::breakpointsByScriptHash);
m_state->remove(DebuggerAgentState::breakpointHints);
m_state->remove(DebuggerAgentState::instrumentationBreakpoints);

m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState,
v8::debug::NoBreakOnException);
Expand Down Expand Up @@ -580,6 +596,20 @@ Response V8DebuggerAgentImpl::setBreakpointOnFunctionCall(
return Response::OK();
}

Response V8DebuggerAgentImpl::setInstrumentationBreakpoint(
const String16& instrumentation, String16* outBreakpointId) {
if (!enabled()) return Response::Error(kDebuggerNotEnabled);
String16 breakpointId = generateInstrumentationBreakpointId(instrumentation);
protocol::DictionaryValue* breakpoints = getOrCreateObject(
m_state, DebuggerAgentState::instrumentationBreakpoints);
if (breakpoints->get(breakpointId)) {
return Response::Error("Instrumentation breakpoint is already enabled.");
}
breakpoints->setBoolean(breakpointId, true);
*outBreakpointId = breakpointId;
return Response::OK();
}

Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) {
if (!enabled()) return Response::Error(kDebuggerNotEnabled);
BreakpointType type;
Expand All @@ -606,6 +636,10 @@ Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) {
case BreakpointType::kByUrlRegex:
breakpoints = m_state->getObject(DebuggerAgentState::breakpointsByRegex);
break;
case BreakpointType::kInstrumentationBreakpoint:
breakpoints =
m_state->getObject(DebuggerAgentState::instrumentationBreakpoints);
break;
default:
break;
}
Expand Down Expand Up @@ -1496,6 +1530,40 @@ void V8DebuggerAgentImpl::didParseSource(
m_frontend.breakpointResolved(breakpointId, std::move(location));
}
}
setScriptInstrumentationBreakpointIfNeeded(scriptRef);
}

void V8DebuggerAgentImpl::setScriptInstrumentationBreakpointIfNeeded(
V8DebuggerScript* scriptRef) {
protocol::DictionaryValue* breakpoints =
m_state->getObject(DebuggerAgentState::instrumentationBreakpoints);
if (!breakpoints) return;
bool isBlackboxed = isFunctionBlackboxed(
scriptRef->scriptId(), v8::debug::Location(0, 0),
v8::debug::Location(scriptRef->endLine(), scriptRef->endColumn()));
if (isBlackboxed) return;

String16 sourceMapURL = scriptRef->sourceMappingURL();
String16 breakpointId = generateInstrumentationBreakpointId(
InstrumentationEnum::BeforeScriptExecution);
if (!breakpoints->get(breakpointId)) {
if (sourceMapURL.isEmpty()) return;
breakpointId = generateInstrumentationBreakpointId(
InstrumentationEnum::BeforeScriptWithSourceMapExecution);
if (!breakpoints->get(breakpointId)) return;
}
v8::debug::BreakpointId debuggerBreakpointId;
if (!scriptRef->setBreakpointOnRun(&debuggerBreakpointId)) return;
std::unique_ptr<protocol::DictionaryValue> data =
protocol::DictionaryValue::create();
data->setString("url", scriptRef->sourceURL());
data->setString("scriptId", scriptRef->scriptId());
if (!sourceMapURL.isEmpty()) data->setString("sourceMapURL", sourceMapURL);

m_breakpointsOnScriptRun[debuggerBreakpointId] = std::move(data);
m_debuggerBreakpointIdToBreakpointId[debuggerBreakpointId] = breakpointId;
m_breakpointIdToDebuggerBreakpointIds[breakpointId].push_back(
debuggerBreakpointId);
}

void V8DebuggerAgentImpl::didPause(
Expand Down Expand Up @@ -1539,6 +1607,14 @@ void V8DebuggerAgentImpl::didPause(
std::unique_ptr<Array<String16>> hitBreakpointIds = Array<String16>::create();

for (const auto& id : hitBreakpoints) {
auto it = m_breakpointsOnScriptRun.find(id);
if (it != m_breakpointsOnScriptRun.end()) {
hitReasons.push_back(std::make_pair(
protocol::Debugger::Paused::ReasonEnum::Instrumentation,
std::move(it->second)));
m_breakpointsOnScriptRun.erase(it);
continue;
}
auto breakpointIterator = m_debuggerBreakpointIdToBreakpointId.find(id);
if (breakpointIterator == m_debuggerBreakpointIdToBreakpointId.end()) {
continue;
Expand Down
7 changes: 7 additions & 0 deletions deps/v8/src/inspector/v8-debugger-agent-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
Response setBreakpointOnFunctionCall(const String16& functionObjectId,
Maybe<String16> optionalCondition,
String16* outBreakpointId) override;
Response setInstrumentationBreakpoint(const String16& instrumentation,
String16* outBreakpointId) override;
Response removeBreakpoint(const String16& breakpointId) override;
Response continueToLocation(std::unique_ptr<protocol::Debugger::Location>,
Maybe<String16> targetCallFrames) override;
Expand Down Expand Up @@ -184,6 +186,8 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {

bool isPaused() const;

void setScriptInstrumentationBreakpointIfNeeded(V8DebuggerScript* script);

using ScriptsMap =
std::unordered_map<String16, std::unique_ptr<V8DebuggerScript>>;
using BreakpointIdToDebuggerBreakpointIdsMap =
Expand All @@ -201,6 +205,9 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
ScriptsMap m_scripts;
BreakpointIdToDebuggerBreakpointIdsMap m_breakpointIdToDebuggerBreakpointIds;
DebuggerBreakpointIdToBreakpointIdMap m_debuggerBreakpointIdToBreakpointId;
std::unordered_map<v8::debug::BreakpointId,
std::unique_ptr<protocol::DictionaryValue>>
m_breakpointsOnScriptRun;

size_t m_maxScriptCacheSize = 0;
size_t m_cachedScriptSize = 0;
Expand Down
7 changes: 7 additions & 0 deletions deps/v8/src/inspector/v8-debugger-script.cc
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,11 @@ class ActualScript : public V8DebuggerScript {
id);
}

bool setBreakpointOnRun(int* id) const override {
v8::HandleScope scope(m_isolate);
return script()->SetBreakpointOnScriptEntry(id);
}

const String16& hash() const override {
if (!m_hash.isEmpty()) return m_hash;
v8::HandleScope scope(m_isolate);
Expand Down Expand Up @@ -424,6 +429,8 @@ class WasmVirtualScript : public V8DebuggerScript {
return true;
}

bool setBreakpointOnRun(int*) const override { return false; }

const String16& hash() const override {
if (m_hash.isEmpty()) {
m_hash = m_wasmTranslation->GetHash(m_id, m_functionIndex);
Expand Down
1 change: 1 addition & 0 deletions deps/v8/src/inspector/v8-debugger-script.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class V8DebuggerScript {
virtual bool setBreakpoint(const String16& condition,
v8::debug::Location* location, int* id) const = 0;
virtual void MakeWeak() = 0;
virtual bool setBreakpointOnRun(int* id) const = 0;

protected:
V8DebuggerScript(v8::Isolate*, String16 id, String16 url);
Expand Down
3 changes: 2 additions & 1 deletion deps/v8/test/cctest/test-debug.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ static i::Handle<i::BreakPoint> SetBreakPoint(v8::Local<v8::Function> fun,
i::Handle<i::BreakPoint> break_point =
isolate->factory()->NewBreakPoint(++break_point_index, condition_string);

debug->SetBreakPoint(function, break_point, &position);
debug->SetBreakpoint(handle(function->shared(), isolate), break_point,
&position);
return break_point;
}

Expand Down
Loading