1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

Snapshot clean ups

- Don't call eval() in mock_runtime - not allowed - see js2c.py.
- Don't use v8_use_external_startup_data
- Move MakeSnapshot to snapshot_creator.cc
- Use logging.h in from_snapshot.cc
This commit is contained in:
Ryan Dahl 2018-06-18 16:02:08 +02:00
parent 064d889af0
commit cc2ae2d316
9 changed files with 56 additions and 97 deletions

View file

@ -24,15 +24,12 @@ default_args = {
v8_embedder_string = "-deno" v8_embedder_string = "-deno"
v8_enable_gdbjit = false v8_enable_gdbjit = false
v8_enable_i18n_support = false v8_enable_i18n_support = false
v8_enable_test_features = false
v8_experimental_extra_library_files = []
v8_extra_library_files = []
v8_imminent_deprecation_warnings = false v8_imminent_deprecation_warnings = false
v8_monolithic = false v8_monolithic = false
v8_untrusted_code_mitigations = false v8_untrusted_code_mitigations = false
v8_use_multi_snapshots = false
# This tells V8 to write out/Default/gen/v8/snapshot.bin v8_use_external_startup_data = false
# Which we can use to build our own snapshot.
v8_use_external_startup_data = true
v8_use_snapshot = true v8_use_snapshot = true
v8_experimental_extra_library_files = []
v8_extra_library_files = []
} }

View file

@ -194,19 +194,6 @@ bool Execute(v8::Local<v8::Context> context, const char* js_filename,
return true; return true;
} }
v8::StartupData SerializeInternalFields(v8::Local<v8::Object> holder, int index,
void* data) {
DCHECK_EQ(data, nullptr); // TODO(ry) pass Deno* object here.
InternalFieldData* embedder_field = static_cast<InternalFieldData*>(
holder->GetAlignedPointerFromInternalField(index));
if (embedder_field == nullptr) return {nullptr, 0};
int size = sizeof(*embedder_field);
char* payload = new char[size];
// We simply use memcpy to serialize the content.
memcpy(payload, embedder_field, size);
return {payload, size};
}
void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context, void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
const char* js_filename, const char* js_source) { const char* js_filename, const char* js_source) {
v8::HandleScope handle_scope(isolate); v8::HandleScope handle_scope(isolate);
@ -233,31 +220,6 @@ void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
CHECK(r); CHECK(r);
} }
v8::StartupData MakeSnapshot(v8::StartupData* prev_natives_blob,
v8::StartupData* prev_snapshot_blob,
const char* js_filename, const char* js_source) {
v8::V8::SetNativesDataBlob(prev_natives_blob);
v8::V8::SetSnapshotDataBlob(prev_snapshot_blob);
auto* creator = new v8::SnapshotCreator(external_references);
auto* isolate = creator->GetIsolate();
v8::Isolate::Scope isolate_scope(isolate);
{
v8::HandleScope handle_scope(isolate);
auto context = v8::Context::New(isolate);
InitializeContext(isolate, context, js_filename, js_source);
creator->SetDefaultContext(context, v8::SerializeInternalFieldsCallback(
SerializeInternalFields, nullptr));
}
// Note that using kKeep here will cause segfaults. This is demoed in the
// "SnapshotBug" test case.
auto snapshot_blob =
creator->CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
return snapshot_blob;
}
void AddIsolate(Deno* d, v8::Isolate* isolate) { void AddIsolate(Deno* d, v8::Isolate* isolate) {
d->isolate = isolate; d->isolate = isolate;
// Leaving this code here because it will probably be useful later on, but // Leaving this code here because it will probably be useful later on, but

View file

@ -30,23 +30,16 @@ template("create_snapshot") {
data = [] data = []
exe = rebase_path(get_label_info(":snapshot_creator", "root_out_dir") + exe = rebase_path(get_label_info(":snapshot_creator", "root_out_dir") +
"/snapshot_creator") "/snapshot_creator")
natives_in_bin = "$root_out_dir/natives_blob.bin"
snapshot_in_bin = "$root_out_dir/snapshot_blob.bin"
natives_out_cc = "$target_gen_dir/natives${suffix}.cc"
snapshot_out_cc = "$target_gen_dir/snapshot${suffix}.cc" snapshot_out_cc = "$target_gen_dir/snapshot${suffix}.cc"
sources = [ sources = [
invoker.js, invoker.js,
] ]
outputs = [ outputs = [
natives_out_cc,
snapshot_out_cc, snapshot_out_cc,
] ]
args = [ args = [
exe, exe,
rebase_path(invoker.js, root_build_dir), rebase_path(invoker.js, root_build_dir),
rebase_path(natives_in_bin, root_build_dir),
rebase_path(snapshot_in_bin, root_build_dir),
rebase_path(natives_out_cc, root_build_dir),
rebase_path(snapshot_out_cc, root_build_dir), rebase_path(snapshot_out_cc, root_build_dir),
] ]

View file

@ -38,10 +38,6 @@ Deno* NewFromSnapshot(void* data, deno_sub_cb cb);
void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context, void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
const char* js_filename, const char* js_source); const char* js_filename, const char* js_source);
v8::StartupData MakeSnapshot(v8::StartupData* prev_natives_blob,
v8::StartupData* prev_snapshot_blob,
const char* js_filename, const char* js_source);
void AddIsolate(Deno* d, v8::Isolate* isolate); void AddIsolate(Deno* d, v8::Isolate* isolate);
} // namespace deno } // namespace deno

