Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,10 @@ Typical ways of working with internal fields are:
* `obj->GetInternalField(i)` to get a JavaScript value from an internal field.
* `obj->SetInternalField(i, v)` to store a JavaScript value in an
internal field.
* `obj->GetAlignedPointerFromInternalField(i)` to get a `void*` pointer from an
internal field.
* `obj->SetAlignedPointerInInternalField(i, p)` to store a `void*` pointer in an
internal field.
* `obj->GetAlignedPointerFromInternalField(i, EmbedderDataTag::kDefault)` to get
a `void*` pointer from an internal field.
* `obj->SetAlignedPointerInInternalField(i, p, EmbedderDataTag::kDefault)` to store
a `void*` pointer in an internal field.

[`Context`][]s provide the same feature under the name “embedder data”.

Expand Down
16 changes: 10 additions & 6 deletions src/base_object-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,30 +74,34 @@ bool BaseObject::IsBaseObject(IsolateData* isolate_data,
return false;
}

uint16_t* ptr = static_cast<uint16_t*>(
obj->GetAlignedPointerFromInternalField(BaseObject::kEmbedderType));
uint16_t* ptr =
static_cast<uint16_t*>(obj->GetAlignedPointerFromInternalField(
BaseObject::kEmbedderType, EmbedderDataTag::kEmbedderType));
return ptr == isolate_data->embedder_id_for_non_cppgc();
}

void BaseObject::TagBaseObject(IsolateData* isolate_data,
v8::Local<v8::Object> object) {
DCHECK_GE(object->InternalFieldCount(), BaseObject::kInternalFieldCount);
object->SetAlignedPointerInInternalField(
BaseObject::kEmbedderType, isolate_data->embedder_id_for_non_cppgc());
BaseObject::kEmbedderType,
isolate_data->embedder_id_for_non_cppgc(),
EmbedderDataTag::kEmbedderType);
}

void BaseObject::SetInternalFields(IsolateData* isolate_data,
v8::Local<v8::Object> object,
void* slot) {
TagBaseObject(isolate_data, object);
object->SetAlignedPointerInInternalField(BaseObject::kSlot, slot);
object->SetAlignedPointerInInternalField(
BaseObject::kSlot, slot, EmbedderDataTag::kDefault);
}

BaseObject* BaseObject::FromJSObject(v8::Local<v8::Value> value) {
v8::Local<v8::Object> obj = value.As<v8::Object>();
DCHECK_GE(obj->InternalFieldCount(), BaseObject::kInternalFieldCount);
return static_cast<BaseObject*>(
obj->GetAlignedPointerFromInternalField(BaseObject::kSlot));
return static_cast<BaseObject*>(obj->GetAlignedPointerFromInternalField(
BaseObject::kSlot, EmbedderDataTag::kDefault));
}

template <typename T>
Expand Down
3 changes: 2 additions & 1 deletion src/base_object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ BaseObject::~BaseObject() {

{
HandleScope handle_scope(realm()->isolate());
object()->SetAlignedPointerInInternalField(BaseObject::kSlot, nullptr);
object()->SetAlignedPointerInInternalField(
BaseObject::kSlot, nullptr, EmbedderDataTag::kDefault);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/base_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <type_traits> // std::remove_reference
#include "base_object_types.h"
#include "memory_tracker.h"
#include "node_v8_embedder.h"
#include "util.h"
#include "v8.h"

Expand Down
9 changes: 6 additions & 3 deletions src/cppgc_helpers-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ void CppgcMixin::Wrap(T* ptr, Realm* realm, v8::Local<v8::Object> obj) {
v8::Object::Wrap<v8::CppHeapPointerTag::kDefaultTag>(isolate, obj, wrappable);
// Keep the layout consistent with BaseObjects.
obj->SetAlignedPointerInInternalField(
kEmbedderType, realm->isolate_data()->embedder_id_for_cppgc());
obj->SetAlignedPointerInInternalField(kSlot, ptr);
kEmbedderType,
realm->isolate_data()->embedder_id_for_cppgc(),
EmbedderDataTag::kEmbedderType);
obj->SetAlignedPointerInInternalField(kSlot, ptr, EmbedderDataTag::kDefault);
realm->TrackCppgcWrapper(ptr);
}

Expand All @@ -41,7 +43,8 @@ T* CppgcMixin::Unwrap(v8::Local<v8::Object> obj) {
if (obj->InternalFieldCount() != T::kInternalFieldCount) {
return nullptr;
}
T* ptr = static_cast<T*>(obj->GetAlignedPointerFromInternalField(T::kSlot));
T* ptr = static_cast<T*>(obj->GetAlignedPointerFromInternalField(
T::kSlot, EmbedderDataTag::kDefault));
return ptr;
}

Expand Down
5 changes: 2 additions & 3 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,8 @@ inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
if (!ContextEmbedderTag::IsNodeContext(context)) [[unlikely]] {
return nullptr;
}
return static_cast<Environment*>(
context->GetAlignedPointerFromEmbedderData(
ContextEmbedderIndex::kEnvironment));
return static_cast<Environment*>(context->GetAlignedPointerFromEmbedderData(
ContextEmbedderIndex::kEnvironment, EmbedderDataTag::kPerContextData));
}

