summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoyee Cheung <joyeec9h3@gmail.com>2021-07-10 01:54:09 +0800
committerMichaƫl Zasso <targos@protonmail.com>2021-11-21 16:07:37 +0100
commit3a4f3873be8b9a21d362dbc983c2efabcffe76e5 (patch)
treee8bfc425d56be6f6f04d4621480719032522407a
parent88b57bc9d3bab7998c3de0aa787b88233cf46ed4 (diff)
downloadnode-new-3a4f3873be8b9a21d362dbc983c2efabcffe76e5.tar.gz
process: support hrtime in the snapshot
Put the hrtime backing store in the process methods binding data so that it can be integrated into the snapshot builder. For now we simply discard the contents of the hrtime buffer during serialization and create new buffers upon deserialization because the contents are only useful in a synchronous call. This also moves the helper function for creating V8 FastAPI methods into `Environment::SetFastMethod()` for code reuse. The v8::CFunction need to be created before the Environment is created so that we have the CTypeInfo address available for external reference registration. PR-URL: https://github.com/nodejs/node/pull/40649 Refs: https://github.com/nodejs/node/issues/35711 Refs: https://github.com/nodejs/node/issues/37476 Reviewed-By: James M Snell <jasnell@gmail.com>
-rw-r--r--lib/internal/bootstrap/node.js3
-rw-r--r--lib/internal/bootstrap/pre_execution.js11
-rw-r--r--lib/internal/process/per_thread.js67
-rw-r--r--src/env-inl.h45
-rw-r--r--src/env.h20
-rw-r--r--src/node_external_reference.h5
-rw-r--r--src/node_process.h54
-rw-r--r--src/node_process_methods.cc223
-rw-r--r--src/node_snapshotable.cc1
-rw-r--r--src/node_snapshotable.h3
10 files changed, 253 insertions, 179 deletions
diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js
index ae4eac5028..b43fb2a5eb 100644
--- a/lib/internal/bootstrap/node.js
+++ b/lib/internal/bootstrap/node.js
@@ -162,6 +162,9 @@ const rawMethods = internalBinding('process_methods');
process.kill = wrapped.kill;
process.exit = wrapped.exit;
+ process.hrtime = perThreadSetup.hrtime;
+ process.hrtime.bigint = perThreadSetup.hrtimeBigInt;
+
process.openStdin = function() {
process.stdin.resume();
return process.stdin;
diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js
index f2a1064190..71b0afd4e6 100644
--- a/lib/internal/bootstrap/pre_execution.js
+++ b/lib/internal/bootstrap/pre_execution.js
@@ -82,16 +82,7 @@ function patchProcessObject(expandArgv1) {
const binding = internalBinding('process_methods');
binding.patchProcessObject(process);
- // TODO(joyeecheung): snapshot fast APIs (which need to work with
- // array buffers, whose connection with C++ needs to be rebuilt after
- // deserialization).
- const {
- hrtime,
- hrtimeBigInt
- } = require('internal/process/per_thread').getFastAPIs(binding);
-
- process.hrtime = hrtime;
- process.hrtime.bigint = hrtimeBigInt;
+ require('internal/process/per_thread').refreshHrtimeBuffer();
ObjectDefineProperty(process, 'argv0', {
enumerable: true,
diff --git a/lib/internal/process/per_thread.js b/lib/internal/process/per_thread.js
index f1d11911a4..a63217d9b3 100644
--- a/lib/internal/process/per_thread.js
+++ b/lib/internal/process/per_thread.js
@@ -54,49 +54,48 @@ function assert(x, msg) {
if (!x) throw new ERR_ASSERTION(msg || 'assertion error');
}
-function getFastAPIs(binding) {
- const {
- hrtime: _hrtime
- } = binding.getFastAPIs();
+const binding = internalBinding('process_methods');
+
+let hrValues;
+let hrBigintValues;
+function refreshHrtimeBuffer() {
// The 3 entries filled in by the original process.hrtime contains
// the upper/lower 32 bits of the second part of the value,
// and the remaining nanoseconds of the value.
- const hrValues = new Uint32Array(_hrtime.buffer);
+ hrValues = new Uint32Array(binding.hrtimeBuffer);
+ // Use a BigUint64Array in the closure because this is actually a bit
+ // faster than simply returning a BigInt from C++ in V8 7.1.
+ hrBigintValues = new BigUint64Array(binding.hrtimeBuffer, 0, 1);
+}
- function hrtime(time) {
- _hrtime.hrtime();
+// Create the buffers.
+refreshHrtimeBuffer();
- if (time !== undefined) {
- validateArray(time, 'time');
- if (time.length !== 2) {
- throw new ERR_OUT_OF_RANGE('time', 2, time.length);
- }
+function hrtime(time) {
+ binding.hrtime();
- const sec = (hrValues[0] * 0x100000000 + hrValues[1]) - time[0];
- const nsec = hrValues[2] - time[1];
- const needsBorrow = nsec < 0;
- return [needsBorrow ? sec - 1 : sec, needsBorrow ? nsec + 1e9 : nsec];
+ if (time !== undefined) {
+ validateArray(time, 'time');
+ if (time.length !== 2) {
+ throw new ERR_OUT_OF_RANGE('time', 2, time.length);
}
- return [
- hrValues[0] * 0x100000000 + hrValues[1],
- hrValues[2],
- ];
+ const sec = (hrValues[0] * 0x100000000 + hrValues[1]) - time[0];
+ const nsec = hrValues[2] - time[1];
+ const needsBorrow = nsec < 0;
+ return [needsBorrow ? sec - 1 : sec, needsBorrow ? nsec + 1e9 : nsec];
}
- // Use a BigUint64Array in the closure because this is actually a bit
- // faster than simply returning a BigInt from C++ in V8 7.1.
- const hrBigintValues = new BigUint64Array(_hrtime.buffer, 0, 1);
- function hrtimeBigInt() {
- _hrtime.hrtimeBigInt();
- return hrBigintValues[0];
- }
+ return [
+ hrValues[0] * 0x100000000 + hrValues[1],
+ hrValues[2],
+ ];
+}
- return {
- hrtime,
- hrtimeBigInt,
- };
+function hrtimeBigInt() {
+ binding.hrtimeBigInt();
+ return hrBigintValues[0];
}
// The execution of this function itself should not cause any side effects.
@@ -396,8 +395,10 @@ function toggleTraceCategoryState(asyncHooksEnabled) {
module.exports = {
toggleTraceCategoryState,
- getFastAPIs,
assert,
buildAllowedFlags,
- wrapProcessMethods
+ wrapProcessMethods,
+ hrtime,
+ hrtimeBigInt,
+ refreshHrtimeBuffer,
};
diff --git a/src/env-inl.h b/src/env-inl.h
index 1e85bc07a4..04d4edc90b 100644
--- a/src/env-inl.h
+++ b/src/env-inl.h
@@ -29,11 +29,12 @@
#include "callback_queue-inl.h"
#include "env.h"
#include "node.h"
+#include "node_context_data.h"
+#include "node_perf_common.h"
#include "util-inl.h"
#include "uv.h"
+#include "v8-fast-api-calls.h"
#include "v8.h"
-#include "node_perf_common.h"
-#include "node_context_data.h"
#include <cstddef>
#include <cstdint>
@@ -1036,13 +1037,20 @@ inline void Environment::ThrowUVException(int errorno,
UVException(isolate(), errorno, syscall, message, path, dest));
}
-inline v8::Local<v8::FunctionTemplate>
- Environment::NewFunctionTemplate(v8::FunctionCallback callback,
- v8::Local<v8::Signature> signature,
- v8::ConstructorBehavior behavior,
- v8::SideEffectType side_effect_type) {
- return v8::FunctionTemplate::New(isolate(), callback, v8::Local<v8::Value>(),
- signature, 0, behavior, side_effect_type);
+inline v8::Local<v8::FunctionTemplate> Environment::NewFunctionTemplate(
+ v8::FunctionCallback callback,
+ v8::Local<v8::Signature> signature,
+ v8::ConstructorBehavior behavior,
+ v8::SideEffectType side_effect_type,
+ const v8::CFunction* c_function) {
+ return v8::FunctionTemplate::New(isolate(),
+ callback,
+ v8::Local<v8::Value>(),
+ signature,
+ 0,
+ behavior,
+ side_effect_type,
+ c_function);
}
inline void Environment::SetMethod(v8::Local<v8::Object> that,
@@ -1063,6 +1071,25 @@ inline void Environment::SetMethod(v8::Local<v8::Object> that,
function->SetName(name_string); // NODE_SET_METHOD() compatibility.
}
+inline void Environment::SetFastMethod(v8::Local<v8::Object> that,
+ const char* name,
+ v8::FunctionCallback slow_callback,
+ const v8::CFunction* c_function) {
+ v8::Local<v8::Context> context = isolate()->GetCurrentContext();
+ v8::Local<v8::Function> function =
+ NewFunctionTemplate(slow_callback,
+ v8::Local<v8::Signature>(),
+ v8::ConstructorBehavior::kThrow,
+ v8::SideEffectType::kHasNoSideEffect,
+ c_function)
+ ->GetFunction(context)
+ .ToLocalChecked();
+ const v8::NewStringType type = v8::NewStringType::kInternalized;
+ v8::Local<v8::String> name_string =
+ v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
+ that->Set(context, name_string, function).Check();
+}
+
inline void Environment::SetMethodNoSideEffect(v8::Local<v8::Object> that,
const char* name,
v8::FunctionCallback callback) {
diff --git a/src/env.h b/src/env.h
index 7078a8fb4f..c0712d4881 100644
--- a/src/env.h
+++ b/src/env.h
@@ -34,6 +34,7 @@
#include "handle_wrap.h"
#include "node.h"
#include "node_binding.h"
+#include "node_external_reference.h"
#include "node_main_instance.h"
#include "node_options.h"
#include "node_perf_common.h"
@@ -1239,20 +1240,23 @@ class Environment : public MemoryRetainer {
const char* path = nullptr,
const char* dest = nullptr);
- inline v8::Local<v8::FunctionTemplate>
- NewFunctionTemplate(v8::FunctionCallback callback,
- v8::Local<v8::Signature> signature =
- v8::Local<v8::Signature>(),
- v8::ConstructorBehavior behavior =
- v8::ConstructorBehavior::kAllow,
- v8::SideEffectType side_effect =
- v8::SideEffectType::kHasSideEffect);
+ inline v8::Local<v8::FunctionTemplate> NewFunctionTemplate(
+ v8::FunctionCallback callback,
+ v8::Local<v8::Signature> signature = v8::Local<v8::Signature>(),
+ v8::ConstructorBehavior behavior = v8::ConstructorBehavior::kAllow,
+ v8::SideEffectType side_effect = v8::SideEffectType::kHasSideEffect,
+ const v8::CFunction* c_function = nullptr);
// Convenience methods for NewFunctionTemplate().
inline void SetMethod(v8::Local<v8::Object> that,
const char* name,
v8::FunctionCallback callback);
+ inline void SetFastMethod(v8::Local<v8::Object> that,
+ const char* name,
+ v8::FunctionCallback slow_callback,
+ const v8::CFunction* c_function);
+
inline void SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
const char* name,
v8::FunctionCallback callback);
diff --git a/src/node_external_reference.h b/src/node_external_reference.h
index 445ca19f3f..347945a749 100644
--- a/src/node_external_reference.h
+++ b/src/node_external_reference.h
@@ -5,10 +5,13 @@
#include <cinttypes>
#include <vector>
+#include "v8-fast-api-calls.h"
#include "v8.h"
namespace node {
+using CFunctionCallback = void (*)(v8::Local<v8::Value> receiver);
+
// This class manages the external references from the V8 heap
// to the C++ addresses in Node.js.
class ExternalReferenceRegistry {
@@ -16,6 +19,8 @@ class ExternalReferenceRegistry {
ExternalReferenceRegistry();
#define ALLOWED_EXTERNAL_REFERENCE_TYPES(V) \
+ V(CFunctionCallback) \
+ V(const v8::CFunctionInfo*) \
V(v8::FunctionCallback) \
V(v8::AccessorGetterCallback) \
V(v8::AccessorSetterCallback) \
diff --git a/src/node_process.h b/src/node_process.h
index 14c8f65916..68956cb0ac 100644
--- a/src/node_process.h
+++ b/src/node_process.h
@@ -3,10 +3,16 @@
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
+#include "node_snapshotable.h"
+#include "v8-fast-api-calls.h"
#include "v8.h"
namespace node {
+class Environment;
+class MemoryTracker;
+class ExternalReferenceRegistry;
+
v8::MaybeLocal<v8::Object> CreateEnvVarProxy(v8::Local<v8::Context> context,
v8::Isolate* isolate);
@@ -38,6 +44,54 @@ v8::Maybe<bool> ProcessEmitDeprecationWarning(Environment* env,
v8::MaybeLocal<v8::Object> CreateProcessObject(Environment* env);
void PatchProcessObject(const v8::FunctionCallbackInfo<v8::Value>& args);
+namespace process {
+class BindingData : public SnapshotableObject {
+ public:
+ void AddMethods();
+ static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
+
+ SERIALIZABLE_OBJECT_METHODS()
+ static constexpr FastStringKey type_name{"node::process::BindingData"};
+ static constexpr EmbedderObjectType type_int =
+ EmbedderObjectType::k_process_binding_data;
+
+ BindingData(Environment* env, v8::Local<v8::Object> object);
+
+ void MemoryInfo(MemoryTracker* tracker) const override;
+ SET_MEMORY_INFO_NAME(BindingData)
+ SET_SELF_SIZE(BindingData)
+
+ static BindingData* FromV8Value(v8::Local<v8::Value> receiver);
+ static void NumberImpl(BindingData* receiver);
+
+ static void FastNumber(v8::Local<v8::Value> receiver) {
+ NumberImpl(FromV8Value(receiver));
+ }
+
+ static void SlowNumber(const v8::FunctionCallbackInfo<v8::Value>& args);
+
+ static void BigIntImpl(BindingData* receiver);
+
+ static void FastBigInt(v8::Local<v8::Value> receiver) {
+ BigIntImpl(FromV8Value(receiver));
+ }
+
+ static void SlowBigInt(const v8::FunctionCallbackInfo<v8::Value>& args);
+
+ private:
+ static constexpr size_t kBufferSize =
+ std::max(sizeof(uint64_t), sizeof(uint32_t) * 3);
+ v8::Global<v8::ArrayBuffer> array_buffer_;
+ std::shared_ptr<v8::BackingStore> backing_store_;
+
+ // These need to be static so that we have their addresses available to
+ // register as external references in the snapshot at environment creation
+ // time.
+ static v8::CFunction fast_number_;
+ static v8::CFunction fast_bigint_;
+};
+
+} // namespace process
} // namespace node
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#endif // SRC_NODE_PROCESS_H_
diff --git a/src/node_process_methods.cc b/src/node_process_methods.cc
index e1ff446ac1..e4b1680558 100644
--- a/src/node_process_methods.cc
+++ b/src/node_process_methods.cc
@@ -36,14 +36,10 @@ namespace node {
using v8::Array;
using v8::ArrayBuffer;
-using v8::BackingStore;
using v8::CFunction;
-using v8::ConstructorBehavior;
using v8::Context;
using v8::Float64Array;
using v8::FunctionCallbackInfo;
-using v8::FunctionTemplate;
-using v8::Global;
using v8::HeapStatistics;
using v8::Integer;
using v8::Isolate;
@@ -51,9 +47,6 @@ using v8::Local;
using v8::NewStringType;
using v8::Number;
using v8::Object;
-using v8::ObjectTemplate;
-using v8::SideEffectType;
-using v8::Signature;
using v8::String;
using v8::Uint32;
using v8::Value;
@@ -423,124 +416,119 @@ static void ReallyExit(const FunctionCallbackInfo<Value>& args) {
env->Exit(code);
}
-class FastHrtime : public BaseObject {
- public:
- static Local<Object> New(Environment* env) {
- Local<FunctionTemplate> ctor = FunctionTemplate::New(env->isolate());
- ctor->Inherit(BaseObject::GetConstructorTemplate(env));
- Local<ObjectTemplate> otmpl = ctor->InstanceTemplate();
- otmpl->SetInternalFieldCount(FastHrtime::kInternalFieldCount);
-
- auto create_func = [env](auto fast_func, auto slow_func) {
- auto cfunc = CFunction::Make(fast_func);
- return FunctionTemplate::New(env->isolate(),
- slow_func,
- Local<Value>(),
- Local<Signature>(),
- 0,
- ConstructorBehavior::kThrow,
- SideEffectType::kHasNoSideEffect,
- &cfunc);
- };
-
- otmpl->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "hrtime"),
- create_func(FastNumber, SlowNumber));
- otmpl->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "hrtimeBigInt"),
- create_func(FastBigInt, SlowBigInt));
-
- Local<Object> obj = otmpl->NewInstance(env->context()).ToLocalChecked();
-
- Local<ArrayBuffer> ab =
- ArrayBuffer::New(env->isolate(),
- std::max(sizeof(uint64_t), sizeof(uint32_t) * 3));
- new FastHrtime(env, obj, ab);
- obj->Set(
- env->context(), FIXED_ONE_BYTE_STRING(env->isolate(), "buffer"), ab)
- .ToChecked();
-
- return obj;
- }
+namespace process {
- private:
- FastHrtime(Environment* env,
- Local<Object> object,
- Local<ArrayBuffer> ab)
- : BaseObject(env, object),
- array_buffer_(env->isolate(), ab),
- backing_store_(ab->GetBackingStore()) {
- MakeWeak();
- }
+constexpr FastStringKey BindingData::type_name;
- void MemoryInfo(MemoryTracker* tracker) const override {
- tracker->TrackField("array_buffer", array_buffer_);
- }
- SET_MEMORY_INFO_NAME(FastHrtime)
- SET_SELF_SIZE(FastHrtime)
+BindingData::BindingData(Environment* env, v8::Local<v8::Object> object)
+ : SnapshotableObject(env, object, type_int) {
+ Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), kBufferSize);
+ array_buffer_.Reset(env->isolate(), ab);
+ object
+ ->Set(env->context(),
+ FIXED_ONE_BYTE_STRING(env->isolate(), "hrtimeBuffer"),
+ ab)
+ .ToChecked();
+ backing_store_ = ab->GetBackingStore();
+}
- static FastHrtime* FromV8Value(Local<Value> value) {
- Local<Object> v8_object = value.As<Object>();
- return static_cast<FastHrtime*>(
- v8_object->GetAlignedPointerFromInternalField(BaseObject::kSlot));
- }
+v8::CFunction BindingData::fast_number_(v8::CFunction::Make(FastNumber));
+v8::CFunction BindingData::fast_bigint_(v8::CFunction::Make(FastBigInt));
- // This is the legacy version of hrtime before BigInt was introduced in
- // JavaScript.
- // The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
- // so this function instead fills in an Uint32Array with 3 entries,
- // to avoid any integer overflow possibility.
- // The first two entries contain the second part of the value
- // broken into the upper/lower 32 bits to be converted back in JS,
- // because there is no Uint64Array in JS.
- // The third entry contains the remaining nanosecond part of the value.
- static void NumberImpl(FastHrtime* receiver) {
- uint64_t t = uv_hrtime();
- uint32_t* fields = static_cast<uint32_t*>(receiver->backing_store_->Data());
- fields[0] = (t / NANOS_PER_SEC) >> 32;
- fields[1] = (t / NANOS_PER_SEC) & 0xffffffff;
- fields[2] = t % NANOS_PER_SEC;
- }
+void BindingData::AddMethods() {
+ env()->SetFastMethod(object(), "hrtime", SlowNumber, &fast_number_);
+ env()->SetFastMethod(object(), "hrtimeBigInt", SlowBigInt, &fast_bigint_);
+}
- static void FastNumber(Local<Value> receiver) {
- NumberImpl(FromV8Value(receiver));
- }
+void BindingData::RegisterExternalReferences(
+ ExternalReferenceRegistry* registry) {
+ registry->Register(SlowNumber);
+ registry->Register(SlowBigInt);
+ registry->Register(FastNumber);
+ registry->Register(FastBigInt);
+ registry->Register(fast_number_.GetTypeInfo());
+ registry->Register(fast_bigint_.GetTypeInfo());
+}
- static void SlowNumber(const FunctionCallbackInfo<Value>& args) {
- NumberImpl(FromJSObject<FastHrtime>(args.Holder()));
- }
+BindingData* BindingData::FromV8Value(Local<Value> value) {
+ Local<Object> v8_object = value.As<Object>();
+ return static_cast<BindingData*>(
+ v8_object->GetAlignedPointerFromInternalField(BaseObject::kSlot));
+}
- static void BigIntImpl(FastHrtime* receiver) {
- uint64_t t = uv_hrtime();
- uint64_t* fields = static_cast<uint64_t*>(receiver->backing_store_->Data());
- fields[0] = t;
- }
+void BindingData::MemoryInfo(MemoryTracker* tracker) const {
+ tracker->TrackField("array_buffer", array_buffer_);
+}
- static void FastBigInt(Local<Value> receiver) {
- BigIntImpl(FromV8Value(receiver));
- }
+// This is the legacy version of hrtime before BigInt was introduced in
+// JavaScript.
+// The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
+// so this function instead fills in an Uint32Array with 3 entries,
+// to avoid any integer overflow possibility.
+// The first two entries contain the second part of the value
+// broken into the upper/lower 32 bits to be converted back in JS,
+// because there is no Uint64Array in JS.
+// The third entry contains the remaining nanosecond part of the value.
+void BindingData::NumberImpl(BindingData* receiver) {
+ // Make sure we don't accidentally access buffers wiped for snapshot.
+ CHECK(!receiver->array_buffer_.IsEmpty());
+ uint64_t t = uv_hrtime();
+ uint32_t* fields = static_cast<uint32_t*>(receiver->backing_store_->Data());
+ fields[0] = (t / NANOS_PER_SEC) >> 32;
+ fields[1] = (t / NANOS_PER_SEC) & 0xffffffff;
+ fields[2] = t % NANOS_PER_SEC;
+}
- static void SlowBigInt(const FunctionCallbackInfo<Value>& args) {
- BigIntImpl(FromJSObject<FastHrtime>(args.Holder()));
- }
+void BindingData::BigIntImpl(BindingData* receiver) {
+ // Make sure we don't accidentally access buffers wiped for snapshot.
+ CHECK(!receiver->array_buffer_.IsEmpty());
+ uint64_t t = uv_hrtime();
+ uint64_t* fields = static_cast<uint64_t*>(receiver->backing_store_->Data());
+ fields[0] = t;
+}
+
+void BindingData::SlowBigInt(const FunctionCallbackInfo<Value>& args) {
+ BigIntImpl(FromJSObject<BindingData>(args.Holder()));
+}
- Global<ArrayBuffer> array_buffer_;
- std::shared_ptr<BackingStore> backing_store_;
-};
+void BindingData::SlowNumber(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ NumberImpl(FromJSObject<BindingData>(args.Holder()));
+}
-static void GetFastAPIs(const FunctionCallbackInfo<Value>& args) {
- Environment* env = Environment::GetCurrent(args);
- Local<Object> ret = Object::New(env->isolate());
- ret->Set(env->context(),
- FIXED_ONE_BYTE_STRING(env->isolate(), "hrtime"),
- FastHrtime::New(env))
- .ToChecked();
- args.GetReturnValue().Set(ret);
+void BindingData::PrepareForSerialization(Local<Context> context,
+ v8::SnapshotCreator* creator) {
+ // It's not worth keeping.
+ // Release it, we will recreate it when the instance is dehydrated.
+ array_buffer_.Reset();
}
-static void InitializeProcessMethods(Local<Object> target,
- Local<Value> unused,
- Local<Context> context,
- void* priv) {
+InternalFieldInfo* BindingData::Serialize(int index) {
+ DCHECK_EQ(index, BaseObject::kSlot);
+ InternalFieldInfo* info = InternalFieldInfo::New(type());
+ return info;
+}
+
+void BindingData::Deserialize(Local<Context> context,
+ Local<Object> holder,
+ int index,
+ InternalFieldInfo* info) {
+ DCHECK_EQ(index, BaseObject::kSlot);
+ v8::HandleScope scope(context->GetIsolate());
Environment* env = Environment::GetCurrent(context);
+ // Recreate the buffer in the constructor.
+ BindingData* binding = env->AddBindingData<BindingData>(context, holder);
+ CHECK_NOT_NULL(binding);
+}
+
+static void Initialize(Local<Object> target,
+ Local<Value> unused,
+ Local<Context> context,
+ void* priv) {
+ Environment* env = Environment::GetCurrent(context);
+ BindingData* const binding_data =
+ env->AddBindingData<BindingData>(context, target);
+ if (binding_data == nullptr) return;
+ binding_data->AddMethods();
// define various internal methods
if (env->owns_process_state()) {
@@ -567,11 +555,11 @@ static void InitializeProcessMethods(Local<Object> target,
env->SetMethod(target, "reallyExit", ReallyExit);
env->SetMethodNoSideEffect(target, "uptime", Uptime);
env->SetMethod(target, "patchProcessObject", PatchProcessObject);
- env->SetMethod(target, "getFastAPIs", GetFastAPIs);
}
-void RegisterProcessMethodsExternalReferences(
- ExternalReferenceRegistry* registry) {
+void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
+ BindingData::RegisterExternalReferences(registry);
+
registry->Register(DebugProcess);
registry->Register(DebugEnd);
registry->Register(Abort);
@@ -594,12 +582,11 @@ void RegisterProcessMethodsExternalReferences(
registry->Register(ReallyExit);
registry->Register(Uptime);
registry->Register(PatchProcessObject);
- registry->Register(GetFastAPIs);
}
+} // namespace process
} // namespace node
-NODE_MODULE_CONTEXT_AWARE_INTERNAL(process_methods,
- node::InitializeProcessMethods)
+NODE_MODULE_CONTEXT_AWARE_INTERNAL(process_methods, node::process::Initialize)
NODE_MODULE_EXTERNAL_REFERENCE(process_methods,
- node::RegisterProcessMethodsExternalReferences)
+ node::process::RegisterExternalReferences)
diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc
index 6e284bb66a..6f45ce5379 100644
--- a/src/node_snapshotable.cc
+++ b/src/node_snapshotable.cc
@@ -11,6 +11,7 @@
#include "node_file.h"
#include "node_internals.h"
#include "node_main_instance.h"
+#include "node_process.h"
#include "node_v8.h"
#include "node_v8_platform-inl.h"
diff --git a/src/node_snapshotable.h b/src/node_snapshotable.h
index ceb84fc9bf..1ccd9a9322 100644
--- a/src/node_snapshotable.h
+++ b/src/node_snapshotable.h
@@ -16,7 +16,8 @@ struct SnapshotData;
#define SERIALIZABLE_OBJECT_TYPES(V) \
V(fs_binding_data, fs::BindingData) \
V(v8_binding_data, v8_utils::BindingData) \
- V(blob_binding_data, BlobBindingData)
+ V(blob_binding_data, BlobBindingData) \
+ V(process_binding_data, process::BindingData)
enum class EmbedderObjectType : uint8_t {
k_default = 0,