mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
- Use camel case names for memory retainers inherited from AsyncWrap instead of their provider names (which are all in upper case) - Assign class names to wraps so that they appear in the heap snapshot as nodes with class names as node names. Previously some nodes are named with reference names, which are supposed to be edge names instead. PR-URL: https://github.com/nodejs/node/pull/21939 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
136 lines
4.0 KiB
C++
136 lines
4.0 KiB
C++
#include "sharedarraybuffer_metadata.h"
|
|
#include "base_object.h"
|
|
#include "base_object-inl.h"
|
|
#include "node_errors.h"
|
|
|
|
using v8::Context;
|
|
using v8::Function;
|
|
using v8::FunctionTemplate;
|
|
using v8::Local;
|
|
using v8::Maybe;
|
|
using v8::MaybeLocal;
|
|
using v8::Nothing;
|
|
using v8::Object;
|
|
using v8::SharedArrayBuffer;
|
|
using v8::Value;
|
|
|
|
namespace node {
|
|
namespace worker {
|
|
|
|
namespace {
|
|
|
|
// Yield a JS constructor for SABLifetimePartner objects in the form of a
|
|
// standard API object, that has a single field for containing the raw
|
|
// SABLiftimePartner* pointer.
|
|
Local<Function> GetSABLifetimePartnerConstructor(
|
|
Environment* env, Local<Context> context) {
|
|
Local<FunctionTemplate> templ;
|
|
templ = env->sab_lifetimepartner_constructor_template();
|
|
if (!templ.IsEmpty())
|
|
return templ->GetFunction(context).ToLocalChecked();
|
|
|
|
templ = BaseObject::MakeLazilyInitializedJSTemplate(env);
|
|
templ->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(),
|
|
"SABLifetimePartner"));
|
|
env->set_sab_lifetimepartner_constructor_template(templ);
|
|
|
|
return GetSABLifetimePartnerConstructor(env, context);
|
|
}
|
|
|
|
class SABLifetimePartner : public BaseObject {
|
|
public:
|
|
SABLifetimePartner(Environment* env,
|
|
Local<Object> obj,
|
|
SharedArrayBufferMetadataReference r)
|
|
: BaseObject(env, obj),
|
|
reference(r) {
|
|
MakeWeak();
|
|
}
|
|
|
|
void MemoryInfo(MemoryTracker* tracker) const override {
|
|
tracker->TrackThis(this);
|
|
}
|
|
|
|
ADD_MEMORY_INFO_NAME(SABLifetimePartner)
|
|
|
|
SharedArrayBufferMetadataReference reference;
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
SharedArrayBufferMetadataReference
|
|
SharedArrayBufferMetadata::ForSharedArrayBuffer(
|
|
Environment* env,
|
|
Local<Context> context,
|
|
Local<SharedArrayBuffer> source) {
|
|
Local<Value> lifetime_partner;
|
|
|
|
if (!source->GetPrivate(context,
|
|
env->sab_lifetimepartner_symbol())
|
|
.ToLocal(&lifetime_partner)) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (lifetime_partner->IsObject() &&
|
|
env->sab_lifetimepartner_constructor_template()
|
|
->HasInstance(lifetime_partner)) {
|
|
CHECK(source->IsExternal());
|
|
SABLifetimePartner* partner =
|
|
Unwrap<SABLifetimePartner>(lifetime_partner.As<Object>());
|
|
CHECK_NE(partner, nullptr);
|
|
return partner->reference;
|
|
}
|
|
|
|
if (source->IsExternal()) {
|
|
// If this is an external SharedArrayBuffer but we do not see a lifetime
|
|
// partner object, it was not us who externalized it. In that case, there
|
|
// is no way to serialize it, because it's unclear how the memory
|
|
// is actually owned.
|
|
THROW_ERR_TRANSFERRING_EXTERNALIZED_SHAREDARRAYBUFFER(env);
|
|
return nullptr;
|
|
}
|
|
|
|
SharedArrayBuffer::Contents contents = source->Externalize();
|
|
SharedArrayBufferMetadataReference r(new SharedArrayBufferMetadata(
|
|
contents.Data(), contents.ByteLength()));
|
|
if (r->AssignToSharedArrayBuffer(env, context, source).IsNothing())
|
|
return nullptr;
|
|
return r;
|
|
}
|
|
|
|
Maybe<bool> SharedArrayBufferMetadata::AssignToSharedArrayBuffer(
|
|
Environment* env, Local<Context> context,
|
|
Local<SharedArrayBuffer> target) {
|
|
CHECK(target->IsExternal());
|
|
Local<Function> ctor = GetSABLifetimePartnerConstructor(env, context);
|
|
Local<Object> obj;
|
|
if (!ctor->NewInstance(context).ToLocal(&obj))
|
|
return Nothing<bool>();
|
|
|
|
new SABLifetimePartner(env, obj, shared_from_this());
|
|
return target->SetPrivate(context,
|
|
env->sab_lifetimepartner_symbol(),
|
|
obj);
|
|
}
|
|
|
|
SharedArrayBufferMetadata::SharedArrayBufferMetadata(void* data, size_t size)
|
|
: data(data), size(size) { }
|
|
|
|
SharedArrayBufferMetadata::~SharedArrayBufferMetadata() {
|
|
free(data);
|
|
}
|
|
|
|
MaybeLocal<SharedArrayBuffer> SharedArrayBufferMetadata::GetSharedArrayBuffer(
|
|
Environment* env, Local<Context> context) {
|
|
Local<SharedArrayBuffer> obj =
|
|
SharedArrayBuffer::New(env->isolate(), data, size);
|
|
|
|
if (AssignToSharedArrayBuffer(env, context, obj).IsNothing())
|
|
return MaybeLocal<SharedArrayBuffer>();
|
|
|
|
return obj;
|
|
}
|
|
|
|
} // namespace worker
|
|
} // namespace node
|