inline Environment* Environment::GetCurrent(
Expand Down
20 changes: 14 additions & 6 deletions src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -674,12 +674,16 @@ void Environment::AssignToContext(Local<v8::Context> context,
Realm* realm,
const ContextInfo& info) {
context->SetAlignedPointerInEmbedderData(ContextEmbedderIndex::kEnvironment,
this);
context->SetAlignedPointerInEmbedderData(ContextEmbedderIndex::kRealm, realm);
this,
EmbedderDataTag::kPerContextData);
context->SetAlignedPointerInEmbedderData(
ContextEmbedderIndex::kRealm, realm, EmbedderDataTag::kPerContextData);

// ContextifyContexts will update this to a pointer to the native object.
context->SetAlignedPointerInEmbedderData(
ContextEmbedderIndex::kContextifyContext, nullptr);
ContextEmbedderIndex::kContextifyContext,
nullptr,
EmbedderDataTag::kPerContextData);

// This must not be done before other context fields are initialized.
ContextEmbedderTag::TagNodeContext(context);
Expand All @@ -695,11 +699,15 @@ void Environment::AssignToContext(Local<v8::Context> context,
void Environment::UnassignFromContext(Local<v8::Context> context) {
if (!context.IsEmpty()) {
context->SetAlignedPointerInEmbedderData(ContextEmbedderIndex::kEnvironment,
nullptr);
nullptr,
EmbedderDataTag::kPerContextData);
context->SetAlignedPointerInEmbedderData(ContextEmbedderIndex::kRealm,
nullptr);
nullptr,
EmbedderDataTag::kPerContextData);
context->SetAlignedPointerInEmbedderData(
ContextEmbedderIndex::kContextifyContext, nullptr);
ContextEmbedderIndex::kContextifyContext,
nullptr,
EmbedderDataTag::kPerContextData);
}
UntrackContext(context);
}
Expand Down
13 changes: 8 additions & 5 deletions src/histogram.cc
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ HistogramBase::HistogramBase(
MakeWeak();
wrap->SetAlignedPointerInInternalField(
HistogramImpl::InternalFields::kImplField,
static_cast<HistogramImpl*>(this));
static_cast<HistogramImpl*>(this),
EmbedderDataTag::kDefault);
}

HistogramBase::HistogramBase(
Expand All @@ -148,7 +149,8 @@ HistogramBase::HistogramBase(
MakeWeak();
wrap->SetAlignedPointerInInternalField(
HistogramImpl::InternalFields::kImplField,
static_cast<HistogramImpl*>(this));
static_cast<HistogramImpl*>(this),
EmbedderDataTag::kDefault);
}

void HistogramBase::MemoryInfo(MemoryTracker* tracker) const {
Expand Down Expand Up @@ -362,7 +364,8 @@ IntervalHistogram::IntervalHistogram(
MakeWeak();
wrap->SetAlignedPointerInInternalField(
HistogramImpl::InternalFields::kImplField,
static_cast<HistogramImpl*>(this));
static_cast<HistogramImpl*>(this),
EmbedderDataTag::kDefault);
uv_timer_init(env->event_loop(), &timer_);
}

Expand Down Expand Up @@ -600,8 +603,8 @@ double HistogramImpl::FastGetPercentile(Local<Value> receiver,
HistogramImpl* HistogramImpl::FromJSObject(Local<Value> value) {
auto obj = value.As<Object>();
DCHECK_GE(obj->InternalFieldCount(), HistogramImpl::kInternalFieldCount);
return static_cast<HistogramImpl*>(
obj->GetAlignedPointerFromInternalField(HistogramImpl::kImplField));
return static_cast<HistogramImpl*>(obj->GetAlignedPointerFromInternalField(
HistogramImpl::kImplField, EmbedderDataTag::kDefault));
}

std::unique_ptr<worker::TransferData>
Expand Down
5 changes: 3 additions & 2 deletions src/js_udp_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ JSUDPWrap::JSUDPWrap(Environment* env, Local<Object> obj)
: AsyncWrap(env, obj, PROVIDER_JSUDPWRAP) {
MakeWeak();

obj->SetAlignedPointerInInternalField(
kUDPWrapBaseField, static_cast<UDPWrapBase*>(this));
obj->SetAlignedPointerInInternalField(kUDPWrapBaseField,
static_cast<UDPWrapBase*>(this),
EmbedderDataTag::kDefault);
}

int JSUDPWrap::RecvStart() {
Expand Down
7 changes: 5 additions & 2 deletions src/node_context_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#include "node_v8_embedder.h"
#include "util.h"
#include "v8.h"

Expand Down Expand Up @@ -135,7 +136,8 @@ class ContextEmbedderTag {
// context.
context->SetAlignedPointerInEmbedderData(
ContextEmbedderIndex::kContextTag,
ContextEmbedderTag::kNodeContextTagPtr);
ContextEmbedderTag::kNodeContextTagPtr,
EmbedderDataTag::kPerContextData);
}

static inline bool IsNodeContext(v8::Local<v8::Context> context) {
Expand All @@ -147,7 +149,8 @@ class ContextEmbedderTag {
return false;
}
if (context->GetAlignedPointerFromEmbedderData(
ContextEmbedderIndex::kContextTag) !=
ContextEmbedderIndex::kContextTag,
EmbedderDataTag::kPerContextData) !=
ContextEmbedderTag::kNodeContextTagPtr) [[unlikely]] {
return false;
}
Expand Down
10 changes: 7 additions & 3 deletions src/node_contextify.cc
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,12 @@ ContextifyContext::ContextifyContext(Environment* env,
// This should only be done after the initial initializations of the context
// global object is finished.
DCHECK_NULL(v8_context->GetAlignedPointerFromEmbedderData(
ContextEmbedderIndex::kContextifyContext));
ContextEmbedderIndex::kContextifyContext,
EmbedderDataTag::kPerContextData));
v8_context->SetAlignedPointerInEmbedderData(
ContextEmbedderIndex::kContextifyContext, this);
ContextEmbedderIndex::kContextifyContext,
this,
EmbedderDataTag::kPerContextData);
}

void ContextifyContext::InitializeGlobalTemplates(IsolateData* isolate_data) {
Expand Down Expand Up @@ -473,7 +476,8 @@ ContextifyContext* ContextifyContext::Get(Local<Object> object) {
}
return static_cast<ContextifyContext*>(
context->GetAlignedPointerFromEmbedderData(
ContextEmbedderIndex::kContextifyContext));
ContextEmbedderIndex::kContextifyContext,
EmbedderDataTag::kPerContextData));
}

bool ContextifyContext::IsStillInitializing(const ContextifyContext* ctx) {
Expand Down
6 changes: 4 additions & 2 deletions src/node_object_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ class ObjectWrap {
assert(handle->InternalFieldCount() > 0);
// Cast to ObjectWrap before casting to T. A direct cast from void
// to T won't work right when T has more than one base class.
void* ptr = handle->GetAlignedPointerFromInternalField(0);
void* ptr = handle->GetAlignedPointerFromInternalField(
0, v8::kEmbedderDataTypeTagDefault);
ObjectWrap* wrap = static_cast<ObjectWrap*>(ptr);
return static_cast<T*>(wrap);
}
Expand All @@ -75,7 +76,8 @@ class ObjectWrap {
inline void Wrap(v8::Local<v8::Object> handle) {
assert(persistent().IsEmpty());
assert(handle->InternalFieldCount() > 0);
handle->SetAlignedPointerInInternalField(0, this);
handle->SetAlignedPointerInInternalField(
0, this, v8::kEmbedderDataTypeTagDefault);
persistent().Reset(v8::Isolate::GetCurrent(), handle);
MakeWeak();
}
Expand Down
3 changes: 2 additions & 1 deletion src/node_process_methods.cc
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,8 @@ void BindingData::RegisterExternalReferences(
BindingData* BindingData::FromV8Value(Local<Value> value) {
Local<Object> v8_object = value.As<Object>();
return static_cast<BindingData*>(
v8_object->GetAlignedPointerFromInternalField(BaseObject::kSlot));
v8_object->GetAlignedPointerFromInternalField(BaseObject::kSlot,
EmbedderDataTag::kDefault));
}

void BindingData::MemoryInfo(MemoryTracker* tracker) const {
Expand Down
4 changes: 2 additions & 2 deletions src/node_realm-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ inline Realm* Realm::GetCurrent(v8::Local<v8::Context> context) {
if (!ContextEmbedderTag::IsNodeContext(context)) [[unlikely]] {
return nullptr;
}
return static_cast<Realm*>(
context->GetAlignedPointerFromEmbedderData(ContextEmbedderIndex::kRealm));
return static_cast<Realm*>(context->GetAlignedPointerFromEmbedderData(
ContextEmbedderIndex::kRealm, EmbedderDataTag::kPerContextData));
}

inline Realm* Realm::GetCurrent(
Expand Down
11 changes: 7 additions & 4 deletions src/node_snapshotable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1309,7 +1309,8 @@ StartupData SerializeNodeContextData(Local<Context> holder,
case ContextEmbedderIndex::kContextifyContext:
case ContextEmbedderIndex::kRealm:
case ContextEmbedderIndex::kContextTag: {
void* data = holder->GetAlignedPointerFromEmbedderData(index);
void* data = holder->GetAlignedPointerFromEmbedderData(
index, EmbedderDataTag::kPerContextData);
per_process::Debug(
DebugCategory::MKSNAPSHOT,
"Serialize context data, index=%d, holder=%p, ptr=%p\n",
Expand Down Expand Up @@ -1400,7 +1401,8 @@ StartupData SerializeNodeContextInternalFields(Local<Object> holder,
// For the moment we do not set any internal fields in ArrayBuffer
// or ArrayBufferViews, so just return nullptr.
if (holder->IsArrayBuffer() || holder->IsArrayBufferView()) {
CHECK_NULL(holder->GetAlignedPointerFromInternalField(index));
CHECK_NULL(holder->GetAlignedPointerFromInternalField(
index, EmbedderDataTag::kDefault));
return StartupData{nullptr, 0};
}

Expand All @@ -1419,8 +1421,9 @@ StartupData SerializeNodeContextInternalFields(Local<Object> holder,
static_cast<int>(index),
*holder);

BaseObject* object_ptr = static_cast<BaseObject*>(
holder->GetAlignedPointerFromInternalField(BaseObject::kSlot));
BaseObject* object_ptr =
static_cast<BaseObject*>(holder->GetAlignedPointerFromInternalField(
BaseObject::kSlot, EmbedderDataTag::kDefault));
// If the native object is already set to null, ignore it.
if (object_ptr == nullptr) {
return StartupData{nullptr, 0};
Expand Down
26 changes: 26 additions & 0 deletions src/node_v8_embedder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef SRC_NODE_V8_EMBEDDER_H_
#define SRC_NODE_V8_EMBEDDER_H_

#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#include <cstdint>

namespace node {

// Type tags for different kinds of embedder data stored in V8 aligned pointer
// slots.
enum EmbedderDataTag : uint16_t {
// kDefault is used in slots that don't use V8 type tagging.
kDefault = 0,
// kEmbedderType is used by BaseObject to store the kEmbedderType value.
kEmbedderType,
// kPerContextData is used to store data on a `v8::Context`, including
// slots indexed by ContextEmbedderIndex.
kPerContextData,
};

} // namespace node

#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#endif // SRC_NODE_V8_EMBEDDER_H_
Loading
Loading