View file

@ -44,16 +44,18 @@ class StartupDataCppWriter {
void WritePrefix() { void WritePrefix() {
file_ << "// Autogenerated snapshot file. Do not edit.\n\n"; file_ << "// Autogenerated snapshot file. Do not edit.\n\n";
file_ << "#include \"v8/include/v8.h\"\n\n"; file_ << "#include \"v8/include/v8.h\"\n\n";
file_ << "namespace deno { \n\n";
} }
void WriteSuffix() { void WriteSuffix() {
char buffer[500]; char buffer[500];
snprintf(buffer, sizeof(buffer), snprintf(buffer, sizeof(buffer), "v8::StartupData* StartupBlob_%s() {\n",
"const v8::StartupData* StartupBlob_%s() {\n", name_); name_);
file_ << buffer; file_ << buffer;
snprintf(buffer, sizeof(buffer), " return &%s_blob;\n", name_); snprintf(buffer, sizeof(buffer), " return &%s_blob;\n", name_);
file_ << buffer; file_ << buffer;
file_ << "}\n\n"; file_ << "}\n\n";
file_ << "} // namespace deno\n\n";
} }
void WriteBinaryContentsAsCArray() { void WriteBinaryContentsAsCArray() {
@ -78,7 +80,7 @@ class StartupDataCppWriter {
snprintf(buffer, sizeof(buffer), "static const int %s_blob_size = %llu;\n", snprintf(buffer, sizeof(buffer), "static const int %s_blob_size = %llu;\n",
name_, static_cast<unsigned long long>(data_.size())); name_, static_cast<unsigned long long>(data_.size()));
file_ << buffer; file_ << buffer;
snprintf(buffer, sizeof(buffer), "static const v8::StartupData %s_blob =\n", snprintf(buffer, sizeof(buffer), "static v8::StartupData %s_blob =\n",
name_); name_);
file_ << buffer; file_ << buffer;
snprintf(buffer, sizeof(buffer), snprintf(buffer, sizeof(buffer),

View file

@ -1,31 +1,29 @@
// Copyright 2018 Ryan Dahl <ry@tinyclouds.org> // Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
// All rights reserved. MIT License. // All rights reserved. MIT License.
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <string> #include <string>
#include "v8/include/v8.h" #include "v8/include/v8.h"
#include "v8/src/base/logging.h"
#include "./deno_internal.h" #include "./deno_internal.h"
#include "include/deno.h" #include "include/deno.h"
namespace deno {
#ifdef DENO_MOCK_RUNTIME #ifdef DENO_MOCK_RUNTIME
#include "natives_mock_runtime.cc"
#include "snapshot_mock_runtime.cc" #include "snapshot_mock_runtime.cc"
#else #else
#include "natives_deno.cc"
#include "snapshot_deno.cc" #include "snapshot_deno.cc"
#endif #endif
namespace deno {
std::vector<InternalFieldData*> deserialized_data; std::vector<InternalFieldData*> deserialized_data;
void DeserializeInternalFields(v8::Local<v8::Object> holder, int index, void DeserializeInternalFields(v8::Local<v8::Object> holder, int index,
v8::StartupData payload, void* data) { v8::StartupData payload, void* data) {
assert(data == nullptr); // TODO(ry) pass Deno* object here. DCHECK_EQ(data, nullptr);
if (payload.raw_size == 0) { if (payload.raw_size == 0) {
holder->SetAlignedPointerInInternalField(index, nullptr); holder->SetAlignedPointerInInternalField(index, nullptr);
return; return;
@ -37,13 +35,6 @@ void DeserializeInternalFields(v8::Local<v8::Object> holder, int index,
} }
Deno* NewFromSnapshot(void* data, deno_sub_cb cb) { Deno* NewFromSnapshot(void* data, deno_sub_cb cb) {
auto natives_blob = *StartupBlob_natives();
auto snapshot_blob = *StartupBlob_snapshot();
v8::V8::SetNativesDataBlob(&natives_blob);
v8::V8::SetSnapshotDataBlob(&snapshot_blob);
v8::DeserializeInternalFieldsCallback(DeserializeInternalFields, nullptr);
Deno* d = new Deno; Deno* d = new Deno;
d->currentArgs = nullptr; d->currentArgs = nullptr;
d->cb = cb; d->cb = cb;
@ -52,6 +43,7 @@ Deno* NewFromSnapshot(void* data, deno_sub_cb cb) {
params.array_buffer_allocator = params.array_buffer_allocator =
v8::ArrayBuffer::Allocator::NewDefaultAllocator(); v8::ArrayBuffer::Allocator::NewDefaultAllocator();
params.external_references = external_references; params.external_references = external_references;
params.snapshot_blob = StartupBlob_snapshot();
v8::Isolate* isolate = v8::Isolate::New(params); v8::Isolate* isolate = v8::Isolate::New(params);
AddIsolate(d, isolate); AddIsolate(d, isolate);

View file

@ -1,6 +1,5 @@
// A simple runtime that doesn't involve typescript or protobufs to test // A simple runtime that doesn't involve typescript or protobufs to test
// libdeno. Invoked by mock_runtime_test.cc // libdeno. Invoked by mock_runtime_test.cc
const window = eval("this");
function assert(cond) { function assert(cond) {
if (!cond) throw Error("mock_runtime.js assert failed"); if (!cond) throw Error("mock_runtime.js assert failed");
@ -68,7 +67,6 @@ function DoubleSubFails() {
deno.sub((channel, msg) => assert(false)); deno.sub((channel, msg) => assert(false));
} }
// The following join has caused SnapshotBug to segfault when using kKeep. // The following join has caused SnapshotBug to segfault when using kKeep.
[].join(""); [].join("");

View file

@ -99,5 +99,6 @@ TEST(MockRuntimeTest, SnapshotBug) {
int main(int argc, char** argv) { int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
deno_init(); deno_init();
deno_set_flags(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }

View file

@ -7,41 +7,59 @@
#include "v8/include/v8.h" #include "v8/include/v8.h"
#include "v8/src/base/logging.h" #include "v8/src/base/logging.h"
v8::StartupData StringToStartupData(const std::string& s) { namespace deno {
return v8::StartupData{s.c_str(), s.size()};
v8::StartupData SerializeInternalFields(v8::Local<v8::Object> holder, int index,
void* data) {
DCHECK_EQ(data, nullptr);
InternalFieldData* embedder_field = static_cast<InternalFieldData*>(
holder->GetAlignedPointerFromInternalField(index));
if (embedder_field == nullptr) return {nullptr, 0};
int size = sizeof(*embedder_field);
char* payload = new char[size];
// We simply use memcpy to serialize the content.
memcpy(payload, embedder_field, size);
return {payload, size};
} }
v8::StartupData MakeSnapshot(const char* js_filename, const char* js_source) {
auto* creator = new v8::SnapshotCreator(external_references);
auto* isolate = creator->GetIsolate();
v8::Isolate::Scope isolate_scope(isolate);
{
v8::HandleScope handle_scope(isolate);
auto context = v8::Context::New(isolate);
InitializeContext(isolate, context, js_filename, js_source);
creator->SetDefaultContext(context, v8::SerializeInternalFieldsCallback(
SerializeInternalFields, nullptr));
}
// Note that using kKeep here will cause segfaults. This is demoed in the
// "SnapshotBug" test case.
auto snapshot_blob =
creator->CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
return snapshot_blob;
}
} // namespace deno
int main(int argc, char** argv) { int main(int argc, char** argv) {
const char* js_fn = argv[1]; const char* js_fn = argv[1];
const char* natives_in_bin = argv[2]; const char* snapshot_out_cc = argv[2];
const char* snapshot_in_bin = argv[3];
const char* natives_out_cc = argv[4];
const char* snapshot_out_cc = argv[5];
CHECK_NE(js_fn, nullptr);
CHECK_NE(natives_in_bin, nullptr);
CHECK_NE(snapshot_in_bin, nullptr);
CHECK_NE(natives_out_cc, nullptr);
CHECK_NE(snapshot_out_cc, nullptr);
v8::V8::SetFlagsFromCommandLine(&argc, argv, true); v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
CHECK_EQ(argc, 3);
CHECK_NE(js_fn, nullptr);
CHECK_NE(snapshot_out_cc, nullptr);
std::string js_source; std::string js_source;
CHECK(deno::ReadFileToString(js_fn, &js_source)); CHECK(deno::ReadFileToString(js_fn, &js_source));
std::string natives_str;
CHECK(deno::ReadFileToString(natives_in_bin, &natives_str));
auto natives_blob = StringToStartupData(natives_str);
std::string snapshot_in_str;
CHECK(deno::ReadFileToString(snapshot_in_bin, &snapshot_in_str));
auto snapshot_in_blob = StringToStartupData(snapshot_in_str);
deno_init(); deno_init();
auto snapshot_blob = deno::MakeSnapshot(&natives_blob, &snapshot_in_blob, auto snapshot_blob = deno::MakeSnapshot(js_fn, js_source.c_str());
js_fn, js_source.c_str());
std::string snapshot_str(snapshot_blob.data, snapshot_blob.raw_size); std::string snapshot_str(snapshot_blob.data, snapshot_blob.raw_size);
CHECK(deno::WriteDataAsCpp("natives", natives_out_cc, natives_str));
CHECK(deno::WriteDataAsCpp("snapshot", snapshot_out_cc, snapshot_str)); CHECK(deno::WriteDataAsCpp("snapshot", snapshot_out_cc, snapshot_str));
} }