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_enable_gdbjit = 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_monolithic = false
v8_untrusted_code_mitigations = false
# This tells V8 to write out/Default/gen/v8/snapshot.bin
# Which we can use to build our own snapshot.
v8_use_external_startup_data = true
v8_use_multi_snapshots = false
v8_use_external_startup_data = false
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;
}
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,
const char* js_filename, const char* js_source) {
v8::HandleScope handle_scope(isolate);
@ -233,31 +220,6 @@ void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
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) {
d->isolate = isolate;
// Leaving this code here because it will probably be useful later on, but

View file

@ -30,23 +30,16 @@ template("create_snapshot") {
data = []
exe = rebase_path(get_label_info(":snapshot_creator", "root_out_dir") +
"/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"
sources = [
invoker.js,
]
outputs = [
natives_out_cc,
snapshot_out_cc,
]
args = [
exe,
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),
]

View file

@ -38,10 +38,6 @@ Deno* NewFromSnapshot(void* data, deno_sub_cb cb);
void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
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);
} // namespace deno

View file

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

View file

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

View file

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

View file

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

View file

@ -7,41 +7,59 @@
#include "v8/include/v8.h"
#include "v8/src/base/logging.h"
v8::StartupData StringToStartupData(const std::string& s) {
return v8::StartupData{s.c_str(), s.size()};
namespace deno {
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) {
const char* js_fn = argv[1];
const char* natives_in_bin = 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);
const char* snapshot_out_cc = argv[2];
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;
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();
auto snapshot_blob = deno::MakeSnapshot(&natives_blob, &snapshot_in_blob,
js_fn, js_source.c_str());
auto snapshot_blob = deno::MakeSnapshot(js_fn, js_source.c_str());
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));
}