Skip to content

Commit 7997f5f

Browse files
committed
work with the new BaseObject layout in snapshot callbacks
1 parent 096447c commit 7997f5f

8 files changed

+40
-21
lines changed

src/base_object-inl.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ BaseObject::BaseObject(Environment* env, v8::Local<v8::Object> object)
4444
CHECK_EQ(false, object.IsEmpty());
4545
CHECK_GE(object->InternalFieldCount(), BaseObject::kInternalFieldCount);
4646
object->SetAlignedPointerInInternalField(BaseObject::kEmbedderType,
47-
&kNodeEmbedderId);
47+
&kNodeEmbedderId);
4848
object->SetAlignedPointerInInternalField(
4949
BaseObject::kSlot,
5050
static_cast<void*>(this));
@@ -161,8 +161,8 @@ void BaseObject::LazilyInitializedJSTemplateConstructor(
161161
const v8::FunctionCallbackInfo<v8::Value>& args) {
162162
DCHECK(args.IsConstructCall());
163163
CHECK_GE(args.This()->InternalFieldCount(), BaseObject::kInternalFieldCount);
164-
args.This()->SetAlignedPointerInInternalField(
165-
BaseObject::kEmbedderType, &kNodeEmbedderId);
164+
args.This()->SetAlignedPointerInInternalField(BaseObject::kEmbedderType,
165+
&kNodeEmbedderId);
166166
args.This()->SetAlignedPointerInInternalField(BaseObject::kSlot, nullptr);
167167
}
168168

src/env.cc

+1
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,7 @@ void Environment::EnqueueDeserializeRequest(DeserializeRequestCallback cb,
14441444
Local<Object> holder,
14451445
int index,
14461446
InternalFieldInfo* info) {
1447+
DCHECK_EQ(index, BaseObject::kEmbedderType);
14471448
DeserializeRequest request{cb, {isolate(), holder}, index, info};
14481449
deserialize_requests_.push_back(std::move(request));
14491450
}

src/node_blob.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ void BlobBindingData::PrepareForSerialization(
479479
}
480480

481481
InternalFieldInfo* BlobBindingData::Serialize(int index) {
482-
DCHECK_EQ(index, BaseObject::kSlot);
482+
DCHECK_EQ(index, BaseObject::kEmbedderType);
483483
InternalFieldInfo* info = InternalFieldInfo::New(type());
484484
return info;
485485
}

