GYPFLAGS += -Dlsan=1
endif
endif
+ifdef embedscript
+ GYPFLAGS += -Dembed_script=$(embedscript)
+endif
# arm specific flags.
# arm_version=<number | "default">
* Returns { NULL, 0 } on failure.
* The caller owns the data array in the return value.
*/
- static StartupData CreateSnapshotDataBlob();
+ static StartupData CreateSnapshotDataBlob(char* custom_source = NULL);
/**
* Adds a message listener.
}
-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;
params.enable_serializer = true;
Isolate* isolate = v8::Isolate::New(params);
Persistent<Context> context;
{
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()) {
// Make sure all builtin scripts are cached.
static void PrintDeserializedCodeInfo(Handle<JSFunction> function) {
if (function->code() == function->shared()->code() &&
function->shared()->deserialized()) {
- PrintF("Running deserialized script ");
+ PrintF("[Running deserialized script");
Object* script = function->shared()->script();
- if (script->IsScript()) Script::cast(script)->name()->ShortPrint();
- PrintF("\n");
+ if (script->IsScript()) {
+ Object* name = Script::cast(script)->name();
+ if (name->IsString()) {
+ PrintF(": %s", String::cast(name)->ToCString().get());
+ }
+ }
+ PrintF("]\n");
}
}
};
+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) {
// By default, log code create information in the snapshot.
i::FLAG_log_code = true;
// Print the usage if an error occurs when parsing the command line
// flags or if the help flag is set.
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]);
i::FlagList::PrintHelp();
return !i::FLAG_help;
{
SnapshotWriter writer(argv[1]);
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);
writer.WriteSnapshot(blob);
+ delete[] extra_code;
delete[] blob.data;
}
if (FLAG_profile_deserialization) timer.Start();
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);
bool success = isolate->Init(&deserializer);
if (FLAG_profile_deserialization) {
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;
}
Handle<Context> Snapshot::NewContextFromSnapshot(Isolate* isolate) {
if (!HaveASnapshotToStartFrom()) return Handle<Context>();
+ base::ElapsedTimer timer;
+ if (FLAG_profile_deserialization) timer.Start();
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);
Object* root;
deserializer.DeserializePartial(isolate, &root);
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));
}
'icu_use_data_file_flag%': 0,
'v8_code': 1,
'v8_random_seed%': 314159265,
+ 'embed_script%': "",
+ 'mksnapshot_exec': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot<(EXECUTABLE_SUFFIX)',
},
'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'],
'targets': [
{
'action_name': 'run_mksnapshot',
'inputs': [
- '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot<(EXECUTABLE_SUFFIX)',
+ '<(mksnapshot_exec)',
+ '<(embed_script)',
],
'outputs': [
'<(INTERMEDIATE_DIR)/snapshot.cc',
],
},
'action': [
- '<@(_inputs)',
+ '<(mksnapshot_exec)',
'<@(mksnapshot_flags)',
- '<@(INTERMEDIATE_DIR)/snapshot.cc'
+ '<@(INTERMEDIATE_DIR)/snapshot.cc',
+ '<(embed_script)',
],
},
],
{
'action_name': 'run_mksnapshot (external)',
'inputs': [
- '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot<(EXECUTABLE_SUFFIX)',
+ '<(mksnapshot_exec)',
],
'variables': {
'mksnapshot_flags': [
'<(PRODUCT_DIR)/snapshot_blob_host.bin',
],
'action': [
- '<@(_inputs)',
+ '<(mksnapshot_exec)',
'<@(mksnapshot_flags)',
'<@(INTERMEDIATE_DIR)/snapshot.cc',
'--startup_blob', '<(PRODUCT_DIR)/snapshot_blob_host.bin',
+ '<(embed_script)',
],
}, {
'outputs': [
'<(PRODUCT_DIR)/snapshot_blob.bin',
],
'action': [
- '<@(_inputs)',
+ '<(mksnapshot_exec)',
'<@(mksnapshot_flags)',
'<@(INTERMEDIATE_DIR)/snapshot.cc',
'--startup_blob', '<(PRODUCT_DIR)/snapshot_blob.bin',
+ '<(embed_script)',
],
}],
],
'<(PRODUCT_DIR)/snapshot_blob.bin',
],
'action': [
- '<@(_inputs)',
+ '<(mksnapshot_exec)',
'<@(mksnapshot_flags)',
'<@(INTERMEDIATE_DIR)/snapshot.cc',
'--startup_blob', '<(PRODUCT_DIR)/snapshot_blob.bin',
+ '<(embed_script)',
],
}],
],