Commit 39cd762c authored by yangguo's avatar yangguo Committed by Commit bot

Embed custom script into the snapshot.

R=vogelheim@chromium.org

Review URL: https://codereview.chromium.org/845973003

Cr-Commit-Position: refs/heads/master@{#26029}
parent 4b6316c5
...@@ -153,6 +153,9 @@ ifeq ($(asan), on) ...@@ -153,6 +153,9 @@ ifeq ($(asan), on)
GYPFLAGS += -Dlsan=1 GYPFLAGS += -Dlsan=1
endif endif
endif endif
ifdef embedscript
GYPFLAGS += -Dembed_script=$(embedscript)
endif
# arm specific flags. # arm specific flags.
# arm_version=<number | "default"> # arm_version=<number | "default">
......
...@@ -5336,7 +5336,7 @@ class V8_EXPORT V8 { ...@@ -5336,7 +5336,7 @@ class V8_EXPORT V8 {
* Returns { NULL, 0 } on failure. * Returns { NULL, 0 } on failure.
* The caller owns the data array in the return value. * The caller owns the data array in the return value.
*/ */
static StartupData CreateSnapshotDataBlob(); static StartupData CreateSnapshotDataBlob(char* custom_source = NULL);
/** /**
* Adds a message listener. * Adds a message listener.
......
...@@ -206,7 +206,21 @@ void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) { ...@@ -206,7 +206,21 @@ void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
} }
StartupData V8::CreateSnapshotDataBlob() { bool RunExtraCode(Isolate* isolate, char* utf8_source) {
// Run custom script if provided.
TryCatch try_catch;
Local<String> source_string = String::NewFromUtf8(isolate, utf8_source);
if (try_catch.HasCaught()) return false;
ScriptOrigin origin(String::NewFromUtf8(isolate, "<embedded script>"));
ScriptCompiler::Source source(source_string, origin);
Local<Script> script = ScriptCompiler::Compile(isolate, &source);
if (try_catch.HasCaught()) return false;
script->Run();
return !try_catch.HasCaught();
}
StartupData V8::CreateSnapshotDataBlob(char* custom_source) {
Isolate::CreateParams params; Isolate::CreateParams params;
params.enable_serializer = true; params.enable_serializer = true;
Isolate* isolate = v8::Isolate::New(params); Isolate* isolate = v8::Isolate::New(params);
...@@ -217,7 +231,12 @@ StartupData V8::CreateSnapshotDataBlob() { ...@@ -217,7 +231,12 @@ StartupData V8::CreateSnapshotDataBlob() {
Persistent<Context> context; Persistent<Context> context;
{ {
HandleScope handle_scope(isolate); HandleScope handle_scope(isolate);
context.Reset(isolate, Context::New(isolate)); Handle<Context> new_context = Context::New(isolate);
context.Reset(isolate, new_context);
if (custom_source != NULL) {
Context::Scope context_scope(new_context);
if (!RunExtraCode(isolate, custom_source)) context.Reset();
}
} }
if (!context.IsEmpty()) { if (!context.IsEmpty()) {
// Make sure all builtin scripts are cached. // Make sure all builtin scripts are cached.
......
...@@ -37,10 +37,15 @@ void StackGuard::reset_limits(const ExecutionAccess& lock) { ...@@ -37,10 +37,15 @@ void StackGuard::reset_limits(const ExecutionAccess& lock) {
static void PrintDeserializedCodeInfo(Handle<JSFunction> function) { static void PrintDeserializedCodeInfo(Handle<JSFunction> function) {
if (function->code() == function->shared()->code() && if (function->code() == function->shared()->code() &&
function->shared()->deserialized()) { function->shared()->deserialized()) {
PrintF("Running deserialized script "); PrintF("[Running deserialized script");
Object* script = function->shared()->script(); Object* script = function->shared()->script();
if (script->IsScript()) Script::cast(script)->name()->ShortPrint(); if (script->IsScript()) {
PrintF("\n"); Object* name = Script::cast(script)->name();
if (name->IsString()) {
PrintF(": %s", String::cast(name)->ToCString().get());
}
}
PrintF("]\n");
} }
} }
......
...@@ -111,6 +111,32 @@ class SnapshotWriter { ...@@ -111,6 +111,32 @@ class SnapshotWriter {
}; };
char* GetExtraCode(char* filename) {
if (filename == NULL || strlen(filename) == 0) return NULL;
::printf("Embedding extra script: %s\n", filename);
FILE* file = base::OS::FOpen(filename, "rb");
if (file == NULL) {
fprintf(stderr, "Failed to open '%s': errno %d\n", filename, errno);
exit(1);
}
fseek(file, 0, SEEK_END);
int size = ftell(file);
rewind(file);
char* chars = new char[size + 1];
chars[size] = '\0';
for (int i = 0; i < size;) {
int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
if (read < 0) {
fprintf(stderr, "Failed to read '%s': errno %d\n", filename, errno);
exit(1);
}
i += read;
}
fclose(file);
return chars;
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
// By default, log code create information in the snapshot. // By default, log code create information in the snapshot.
i::FLAG_log_code = true; i::FLAG_log_code = true;
...@@ -124,7 +150,7 @@ int main(int argc, char** argv) { ...@@ -124,7 +150,7 @@ int main(int argc, char** argv) {
// Print the usage if an error occurs when parsing the command line // Print the usage if an error occurs when parsing the command line
// flags or if the help flag is set. // flags or if the help flag is set.
int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true); int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
if (result > 0 || argc != 2 || i::FLAG_help) { if (result > 0 || (argc != 2 && argc != 3) || i::FLAG_help) {
::printf("Usage: %s [flag] ... outfile\n", argv[0]); ::printf("Usage: %s [flag] ... outfile\n", argv[0]);
i::FlagList::PrintHelp(); i::FlagList::PrintHelp();
return !i::FLAG_help; return !i::FLAG_help;
...@@ -139,9 +165,11 @@ int main(int argc, char** argv) { ...@@ -139,9 +165,11 @@ int main(int argc, char** argv) {
{ {
SnapshotWriter writer(argv[1]); SnapshotWriter writer(argv[1]);
if (i::FLAG_startup_blob) writer.SetStartupBlobFile(i::FLAG_startup_blob); if (i::FLAG_startup_blob) writer.SetStartupBlobFile(i::FLAG_startup_blob);
StartupData blob = v8::V8::CreateSnapshotDataBlob(); char* extra_code = GetExtraCode(argc == 3 ? argv[2] : NULL);
StartupData blob = v8::V8::CreateSnapshotDataBlob(extra_code);
CHECK(blob.data); CHECK(blob.data);
writer.WriteSnapshot(blob); writer.WriteSnapshot(blob);
delete[] extra_code;
delete[] blob.data; delete[] blob.data;
} }
......
...@@ -25,12 +25,14 @@ bool Snapshot::Initialize(Isolate* isolate) { ...@@ -25,12 +25,14 @@ bool Snapshot::Initialize(Isolate* isolate) {
if (FLAG_profile_deserialization) timer.Start(); if (FLAG_profile_deserialization) timer.Start();
const v8::StartupData blob = SnapshotBlob(); const v8::StartupData blob = SnapshotBlob();
SnapshotData snapshot_data(ExtractStartupData(&blob)); Vector<const byte> startup_data = ExtractStartupData(&blob);
SnapshotData snapshot_data(startup_data);
Deserializer deserializer(&snapshot_data); Deserializer deserializer(&snapshot_data);
bool success = isolate->Init(&deserializer); bool success = isolate->Init(&deserializer);
if (FLAG_profile_deserialization) { if (FLAG_profile_deserialization) {
double ms = timer.Elapsed().InMillisecondsF(); double ms = timer.Elapsed().InMillisecondsF();
PrintF("[Snapshot loading and deserialization took %0.3f ms]\n", ms); int bytes = startup_data.length();
PrintF("[Deserializing isolate (%d bytes) took %0.3f ms]\n", bytes, ms);
} }
return success; return success;
} }
...@@ -38,13 +40,21 @@ bool Snapshot::Initialize(Isolate* isolate) { ...@@ -38,13 +40,21 @@ bool Snapshot::Initialize(Isolate* isolate) {
Handle<Context> Snapshot::NewContextFromSnapshot(Isolate* isolate) { Handle<Context> Snapshot::NewContextFromSnapshot(Isolate* isolate) {
if (!HaveASnapshotToStartFrom()) return Handle<Context>(); if (!HaveASnapshotToStartFrom()) return Handle<Context>();
base::ElapsedTimer timer;
if (FLAG_profile_deserialization) timer.Start();
const v8::StartupData blob = SnapshotBlob(); const v8::StartupData blob = SnapshotBlob();
SnapshotData snapshot_data(ExtractContextData(&blob)); Vector<const byte> context_data = ExtractContextData(&blob);
SnapshotData snapshot_data(context_data);
Deserializer deserializer(&snapshot_data); Deserializer deserializer(&snapshot_data);
Object* root; Object* root;
deserializer.DeserializePartial(isolate, &root); deserializer.DeserializePartial(isolate, &root);
CHECK(root->IsContext()); CHECK(root->IsContext());
if (FLAG_profile_deserialization) {
double ms = timer.Elapsed().InMillisecondsF();
int bytes = context_data.length();
PrintF("[Deserializing context (%d bytes) took %0.3f ms]\n", bytes, ms);
}
return Handle<Context>(Context::cast(root)); return Handle<Context>(Context::cast(root));
} }
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
'icu_use_data_file_flag%': 0, 'icu_use_data_file_flag%': 0,
'v8_code': 1, 'v8_code': 1,
'v8_random_seed%': 314159265, 'v8_random_seed%': 314159265,
'embed_script%': "",
'mksnapshot_exec': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot<(EXECUTABLE_SUFFIX)',
}, },
'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'], 'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'],
'targets': [ 'targets': [
...@@ -169,7 +171,8 @@ ...@@ -169,7 +171,8 @@
{ {
'action_name': 'run_mksnapshot', 'action_name': 'run_mksnapshot',
'inputs': [ 'inputs': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot<(EXECUTABLE_SUFFIX)', '<(mksnapshot_exec)',
'<(embed_script)',
], ],
'outputs': [ 'outputs': [
'<(INTERMEDIATE_DIR)/snapshot.cc', '<(INTERMEDIATE_DIR)/snapshot.cc',
...@@ -186,9 +189,10 @@ ...@@ -186,9 +189,10 @@
], ],
}, },
'action': [ 'action': [
'<@(_inputs)', '<(mksnapshot_exec)',
'<@(mksnapshot_flags)', '<@(mksnapshot_flags)',
'<@(INTERMEDIATE_DIR)/snapshot.cc' '<@(INTERMEDIATE_DIR)/snapshot.cc',
'<(embed_script)',
], ],
}, },
], ],
...@@ -270,7 +274,7 @@ ...@@ -270,7 +274,7 @@
{ {
'action_name': 'run_mksnapshot (external)', 'action_name': 'run_mksnapshot (external)',
'inputs': [ 'inputs': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot<(EXECUTABLE_SUFFIX)', '<(mksnapshot_exec)',
], ],
'variables': { 'variables': {
'mksnapshot_flags': [ 'mksnapshot_flags': [
...@@ -292,10 +296,11 @@ ...@@ -292,10 +296,11 @@
'<(PRODUCT_DIR)/snapshot_blob_host.bin', '<(PRODUCT_DIR)/snapshot_blob_host.bin',
], ],
'action': [ 'action': [
'<@(_inputs)', '<(mksnapshot_exec)',
'<@(mksnapshot_flags)', '<@(mksnapshot_flags)',
'<@(INTERMEDIATE_DIR)/snapshot.cc', '<@(INTERMEDIATE_DIR)/snapshot.cc',
'--startup_blob', '<(PRODUCT_DIR)/snapshot_blob_host.bin', '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob_host.bin',
'<(embed_script)',
], ],
}, { }, {
'outputs': [ 'outputs': [
...@@ -303,10 +308,11 @@ ...@@ -303,10 +308,11 @@
'<(PRODUCT_DIR)/snapshot_blob.bin', '<(PRODUCT_DIR)/snapshot_blob.bin',
], ],
'action': [ 'action': [
'<@(_inputs)', '<(mksnapshot_exec)',
'<@(mksnapshot_flags)', '<@(mksnapshot_flags)',
'<@(INTERMEDIATE_DIR)/snapshot.cc', '<@(INTERMEDIATE_DIR)/snapshot.cc',
'--startup_blob', '<(PRODUCT_DIR)/snapshot_blob.bin', '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob.bin',
'<(embed_script)',
], ],
}], }],
], ],
...@@ -316,10 +322,11 @@ ...@@ -316,10 +322,11 @@
'<(PRODUCT_DIR)/snapshot_blob.bin', '<(PRODUCT_DIR)/snapshot_blob.bin',
], ],
'action': [ 'action': [
'<@(_inputs)', '<(mksnapshot_exec)',
'<@(mksnapshot_flags)', '<@(mksnapshot_flags)',
'<@(INTERMEDIATE_DIR)/snapshot.cc', '<@(INTERMEDIATE_DIR)/snapshot.cc',
'--startup_blob', '<(PRODUCT_DIR)/snapshot_blob.bin', '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob.bin',
'<(embed_script)',
], ],
}], }],
], ],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment