[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:
yangguo 2017-04-26 08:13:14 -07:00 committed by Commit bot
parent af1a309146
commit aaaaa80f02
11 changed files with 110 additions and 23 deletions

View File

@ -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 {

View File

@ -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;

View File

@ -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);

View File

@ -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));
}

View File

@ -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.

View 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(#)

View 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);

View File

@ -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;
}

View File

@ -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_);

View File

@ -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_;

View File

@ -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)