bootstrap: include v8 module into the builtin snapshot

PR-URL: https://github.com/nodejs/node/pull/36943
Fixes: https://github.com/nodejs/node/issues/35930
Refs: https://github.com/nodejs/node/issues/35711
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Joyee Cheung 2021-02-08 23:19:37 +08:00
parent 8aa9b772f4
commit 445108dc30
No known key found for this signature in database
GPG Key ID: 92B78A53C8303B8D
13 changed files with 147 additions and 29 deletions

View File

@ -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 {

View File

@ -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,
@ -106,7 +107,7 @@ const {
kCodeAndMetadataSizeIndex,
kBytecodeAndMetadataSizeIndex,
kExternalScriptSourceSizeIndex
} = internalBinding('v8');
} = binding;
const kNumberOfHeapSpaces = kHeapSpaces.length;
@ -116,7 +117,7 @@ function setFlagsFromString(flags) {
}
function getHeapStatistics() {
const buffer = heapStatisticsBuffer;
const buffer = binding.heapStatisticsBuffer;
updateHeapStatisticsBuffer();
@ -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);
@ -154,7 +155,7 @@ function getHeapSpaceStatistics() {
}
function getHeapCodeStatistics() {
const buffer = heapCodeStatisticsBuffer;
const buffer = binding.heapCodeStatisticsBuffer;
updateHeapCodeStatisticsBuffer();
return {

View File

@ -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"
@ -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)

View File

@ -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"
@ -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)

View File

@ -56,6 +56,7 @@ class ExternalReferenceRegistry {
V(fs) \
V(fs_dir) \
V(handle_wrap) \
V(heap_utils) \
V(messaging) \
V(native_module) \
V(process_methods) \
@ -63,10 +64,14 @@ class ExternalReferenceRegistry {
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
@ -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

View File

@ -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 {
@ -26,7 +27,7 @@ using v8::Value;
using v8::ValueDeserializer;
using v8::ValueSerializer;
namespace {
namespace serdes {
class SerializerContext : public BaseObject,
public ValueSerializer::Delegate {
@ -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)

View File

@ -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,

View File

@ -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"
@ -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;
@ -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) \
@ -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),
@ -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",
@ -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,
@ -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)

View File

@ -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;

View File

@ -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"
@ -51,6 +52,10 @@ 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,
@ -58,13 +63,8 @@ void LibuvStreamWrap::Initialize(Local<Object> target,
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,
@ -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));
@ -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,
@ -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)

View File

@ -31,6 +31,7 @@
namespace node {
class Environment;
class ExternalReferenceRegistry;
class LibuvStreamWrap : public HandleWrap, public StreamBase {
public:
@ -38,7 +39,7 @@ class LibuvStreamWrap : public HandleWrap, public StreamBase {
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
int GetFD() override;
bool IsAlive() override;
bool IsClosing() override;

View File

@ -22,6 +22,7 @@
#include "uv.h"
#include "env-inl.h"
#include "node.h"
#include "node_external_reference.h"
#include "node_process.h"
namespace node {
@ -42,7 +43,7 @@ static const struct UVError uv_errors_map[] = {
};
} // namespace per_process
namespace {
namespace uv {
using v8::Array;
using v8::Context;
@ -130,7 +131,12 @@ void Initialize(Local<Object> target,
env->SetMethod(target, "getErrorMap", GetErrMap);
}
} // anonymous namespace
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(ErrName);
registry->Register(GetErrMap);
}
} // namespace uv
} // namespace node
NODE_MODULE_CONTEXT_AWARE_INTERNAL(uv, node::Initialize)
NODE_MODULE_CONTEXT_AWARE_INTERNAL(uv, node::uv::Initialize)
NODE_MODULE_EXTERNAL_REFERENCE(uv, node::uv::RegisterExternalReferences)

View File

@ -18,12 +18,15 @@ const expectedModules = new Set([
'Internal Binding fs',
'Internal Binding fs_dir',
'Internal Binding fs_event_wrap',
'Internal Binding heap_utils',
'Internal Binding messaging',
'Internal Binding module_wrap',
'Internal Binding native_module',
'Internal Binding options',
'Internal Binding process_methods',
'Internal Binding report',
'Internal Binding serdes',
'Internal Binding stream_wrap',
'Internal Binding string_decoder',
'Internal Binding symbols',
'Internal Binding task_queue',
@ -33,6 +36,7 @@ const expectedModules = new Set([
'Internal Binding url',
'Internal Binding util',
'Internal Binding uv',
'Internal Binding v8',
'Internal Binding worker',
'NativeModule buffer',
'NativeModule events',
@ -54,6 +58,7 @@ const expectedModules = new Set([
'NativeModule internal/fs/promises',
'NativeModule internal/fs/rimraf',
'NativeModule internal/fs/watchers',
'NativeModule internal/heap_utils',
'NativeModule internal/idna',
'NativeModule internal/linkedlist',
'NativeModule internal/modules/run_main',
@ -81,6 +86,7 @@ const expectedModules = new Set([
'NativeModule internal/process/warning',
'NativeModule internal/querystring',
'NativeModule internal/source_map/source_map_cache',
'NativeModule internal/stream_base_commons',
'NativeModule internal/streams/add-abort-signal',
'NativeModule internal/streams/buffer_list',
'NativeModule internal/streams/destroy',
@ -111,6 +117,7 @@ const expectedModules = new Set([
'NativeModule timers',
'NativeModule url',
'NativeModule util',
'NativeModule v8',
'NativeModule vm',
]);
@ -150,6 +157,7 @@ if (process.features.inspector) {
expectedModules.add('Internal Binding inspector');
expectedModules.add('NativeModule internal/inspector_async_hook');
expectedModules.add('NativeModule internal/util/inspector');
expectedModules.add('Internal Binding profiler');
}
if (process.env.NODE_V8_COVERAGE) {