9 #include "include/libplatform/libplatform.h" 10 #include "src/assembler-arch.h" 11 #include "src/base/platform/platform.h" 12 #include "src/flags.h" 14 #include "src/snapshot/embedded-file-writer.h" 15 #include "src/snapshot/natives.h" 16 #include "src/snapshot/partial-serializer.h" 17 #include "src/snapshot/snapshot.h" 18 #include "src/snapshot/startup-serializer.h" 22 class SnapshotFileWriter {
24 void SetSnapshotFile(
const char* snapshot_cpp_file) {
25 snapshot_cpp_path_ = snapshot_cpp_file;
28 void SetStartupBlobFile(
const char* snapshot_blob_file) {
29 snapshot_blob_path_ = snapshot_blob_file;
32 void WriteSnapshot(v8::StartupData blob)
const {
38 reinterpret_cast<const i::byte*>(blob.data), blob.raw_size);
39 MaybeWriteSnapshotFile(blob_vector);
40 MaybeWriteStartupBlob(blob_vector);
45 if (!snapshot_blob_path_)
return;
47 FILE* fp = GetFileDescriptorOrDie(snapshot_blob_path_);
48 size_t written = fwrite(blob.begin(), 1, blob.length(), fp);
50 if (written != static_cast<size_t>(blob.length())) {
51 i::PrintF(
"Writing snapshot file failed.. Aborting.\n");
52 remove(snapshot_blob_path_);
58 if (!snapshot_cpp_path_)
return;
60 FILE* fp = GetFileDescriptorOrDie(snapshot_cpp_path_);
62 WriteSnapshotFilePrefix(fp);
63 WriteSnapshotFileData(fp, blob);
64 WriteSnapshotFileSuffix(fp);
69 static void WriteSnapshotFilePrefix(FILE* fp) {
70 fprintf(fp,
"// Autogenerated snapshot file. Do not edit.\n\n");
71 fprintf(fp,
"#include \"src/v8.h\"\n");
72 fprintf(fp,
"#include \"src/base/platform/platform.h\"\n\n");
73 fprintf(fp,
"#include \"src/snapshot/snapshot.h\"\n\n");
74 fprintf(fp,
"namespace v8 {\n");
75 fprintf(fp,
"namespace internal {\n\n");
78 static void WriteSnapshotFileSuffix(FILE* fp) {
79 fprintf(fp,
"const v8::StartupData* Snapshot::DefaultSnapshotBlob() {\n");
80 fprintf(fp,
" return &blob;\n");
82 fprintf(fp,
"} // namespace internal\n");
83 fprintf(fp,
"} // namespace v8\n");
86 static void WriteSnapshotFileData(FILE* fp,
88 fprintf(fp,
"static const byte blob_data[] = {\n");
89 WriteBinaryContentsAsCArray(fp, blob);
91 fprintf(fp,
"static const int blob_size = %d;\n", blob.length());
92 fprintf(fp,
"static const v8::StartupData blob =\n");
93 fprintf(fp,
"{ (const char*) blob_data, blob_size };\n");
96 static void WriteBinaryContentsAsCArray(
98 for (
int i = 0;
i < blob.length();
i++) {
99 if ((
i & 0x1F) == 0x1F) fprintf(fp,
"\n");
100 if (
i > 0) fprintf(fp,
",");
101 fprintf(fp,
"%u", static_cast<unsigned char>(blob.at(
i)));
106 static FILE* GetFileDescriptorOrDie(
const char* filename) {
107 FILE* fp = v8::base::OS::FOpen(filename,
"wb");
109 i::PrintF(
"Unable to open file \"%s\" for writing.\n", filename);
115 const char* snapshot_cpp_path_ =
nullptr;
116 const char* snapshot_blob_path_ =
nullptr;
119 char* GetExtraCode(
char* filename,
const char* description) {
120 if (filename ==
nullptr || strlen(filename) == 0)
return nullptr;
121 ::printf(
"Loading script for %s: %s\n", description, filename);
122 FILE* file = v8::base::OS::FOpen(filename,
"rb");
123 if (file ==
nullptr) {
124 fprintf(stderr,
"Failed to open '%s': errno %d\n", filename, errno);
127 fseek(file, 0, SEEK_END);
128 size_t size = ftell(file);
130 char* chars =
new char[size + 1];
132 for (
size_t i = 0;
i < size;) {
133 size_t read = fread(&chars[
i], 1, size -
i, file);
135 fprintf(stderr,
"Failed to read '%s': errno %d\n", filename, errno);
145 const char* utf8_source,
const char* name) {
149 v8::TryCatch try_catch(isolate);
152 .ToLocal(&source_string)) {
163 if (script->
Run(context).IsEmpty())
return false;
164 if (i::FLAG_profile_deserialization) {
165 i::PrintF(
"Executing custom snapshot script %s took %0.3f ms\n", name,
166 timer.Elapsed().InMillisecondsF());
169 CHECK(!try_catch.HasCaught());
173 v8::StartupData CreateSnapshotDataBlob(v8::SnapshotCreator* snapshot_creator,
174 const char* script_source =
nullptr) {
177 v8::StartupData result = {
nullptr, 0};
181 v8::Isolate* isolate = snapshot_creator->GetIsolate();
185 if (script_source !=
nullptr &&
186 !RunExtraCode(isolate, context, script_source,
"<embedded>")) {
189 snapshot_creator->SetDefaultContext(context);
191 result = snapshot_creator->CreateBlob(
192 v8::SnapshotCreator::FunctionCodeHandling::kClear);
195 if (i::FLAG_profile_deserialization) {
196 i::PrintF(
"Creating snapshot took %0.3f ms\n",
197 timer.Elapsed().InMillisecondsF());
203 v8::StartupData WarmUpSnapshotDataBlob(v8::SnapshotCreator* snapshot_creator,
204 const char* warmup_source) {
205 CHECK_NOT_NULL(warmup_source);
212 v8::StartupData result = {
nullptr, 0};
216 v8::Isolate* isolate = snapshot_creator->GetIsolate();
220 if (!RunExtraCode(isolate, context, warmup_source,
"<warm-up>")) {
226 isolate->ContextDisposedNotification(
false);
228 snapshot_creator->SetDefaultContext(context);
230 result = snapshot_creator->CreateBlob(
231 v8::SnapshotCreator::FunctionCodeHandling::kKeep);
234 if (i::FLAG_profile_deserialization) {
235 i::PrintF(
"Warming up snapshot took %0.3f ms\n",
236 timer.Elapsed().InMillisecondsF());
244 writer->WriteEmbedded(&embedded_blob);
248 int main(
int argc,
char** argv) {
249 v8::base::EnsureConsoleOutput();
252 i::FLAG_predictable =
true;
256 int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv,
true);
257 if (result > 0 || (argc > 3) || i::FLAG_help) {
258 ::printf(
"Usage: %s --startup_src=... --startup_blob=... [extras]\n",
260 i::FlagList::PrintHelp();
261 return !i::FLAG_help;
264 i::CpuFeatures::Probe(
true);
265 v8::V8::InitializeICUDefaultLocation(argv[0]);
266 std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
267 v8::V8::InitializePlatform(platform.get());
268 v8::V8::Initialize();
271 SnapshotFileWriter snapshot_writer;
272 snapshot_writer.SetSnapshotFile(i::FLAG_startup_src);
273 snapshot_writer.SetStartupBlobFile(i::FLAG_startup_blob);
276 embedded_writer.SetEmbeddedFile(i::FLAG_embedded_src);
277 embedded_writer.SetEmbeddedVariant(i::FLAG_embedded_variant);
279 std::unique_ptr<char> embed_script(
280 GetExtraCode(argc >= 2 ? argv[1] :
nullptr,
"embedding"));
281 std::unique_ptr<char> warmup_script(
282 GetExtraCode(argc >= 3 ? argv[2] :
nullptr,
"warm up"));
284 i::DisableEmbeddedBlobRefcounting();
285 v8::StartupData blob;
287 v8::Isolate* isolate = v8::Isolate::Allocate();
288 if (i::FLAG_embedded_builtins) {
292 size_t code_range_size =
293 i::kMaximalCodeRangeSize == 0
294 ? i::kMaxPCRelativeCodeRangeInMB
295 : std::min(i::kMaximalCodeRangeSize / i::MB,
296 i::kMaxPCRelativeCodeRangeInMB);
297 i_isolate->heap()->ConfigureHeap(0, 0, code_range_size);
299 v8::SnapshotCreator snapshot_creator(isolate);
300 if (i::FLAG_embedded_builtins) WriteEmbeddedFile(&embedded_writer);
301 blob = CreateSnapshotDataBlob(&snapshot_creator, embed_script.get());
305 CHECK(blob.raw_size > 0 && blob.data !=
nullptr);
306 v8::StartupData cold = blob;
307 v8::SnapshotCreator snapshot_creator(
nullptr, &cold);
308 blob = WarmUpSnapshotDataBlob(&snapshot_creator, warmup_script.get());
313 snapshot_writer.WriteSnapshot(blob);
316 i::FreeCurrentEmbeddedBlob();
319 v8::V8::ShutdownPlatform();
static V8_WARN_UNUSED_RESULT MaybeLocal< Script > Compile(Local< Context > context, Source *source, CompileOptions options=kNoCompileOptions, NoCacheReason no_cache_reason=kNoCacheNoReason)
V8_WARN_UNUSED_RESULT MaybeLocal< Value > Run(Local< Context > context)
static V8_WARN_UNUSED_RESULT MaybeLocal< String > NewFromUtf8(Isolate *isolate, const char *data, v8::NewStringType type, int length=-1)