Skip to content

Commit

Permalink
bootstrap: include v8 module into the builtin snapshot
Browse files Browse the repository at this point in the history
PR-URL: #36943
Fixes: #35930
Refs: #35711
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
joyeecheung committed Feb 19, 2021
1 parent 8aa9b77 commit 445108d
Show file tree
Hide file tree
Showing 13 changed files with 147 additions and 29 deletions.
1 change: 1 addition & 0 deletions lib/internal/bootstrap/node.js
Expand Up @@ -349,6 +349,7 @@ process.emitWarning = emitWarning;

// Preload modules so that they are included in the builtin snapshot.
require('fs');
require('v8');

function setupPrepareStackTrace() {
const {
Expand Down
15 changes: 8 additions & 7 deletions lib/v8.js
Expand Up @@ -72,12 +72,13 @@ function getHeapSnapshot() {
return new HeapSnapshotStream(handle);
}

// We need to get the buffer from the binding at the callsite since
// it's re-initialized after deserialization.
const binding = internalBinding('v8');

const {
cachedDataVersionTag,
setFlagsFromString: _setFlagsFromString,
heapStatisticsBuffer,
heapSpaceStatisticsBuffer,
heapCodeStatisticsBuffer,
updateHeapStatisticsBuffer,
updateHeapSpaceStatisticsBuffer,
updateHeapCodeStatisticsBuffer,
Expand Down Expand Up @@ -106,7 +107,7 @@ const {
kCodeAndMetadataSizeIndex,
kBytecodeAndMetadataSizeIndex,
kExternalScriptSourceSizeIndex
} = internalBinding('v8');
} = binding;

const kNumberOfHeapSpaces = kHeapSpaces.length;

Expand All @@ -116,7 +117,7 @@ function setFlagsFromString(flags) {
}

function getHeapStatistics() {
const buffer = heapStatisticsBuffer;
const buffer = binding.heapStatisticsBuffer;

updateHeapStatisticsBuffer();

Expand All @@ -137,7 +138,7 @@ function getHeapStatistics() {

function getHeapSpaceStatistics() {
const heapSpaceStatistics = new Array(kNumberOfHeapSpaces);
const buffer = heapSpaceStatisticsBuffer;
const buffer = binding.heapSpaceStatisticsBuffer;

for (let i = 0; i < kNumberOfHeapSpaces; i++) {
updateHeapSpaceStatisticsBuffer(i);
Expand All @@ -154,7 +155,7 @@ function getHeapSpaceStatistics() {
}

function getHeapCodeStatistics() {
const buffer = heapCodeStatisticsBuffer;
const buffer = binding.heapCodeStatisticsBuffer;

updateHeapCodeStatisticsBuffer();
return {
Expand Down
9 changes: 9 additions & 0 deletions src/heap_utils.cc
@@ -1,6 +1,7 @@
#include "diagnosticfilename-inl.h"
#include "env-inl.h"
#include "memory_tracker-inl.h"
#include "node_external_reference.h"
#include "stream_base-inl.h"
#include "util-inl.h"

Expand Down Expand Up @@ -399,7 +400,15 @@ void Initialize(Local<Object> target,
env->SetMethod(target, "createHeapSnapshotStream", CreateHeapSnapshotStream);
}

void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(BuildEmbedderGraph);
registry->Register(TriggerHeapSnapshot);
registry->Register(CreateHeapSnapshotStream);
}

} // namespace heap
} // namespace node

NODE_MODULE_CONTEXT_AWARE_INTERNAL(heap_utils, node::heap::Initialize)
NODE_MODULE_EXTERNAL_REFERENCE(heap_utils,
node::heap::RegisterExternalReferences)
12 changes: 11 additions & 1 deletion src/inspector_profiler.cc
Expand Up @@ -3,8 +3,9 @@
#include "debug_utils-inl.h"
#include "diagnosticfilename-inl.h"
#include "memory_tracker-inl.h"
#include "node_file.h"
#include "node_errors.h"
#include "node_external_reference.h"
#include "node_file.h"
#include "node_internals.h"
#include "util-inl.h"
#include "v8-inspector.h"
Expand Down Expand Up @@ -519,7 +520,16 @@ static void Initialize(Local<Object> target,
env->SetMethod(target, "stopCoverage", StopCoverage);
}

void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(SetCoverageDirectory);
registry->Register(SetSourceMapCacheGetter);
registry->Register(TakeCoverage);
registry->Register(StopCoverage);
}

} // namespace profiler
} // namespace node

NODE_MODULE_CONTEXT_AWARE_INTERNAL(profiler, node::profiler::Initialize)
NODE_MODULE_EXTERNAL_REFERENCE(profiler,
node::profiler::RegisterExternalReferences)
9 changes: 8 additions & 1 deletion src/node_external_reference.h
Expand Up @@ -56,17 +56,22 @@ class ExternalReferenceRegistry {
V(fs) \
V(fs_dir) \
V(handle_wrap) \
V(heap_utils) \
V(messaging) \
V(native_module) \
V(process_methods) \
V(process_object) \
V(task_queue) \
V(url) \
V(util) \
V(serdes) \
V(string_decoder) \
V(stream_wrap) \
V(trace_events) \
V(timers) \
V(types) \
V(uv) \
V(v8) \
V(worker)

#if NODE_HAVE_I18N_SUPPORT
Expand All @@ -76,7 +81,9 @@ class ExternalReferenceRegistry {
#endif // NODE_HAVE_I18N_SUPPORT

#if HAVE_INSPECTOR
#define EXTERNAL_REFERENCE_BINDING_LIST_INSPECTOR(V) V(inspector)
#define EXTERNAL_REFERENCE_BINDING_LIST_INSPECTOR(V) \
V(inspector) \
V(profiler)
#else
#define EXTERNAL_REFERENCE_BINDING_LIST_INSPECTOR(V)
#endif // HAVE_INSPECTOR
Expand Down
36 changes: 31 additions & 5 deletions src/node_serdes.cc
@@ -1,8 +1,9 @@
#include "node_internals.h"
#include "base_object-inl.h"
#include "node_buffer.h"
#include "node_errors.h"
#include "node_external_reference.h"
#include "node_internals.h"
#include "util-inl.h"
#include "base_object-inl.h"

namespace node {

Expand All @@ -26,7 +27,7 @@ using v8::Value;
using v8::ValueDeserializer;
using v8::ValueSerializer;

namespace {
namespace serdes {

class SerializerContext : public BaseObject,
public ValueSerializer::Delegate {
Expand Down Expand Up @@ -503,7 +504,32 @@ void Initialize(Local<Object> target,
env->SetConstructorFunction(target, "Deserializer", des);
}

} // anonymous namespace
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(SerializerContext::New);

registry->Register(SerializerContext::WriteHeader);
registry->Register(SerializerContext::WriteValue);
registry->Register(SerializerContext::ReleaseBuffer);
registry->Register(SerializerContext::TransferArrayBuffer);
registry->Register(SerializerContext::WriteUint32);
registry->Register(SerializerContext::WriteUint64);
registry->Register(SerializerContext::WriteDouble);
registry->Register(SerializerContext::WriteRawBytes);
registry->Register(SerializerContext::SetTreatArrayBufferViewsAsHostObjects);

registry->Register(DeserializerContext::New);
registry->Register(DeserializerContext::ReadHeader);
registry->Register(DeserializerContext::ReadValue);
registry->Register(DeserializerContext::GetWireFormatVersion);
registry->Register(DeserializerContext::TransferArrayBuffer);
registry->Register(DeserializerContext::ReadUint32);
registry->Register(DeserializerContext::ReadUint64);
registry->Register(DeserializerContext::ReadDouble);
registry->Register(DeserializerContext::ReadRawBytes);
}

} // namespace serdes
} // namespace node

NODE_MODULE_CONTEXT_AWARE_INTERNAL(serdes, node::Initialize)
NODE_MODULE_CONTEXT_AWARE_INTERNAL(serdes, node::serdes::Initialize)
NODE_MODULE_EXTERNAL_REFERENCE(serdes, node::serdes::RegisterExternalReferences)
3 changes: 2 additions & 1 deletion src/node_snapshotable.h
Expand Up @@ -13,7 +13,8 @@ class Environment;
struct EnvSerializeInfo;

#define SERIALIZABLE_OBJECT_TYPES(V) \
V(fs_binding_data, fs::BindingData)
V(fs_binding_data, fs::BindingData) \
V(v8_binding_data, v8_utils::BindingData)

enum class EmbedderObjectType : uint8_t {
k_default = 0,
Expand Down
41 changes: 39 additions & 2 deletions src/node_v8.cc
Expand Up @@ -24,6 +24,7 @@
#include "env-inl.h"
#include "memory_tracker-inl.h"
#include "node.h"
#include "node_external_reference.h"
#include "util-inl.h"
#include "v8.h"

Expand All @@ -32,6 +33,7 @@ namespace v8_utils {
using v8::Array;
using v8::Context;
using v8::FunctionCallbackInfo;
using v8::HandleScope;
using v8::HeapCodeStatistics;
using v8::HeapSpaceStatistics;
using v8::HeapStatistics;
Expand All @@ -45,6 +47,7 @@ using v8::Uint32;
using v8::V8;
using v8::Value;


#define HEAP_STATISTICS_PROPERTIES(V) \
V(0, total_heap_size, kTotalHeapSizeIndex) \
V(1, total_heap_size_executable, kTotalHeapSizeExecutableIndex) \
Expand Down Expand Up @@ -85,7 +88,7 @@ static const size_t kHeapCodeStatisticsPropertiesCount =
#undef V

BindingData::BindingData(Environment* env, Local<Object> obj)
: BaseObject(env, obj),
: SnapshotableObject(env, obj, type_int),
heap_statistics_buffer(env->isolate(), kHeapStatisticsPropertiesCount),
heap_space_statistics_buffer(env->isolate(),
kHeapSpaceStatisticsPropertiesCount),
Expand All @@ -105,6 +108,32 @@ BindingData::BindingData(Environment* env, Local<Object> obj)
.Check();
}

void BindingData::PrepareForSerialization(Local<Context> context,
v8::SnapshotCreator* creator) {
// We'll just re-initialize the buffers in the constructor since their
// contents can be thrown away once consumed in the previous call.
heap_statistics_buffer.Release();
heap_space_statistics_buffer.Release();
heap_code_statistics_buffer.Release();
}

void BindingData::Deserialize(Local<Context> context,
Local<Object> holder,
int index,
InternalFieldInfo* info) {
DCHECK_EQ(index, BaseObject::kSlot);
HandleScope scope(context->GetIsolate());
Environment* env = Environment::GetCurrent(context);
BindingData* binding = env->AddBindingData<BindingData>(context, holder);
CHECK_NOT_NULL(binding);
}

InternalFieldInfo* BindingData::Serialize(int index) {
DCHECK_EQ(index, BaseObject::kSlot);
InternalFieldInfo* info = InternalFieldInfo::New(type());
return info;
}

void BindingData::MemoryInfo(MemoryTracker* tracker) const {
tracker->TrackField("heap_statistics_buffer", heap_statistics_buffer);
tracker->TrackField("heap_space_statistics_buffer",
Expand Down Expand Up @@ -168,7 +197,6 @@ void SetFlagsFromString(const FunctionCallbackInfo<Value>& args) {
V8::SetFlagsFromString(*flags, static_cast<size_t>(flags.length()));
}


void Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
Expand Down Expand Up @@ -223,7 +251,16 @@ void Initialize(Local<Object> target,
env->SetMethod(target, "setFlagsFromString", SetFlagsFromString);
}

void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(CachedDataVersionTag);
registry->Register(UpdateHeapStatisticsBuffer);
registry->Register(UpdateHeapCodeStatisticsBuffer);
registry->Register(UpdateHeapSpaceStatisticsBuffer);
registry->Register(SetFlagsFromString);
}

} // namespace v8_utils
} // namespace node

NODE_MODULE_CONTEXT_AWARE_INTERNAL(v8, node::v8_utils::Initialize)
NODE_MODULE_EXTERNAL_REFERENCE(v8, node::v8_utils::RegisterExternalReferences)
7 changes: 6 additions & 1 deletion src/node_v8.h
Expand Up @@ -5,18 +5,23 @@

#include "aliased_buffer.h"
#include "base_object.h"
#include "node_snapshotable.h"
#include "util.h"
#include "v8.h"

namespace node {
class Environment;
struct InternalFieldInfo;

namespace v8_utils {
class BindingData : public BaseObject {
class BindingData : public SnapshotableObject {
public:
BindingData(Environment* env, v8::Local<v8::Object> obj);

SERIALIZABLE_OBJECT_METHODS()
static constexpr FastStringKey type_name{"node::v8::BindingData"};
static constexpr EmbedderObjectType type_int =
EmbedderObjectType::k_v8_binding_data;

AliasedFloat64Array heap_statistics_buffer;
AliasedFloat64Array heap_space_statistics_buffer;
Expand Down
20 changes: 13 additions & 7 deletions src/stream_wrap.cc
Expand Up @@ -25,6 +25,7 @@
#include "env-inl.h"
#include "handle_wrap.h"
#include "node_buffer.h"
#include "node_external_reference.h"
#include "pipe_wrap.h"
#include "req_wrap-inl.h"
#include "tcp_wrap.h"
Expand All @@ -51,20 +52,19 @@ using v8::ReadOnly;
using v8::Signature;
using v8::Value;

void IsConstructCallCallback(const FunctionCallbackInfo<Value>& args) {
CHECK(args.IsConstructCall());
StreamReq::ResetObject(args.This());
}

void LibuvStreamWrap::Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Environment* env = Environment::GetCurrent(context);

auto is_construct_call_callback =
[](const FunctionCallbackInfo<Value>& args) {
CHECK(args.IsConstructCall());
StreamReq::ResetObject(args.This());
};
Local<FunctionTemplate> sw =
FunctionTemplate::New(env->isolate(), is_construct_call_callback);
FunctionTemplate::New(env->isolate(), IsConstructCallCallback);
sw->InstanceTemplate()->SetInternalFieldCount(StreamReq::kInternalFieldCount);

// we need to set handle and callback to null,
Expand All @@ -88,7 +88,7 @@ void LibuvStreamWrap::Initialize(Local<Object> target,
env->set_shutdown_wrap_template(sw->InstanceTemplate());

Local<FunctionTemplate> ww =
FunctionTemplate::New(env->isolate(), is_construct_call_callback);
FunctionTemplate::New(env->isolate(), IsConstructCallCallback);
ww->InstanceTemplate()->SetInternalFieldCount(
StreamReq::kInternalFieldCount);
ww->Inherit(AsyncWrap::GetConstructorTemplate(env));
Expand All @@ -103,6 +103,10 @@ void LibuvStreamWrap::Initialize(Local<Object> target,
env->stream_base_state().GetJSArray()).Check();
}

void LibuvStreamWrap::RegisterExternalReferences(
ExternalReferenceRegistry* registry) {
registry->Register(IsConstructCallCallback);
}

LibuvStreamWrap::LibuvStreamWrap(Environment* env,
Local<Object> object,
Expand Down Expand Up @@ -396,3 +400,5 @@ void LibuvStreamWrap::AfterUvWrite(uv_write_t* req, int status) {

NODE_MODULE_CONTEXT_AWARE_INTERNAL(stream_wrap,
node::LibuvStreamWrap::Initialize)
NODE_MODULE_EXTERNAL_REFERENCE(
stream_wrap, node::LibuvStreamWrap::RegisterExternalReferences)

0 comments on commit 445108d

Please sign in to comment.