[inspector] always include user scripts in the snapshot.
V8 can bundle user scripts in the start up snapshot. These are
shared across contexts, and do not work well context groups.
R=kozyatinskiy@chromium.org
BUG=v8:6274
Review-Url: https://codereview.chromium.org/2836623002
Cr-Original-Commit-Position: refs/heads/master@{#44847}
Committed: 9685cfd310
Review-Url: https://codereview.chromium.org/2836623002
Cr-Commit-Position: refs/heads/master@{#44897}
This commit is contained in:
parent
af1a309146
commit
aaaaa80f02
12
src/api.cc
12
src/api.cc
@ -9287,6 +9287,11 @@ bool debug::Script::WasCompiled() const {
|
||||
i::Script::COMPILATION_STATE_COMPILED;
|
||||
}
|
||||
|
||||
bool debug::Script::IsEmbedded() const {
|
||||
i::Handle<i::Script> script = Utils::OpenHandle(this);
|
||||
return script->context_data() == script->GetHeap()->uninitialized_symbol();
|
||||
}
|
||||
|
||||
int debug::Script::Id() const { return Utils::OpenHandle(this)->id(); }
|
||||
|
||||
int debug::Script::LineOffset() const {
|
||||
@ -9343,12 +9348,13 @@ MaybeLocal<String> debug::Script::SourceMappingURL() const {
|
||||
handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value)));
|
||||
}
|
||||
|
||||
MaybeLocal<Value> debug::Script::ContextData() const {
|
||||
Maybe<int> debug::Script::ContextId() const {
|
||||
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
|
||||
i::HandleScope handle_scope(isolate);
|
||||
i::Handle<i::Script> script = Utils::OpenHandle(this);
|
||||
i::Handle<i::Object> value(script->context_data(), isolate);
|
||||
return Utils::ToLocal(handle_scope.CloseAndEscape(value));
|
||||
i::Object* value = script->context_data();
|
||||
if (value->IsSmi()) return Just(i::Smi::cast(value)->value());
|
||||
return Nothing<int>();
|
||||
}
|
||||
|
||||
MaybeLocal<String> debug::Script::Source() const {
|
||||
|
@ -129,6 +129,7 @@ class V8_EXPORT_PRIVATE Script {
|
||||
|
||||
ScriptOriginOptions OriginOptions() const;
|
||||
bool WasCompiled() const;
|
||||
bool IsEmbedded() const;
|
||||
int Id() const;
|
||||
int LineOffset() const;
|
||||
int ColumnOffset() const;
|
||||
@ -136,7 +137,7 @@ class V8_EXPORT_PRIVATE Script {
|
||||
MaybeLocal<String> Name() const;
|
||||
MaybeLocal<String> SourceURL() const;
|
||||
MaybeLocal<String> SourceMappingURL() const;
|
||||
MaybeLocal<Value> ContextData() const;
|
||||
Maybe<int> ContextId() const;
|
||||
MaybeLocal<String> Source() const;
|
||||
bool IsWasm() const;
|
||||
bool IsModule() const;
|
||||
|
@ -138,11 +138,7 @@ class ActualScript : public V8DebuggerScript {
|
||||
m_endColumn = m_startColumn;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> contextData;
|
||||
if (script->ContextData().ToLocal(&contextData) && contextData->IsInt32()) {
|
||||
m_executionContextId =
|
||||
static_cast<int>(contextData.As<v8::Int32>()->Value());
|
||||
}
|
||||
USE(script->ContextId().To(&m_executionContextId));
|
||||
|
||||
if (script->Source().ToLocal(&tmp)) {
|
||||
m_source = toProtocolString(tmp);
|
||||
|
@ -29,11 +29,8 @@ inline v8::Local<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) {
|
||||
|
||||
V8DebuggerAgentImpl* agentForScript(V8InspectorImpl* inspector,
|
||||
v8::Local<v8::debug::Script> script) {
|
||||
v8::Local<v8::Value> contextData;
|
||||
if (!script->ContextData().ToLocal(&contextData) || !contextData->IsInt32()) {
|
||||
return nullptr;
|
||||
}
|
||||
int contextId = static_cast<int>(contextData.As<v8::Int32>()->Value());
|
||||
int contextId;
|
||||
if (!script->ContextId().To(&contextId)) return nullptr;
|
||||
int contextGroupId = inspector->contextGroupId(contextId);
|
||||
if (!contextGroupId) return nullptr;
|
||||
return inspector->enabledDebuggerAgentForGroup(contextGroupId);
|
||||
@ -218,10 +215,12 @@ void V8Debugger::getCompiledScripts(
|
||||
for (size_t i = 0; i < scripts.Size(); ++i) {
|
||||
v8::Local<v8::debug::Script> script = scripts.Get(i);
|
||||
if (!script->WasCompiled()) continue;
|
||||
v8::Local<v8::Value> contextData;
|
||||
if (!script->ContextData().ToLocal(&contextData) || !contextData->IsInt32())
|
||||
if (script->IsEmbedded()) {
|
||||
result.push_back(V8DebuggerScript::Create(m_isolate, script, false));
|
||||
continue;
|
||||
int contextId = static_cast<int>(contextData.As<v8::Int32>()->Value());
|
||||
}
|
||||
int contextId;
|
||||
if (!script->ContextId().To(&contextId)) continue;
|
||||
if (m_inspector->contextGroupId(contextId) != contextGroupId) continue;
|
||||
result.push_back(V8DebuggerScript::Create(m_isolate, script, false));
|
||||
}
|
||||
|
@ -73,6 +73,9 @@ void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
|
||||
Address original_address = Foreign::cast(info->getter())->foreign_address();
|
||||
Foreign::cast(info->js_getter())->set_foreign_address(original_address);
|
||||
accessor_infos_.Add(info);
|
||||
} else if (obj->IsScript() && Script::cast(obj)->IsUserJavaScript()) {
|
||||
Script::cast(obj)->set_context_data(
|
||||
isolate_->heap()->uninitialized_symbol());
|
||||
}
|
||||
|
||||
// Object has not yet been serialized. Serialize it here.
|
||||
|
33
test/inspector/debugger/step-snapshot-expected.txt
Normal file
33
test/inspector/debugger/step-snapshot-expected.txt
Normal file
@ -0,0 +1,33 @@
|
||||
Embedding script 'function c(f, ...args) { return f(...args); }'
|
||||
paused
|
||||
}
|
||||
#debugger;
|
||||
c(f, 2);
|
||||
|
||||
paused
|
||||
debugger;
|
||||
#c(f, 2);
|
||||
}
|
||||
|
||||
paused
|
||||
function c(f, ...args) { #return f(...args); }
|
||||
|
||||
paused
|
||||
function f(x) {
|
||||
#return x * 2;
|
||||
}
|
||||
|
||||
paused
|
||||
return x * 2;
|
||||
#}
|
||||
debugger;
|
||||
|
||||
paused
|
||||
function c(f, ...args) { return f(...args); #}
|
||||
|
||||
paused
|
||||
c(f, 2);
|
||||
#}
|
||||
|
||||
paused
|
||||
test(#)
|
30
test/inspector/debugger/step-snapshot.js
Normal file
30
test/inspector/debugger/step-snapshot.js
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2017 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Embed a user function in the snapshot and step through it.
|
||||
|
||||
// Flags: --embed 'function c(f, ...args) { return f(...args); }'
|
||||
|
||||
InspectorTest.setupScriptMap();
|
||||
|
||||
InspectorTest.addScript(`
|
||||
function test() {
|
||||
function f(x) {
|
||||
return x * 2;
|
||||
}
|
||||
debugger;
|
||||
c(f, 2);
|
||||
}
|
||||
//# sourceURL=test.js`);
|
||||
|
||||
Protocol.Debugger.onPaused(message => {
|
||||
InspectorTest.log("paused");
|
||||
var frames = message.params.callFrames;
|
||||
InspectorTest.logSourceLocation(frames[0].location);
|
||||
Protocol.Debugger.stepInto();
|
||||
})
|
||||
|
||||
Protocol.Debugger.enable()
|
||||
.then(() => Protocol.Runtime.evaluate({ expression: 'test()' }))
|
||||
.then(InspectorTest.completeTest);
|
@ -601,11 +601,22 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
v8::base::Semaphore ready_semaphore(0);
|
||||
|
||||
v8::StartupData startup_data = {nullptr, 0};
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (strcmp(argv[i], "--embed") == 0) {
|
||||
argv[i++] = nullptr;
|
||||
printf("Embedding script '%s'\n", argv[i]);
|
||||
startup_data = v8::V8::CreateSnapshotDataBlob(argv[i]);
|
||||
argv[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
TaskRunner::SetupGlobalTasks backend_extensions;
|
||||
backend_extensions.emplace_back(new SetTimeoutExtension());
|
||||
backend_extensions.emplace_back(new InspectorExtension());
|
||||
TaskRunner backend_runner(std::move(backend_extensions), false,
|
||||
&ready_semaphore);
|
||||
&ready_semaphore,
|
||||
startup_data.data ? &startup_data : nullptr);
|
||||
ready_semaphore.Wait();
|
||||
SendMessageToBackendExtension::set_backend_task_runner(&backend_runner);
|
||||
UtilsExtension::set_backend_task_runner(&backend_runner);
|
||||
@ -614,7 +625,7 @@ int main(int argc, char* argv[]) {
|
||||
frontend_extensions.emplace_back(new UtilsExtension());
|
||||
frontend_extensions.emplace_back(new SendMessageToBackendExtension());
|
||||
TaskRunner frontend_runner(std::move(frontend_extensions), true,
|
||||
&ready_semaphore);
|
||||
&ready_semaphore, nullptr);
|
||||
ready_semaphore.Wait();
|
||||
|
||||
FrontendChannelImpl frontend_channel(&frontend_runner);
|
||||
@ -628,7 +639,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
// Ignore unknown flags.
|
||||
if (argv[i][0] == '-') continue;
|
||||
if (argv[i] == nullptr || argv[i][0] == '-') continue;
|
||||
|
||||
bool exists = false;
|
||||
v8::internal::Vector<const char> chars =
|
||||
@ -643,5 +654,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
frontend_runner.Join();
|
||||
backend_runner.Join();
|
||||
|
||||
delete startup_data.data;
|
||||
return 0;
|
||||
}
|
||||
|
@ -34,9 +34,11 @@ v8::internal::Vector<uint16_t> ToVector(v8::Local<v8::String> str) {
|
||||
|
||||
TaskRunner::TaskRunner(TaskRunner::SetupGlobalTasks setup_global_tasks,
|
||||
bool catch_exceptions,
|
||||
v8::base::Semaphore* ready_semaphore)
|
||||
v8::base::Semaphore* ready_semaphore,
|
||||
v8::StartupData* startup_data)
|
||||
: Thread(Options("Task Runner")),
|
||||
setup_global_tasks_(std::move(setup_global_tasks)),
|
||||
startup_data_(startup_data),
|
||||
catch_exceptions_(catch_exceptions),
|
||||
ready_semaphore_(ready_semaphore),
|
||||
isolate_(nullptr),
|
||||
@ -51,6 +53,7 @@ void TaskRunner::InitializeIsolate() {
|
||||
v8::Isolate::CreateParams params;
|
||||
params.array_buffer_allocator =
|
||||
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
|
||||
params.snapshot_blob = startup_data_;
|
||||
isolate_ = v8::Isolate::New(params);
|
||||
isolate_->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped);
|
||||
v8::Isolate::Scope isolate_scope(isolate_);
|
||||
|
@ -45,7 +45,8 @@ class TaskRunner : public v8::base::Thread {
|
||||
using SetupGlobalTasks = std::vector<std::unique_ptr<SetupGlobalTask>>;
|
||||
|
||||
TaskRunner(SetupGlobalTasks setup_global_tasks, bool catch_exceptions,
|
||||
v8::base::Semaphore* ready_semaphore);
|
||||
v8::base::Semaphore* ready_semaphore,
|
||||
v8::StartupData* startup_data);
|
||||
virtual ~TaskRunner();
|
||||
|
||||
// Thread implementation.
|
||||
@ -78,6 +79,7 @@ class TaskRunner : public v8::base::Thread {
|
||||
Task* GetNext(bool only_protocol);
|
||||
|
||||
SetupGlobalTasks setup_global_tasks_;
|
||||
v8::StartupData* startup_data_;
|
||||
bool catch_exceptions_;
|
||||
v8::base::Semaphore* ready_semaphore_;
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
import itertools
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
|
||||
from testrunner.local import testsuite
|
||||
from testrunner.local import utils
|
||||
@ -43,7 +44,7 @@ class InspectorProtocolTestSuite(testsuite.TestSuite):
|
||||
flags = [] + context.mode_flags
|
||||
flags_match = re.findall(FLAGS_PATTERN, source)
|
||||
for match in flags_match:
|
||||
flags += match.strip().split()
|
||||
flags += shlex.split(match.strip())
|
||||
testname = testcase.path.split(os.path.sep)[-1]
|
||||
testfilename = os.path.join(self.root, testcase.path + self.suffix())
|
||||
protocoltestfilename = os.path.join(self.root, PROTOCOL_TEST_JS)
|
||||
|
Loading…
Reference in New Issue
Block a user