src/node_file.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -2433,7 +2433,7 @@ void BindingData::Deserialize(Local<Context> context,
24332433
Local<Object> holder,
24342434
int index,
24352435
InternalFieldInfo* info) {
2436-
DCHECK_EQ(index, BaseObject::kSlot);
2436+
DCHECK_EQ(index, BaseObject::kEmbedderType);
24372437
HandleScope scope(context->GetIsolate());
24382438
Environment* env = Environment::GetCurrent(context);
24392439
BindingData* binding = env->AddBindingData<BindingData>(context, holder);
@@ -2450,7 +2450,7 @@ void BindingData::PrepareForSerialization(Local<Context> context,
24502450
}
24512451

24522452
InternalFieldInfo* BindingData::Serialize(int index) {
2453-
DCHECK_EQ(index, BaseObject::kSlot);
2453+
DCHECK_EQ(index, BaseObject::kEmbedderType);
24542454
InternalFieldInfo* info = InternalFieldInfo::New(type());
24552455
return info;
24562456
}

src/node_process_methods.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ void BindingData::PrepareForSerialization(Local<Context> context,
531531
}
532532

533533
InternalFieldInfo* BindingData::Serialize(int index) {
534-
DCHECK_EQ(index, BaseObject::kSlot);
534+
DCHECK_EQ(index, BaseObject::kEmbedderType);
535535
InternalFieldInfo* info = InternalFieldInfo::New(type());
536536
return info;
537537
}
@@ -540,7 +540,7 @@ void BindingData::Deserialize(Local<Context> context,
540540
Local<Object> holder,
541541
int index,
542542
InternalFieldInfo* info) {
543-
DCHECK_EQ(index, BaseObject::kSlot);
543+
DCHECK_EQ(index, BaseObject::kEmbedderType);
544544
v8::HandleScope scope(context->GetIsolate());
545545
Environment* env = Environment::GetCurrent(context);
546546
// Recreate the buffer in the constructor.

src/node_snapshotable.cc

+29-6
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,13 @@ void DeserializeNodeInternalFields(Local<Object> holder,
380380
return;
381381
}
382382

383+
DCHECK_EQ(index, BaseObject::kEmbedderType);
383384
Environment* env_ptr = static_cast<Environment*>(env);
384385
const InternalFieldInfo* info =
385386
reinterpret_cast<const InternalFieldInfo*>(payload.data);
386-
387+
// TODO(joyeecheung): we can add a constant kNodeEmbedderId to the
388+
// beginning of every InternalFieldInfo to ensure that we don't
389+
// step on payloads that were not serialized by Node.js.
387390
switch (info->type) {
388391
#define V(PropertyName, NativeTypeName) \
389392
case EmbedderObjectType::k_##PropertyName: { \
@@ -408,13 +411,32 @@ StartupData SerializeNodeContextInternalFields(Local<Object> holder,
408411
"Serialize internal field, index=%d, holder=%p\n",
409412
static_cast<int>(index),
410413
*holder);
411-
void* ptr = holder->GetAlignedPointerFromInternalField(BaseObject::kSlot);
412-
if (ptr == nullptr) {
414+
// We only do one serialization for the kEmbedderType slot, the result
415+
// contains everything necessary for deserializing the entire object,
416+
// including the fields whose index is bigger than kEmbedderType
417+
// (most importantly, BaseObject::kSlot).
418+
// For Node.js this design is enough for all the native binding that are
419+
// serializable.
420+
if (index != BaseObject::kEmbedderType) {
421+
return StartupData{nullptr, 0};
422+
}
423+
424+
void* type_ptr = holder->GetAlignedPointerFromInternalField(index);
425+
if (type_ptr == nullptr) {
426+
return StartupData{nullptr, 0};
427+
}
428+
429+
uint16_t type = *(static_cast<uint16_t*>(type_ptr));
430+
per_process::Debug(DebugCategory::MKSNAPSHOT, "type = 0x%x\n", type);
431+
if (type != kNodeEmbedderId) {
413432
return StartupData{nullptr, 0};
414433
}
415434

416-
DCHECK(static_cast<BaseObject*>(ptr)->is_snapshotable());
417-
SnapshotableObject* obj = static_cast<SnapshotableObject*>(ptr);
435+
void* binding_ptr =
436+
holder->GetAlignedPointerFromInternalField(BaseObject::kSlot);
437+
per_process::Debug(DebugCategory::MKSNAPSHOT, "binding = %p\n", binding_ptr);
438+
DCHECK(static_cast<BaseObject*>(binding_ptr)->is_snapshotable());
439+
SnapshotableObject* obj = static_cast<SnapshotableObject*>(binding_ptr);
418440
per_process::Debug(DebugCategory::MKSNAPSHOT,
419441
"Object %p is %s, ",
420442
*holder,
@@ -434,8 +456,9 @@ void SerializeBindingData(Environment* env,
434456
env->ForEachBindingData([&](FastStringKey key,
435457
BaseObjectPtr<BaseObject> binding) {
436458
per_process::Debug(DebugCategory::MKSNAPSHOT,
437-
"Serialize binding %i, %p, type=%s\n",
459+
"Serialize binding %i (%p), object=%p, type=%s\n",
438460
static_cast<int>(i),
461+
binding.get(),
439462
*(binding->object()),
440463
key.c_str());
441464

src/node_snapshotable.h

-5
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@ enum class EmbedderObjectType : uint8_t {
3030
// When serializing an embedder object, we'll serialize the native states
3131
// into a chunk that can be mapped into a subclass of InternalFieldInfo,
3232
// and pass it into the V8 callback as the payload of StartupData.
33-
// TODO(joyeecheung): the classification of types seem to be wrong.
34-
// We'd need a type for each field of each class of native object.
35-
// Maybe it's fine - we'll just use the type to invoke BaseObject constructors
36-
// and specify that the BaseObject has only one field for us to serialize.
37-
// And for non-BaseObject embedder objects, we'll use field-wise types.
3833
// The memory chunk looks like this:
3934
//
4035
// [ type ] - EmbedderObjectType (a uint8_t)

src/node_v8.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,15 @@ void BindingData::Deserialize(Local<Context> context,
124124
Local<Object> holder,
125125
int index,
126126
InternalFieldInfo* info) {
127-
DCHECK_EQ(index, BaseObject::kSlot);
127+
DCHECK_EQ(index, BaseObject::kEmbedderType);
128128
HandleScope scope(context->GetIsolate());
129129
Environment* env = Environment::GetCurrent(context);
130130
BindingData* binding = env->AddBindingData<BindingData>(context, holder);
131131
CHECK_NOT_NULL(binding);
132132
}
133133

134134
InternalFieldInfo* BindingData::Serialize(int index) {
135-
DCHECK_EQ(index, BaseObject::kSlot);
135+
DCHECK_EQ(index, BaseObject::kEmbedderType);
136136
InternalFieldInfo* info = InternalFieldInfo::New(type());
137137
return info;
138138
}

0 commit comments

Comments
 (0)