From c5e50da657c82f9fc70d6418b8e82859ce39aaa9 Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Fri, 23 May 2025 16:29:47 +0800 Subject: [PATCH 1/2] [Interop] Support transfer with zero copy Support transfer with zero copy, add some napi apis. Change-Id: I31df7234ac06219e14f64999b49282db05b8b80c Signed-off-by: MockMockBlack --- ecmascript/napi/include/jsnapi_expo.h | 5 ++++ ecmascript/napi/jsnapi_expo.cpp | 43 +++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/ecmascript/napi/include/jsnapi_expo.h b/ecmascript/napi/include/jsnapi_expo.h index c48f47c2a8..f46d7bdaa5 100644 --- a/ecmascript/napi/include/jsnapi_expo.h +++ b/ecmascript/napi/include/jsnapi_expo.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -1129,6 +1130,10 @@ public: void Detach(const EcmaVM *vm); bool IsDetach(const EcmaVM *vm); + + std::tuple GetFinalizer(const EcmaVM *vm); + void SetFinalizer(const EcmaVM *vm, NativePointerCallback finalizer, + void *finalizerHint); }; class PUBLIC_API SendableArrayBufferRef : public ObjectRef { diff --git a/ecmascript/napi/jsnapi_expo.cpp b/ecmascript/napi/jsnapi_expo.cpp index f98cc9802e..df4bd308cc 100644 --- a/ecmascript/napi/jsnapi_expo.cpp +++ b/ecmascript/napi/jsnapi_expo.cpp @@ -14,6 +14,7 @@ */ #include +#include #include "ecmascript/base/json_stringifier.h" #include "ecmascript/base/typed_array_helper-inl.h" @@ -3256,6 +3257,48 @@ bool ArrayBufferRef::IsDetach(const EcmaVM *vm) return arrayBuffer->IsDetach(); } +std::tuple ArrayBufferRef::GetFinalizer(const EcmaVM *vm) { + DCHECK_SPECIAL_VALUE_WITH_RETURN(this, std::make_tuple(nullptr, nullptr)); + + ecmascript::ThreadManagedScope managedScope(vm->GetJSThread()); + JSHandle arrayBuffer(JSNApiHelper::ToJSHandle(this)); + + JSTaggedValue bufferData = arrayBuffer->GetArrayBufferData(); + if (!bufferData.IsJSNativePointer()) { + return std::make_tuple(nullptr, nullptr); + } + + auto deleter = + JSNativePointer::Cast(bufferData.GetTaggedObject())->GetDeleter(); + auto data = JSNativePointer::Cast(bufferData.GetTaggedObject())->GetData(); + + JSNativePointer::Cast(bufferData.GetTaggedObject())->SetData(nullptr); + JSNativePointer::Cast(bufferData.GetTaggedObject())->SetDeleter(nullptr); + + return std::make_tuple(deleter, data); +} + +void ArrayBufferRef::SetFinalizer(const EcmaVM *vm, + NativePointerCallback finalizer, + void *finalizerHint) { + DCHECK_SPECIAL_VALUE(this); + + ecmascript::ThreadManagedScope managedScope(vm->GetJSThread()); + JSHandle arrayBuffer(JSNApiHelper::ToJSHandle(this)); + + JSTaggedValue bufferData = arrayBuffer->GetArrayBufferData(); + if (!bufferData.IsJSNativePointer()) { + return; + } + + auto deleter = + JSNativePointer::Cast(bufferData.GetTaggedObject())->GetDeleter(); + auto data = JSNativePointer::Cast(bufferData.GetTaggedObject())->GetData(); + + JSNativePointer::Cast(bufferData.GetTaggedObject())->SetDeleter(finalizer); + JSNativePointer::Cast(bufferData.GetTaggedObject())->SetData(finalizerHint); +} + Local SendableArrayBufferRef::New(const EcmaVM *vm, int32_t length) { CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm)); -- Gitee From a6e055c4e9dac956f46d79c892742c0e84de408f Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Wed, 2 Jul 2025 11:42:14 +0800 Subject: [PATCH 2/2] [Interop] Support transfer with zero copy Change-Id: Id40c74773e21be0465d3e96f0ca16abe2614aaf5 Signed-off-by: MockMockBlack --- ecmascript/napi/include/jsnapi_expo.h | 3 +++ ecmascript/napi/jsnapi_expo.cpp | 21 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ecmascript/napi/include/jsnapi_expo.h b/ecmascript/napi/include/jsnapi_expo.h index f46d7bdaa5..e936dcc11d 100644 --- a/ecmascript/napi/include/jsnapi_expo.h +++ b/ecmascript/napi/include/jsnapi_expo.h @@ -1134,6 +1134,9 @@ public: std::tuple GetFinalizer(const EcmaVM *vm); void SetFinalizer(const EcmaVM *vm, NativePointerCallback finalizer, void *finalizerHint); + + void DetachForTransferring(const EcmaVM *vm); + bool GetWithNativeAreaAllocator(const EcmaVM *vm); }; class PUBLIC_API SendableArrayBufferRef : public ObjectRef { diff --git a/ecmascript/napi/jsnapi_expo.cpp b/ecmascript/napi/jsnapi_expo.cpp index df4bd308cc..2d535b791d 100644 --- a/ecmascript/napi/jsnapi_expo.cpp +++ b/ecmascript/napi/jsnapi_expo.cpp @@ -3240,6 +3240,14 @@ void *ArrayBufferRef::GetBuffer(const EcmaVM *vm) return JSNativePointer::Cast(bufferData.GetTaggedObject())->GetExternalPointer(); } +void ArrayBufferRef::DetachForTransferring(const EcmaVM *vm) { + CROSS_THREAD_AND_EXCEPTION_CHECK(vm); + ecmascript::ThreadManagedScope managedScope(thread); + // arraybuffer is not shared. Do not need to switch state + JSHandle arrayBuffer(JSNApiHelper::ToJSHandle(this)); + arrayBuffer->Detach(thread, arrayBuffer->GetWithNativeAreaAllocator()); +} + void ArrayBufferRef::Detach(const EcmaVM *vm) { CROSS_THREAD_AND_EXCEPTION_CHECK(vm); @@ -3257,7 +3265,17 @@ bool ArrayBufferRef::IsDetach(const EcmaVM *vm) return arrayBuffer->IsDetach(); } -std::tuple ArrayBufferRef::GetFinalizer(const EcmaVM *vm) { +bool ArrayBufferRef::GetWithNativeAreaAllocator(const EcmaVM *vm) { + DCHECK_SPECIAL_VALUE_WITH_RETURN(this, false); + + ecmascript::ThreadManagedScope managedScope(vm->GetJSThread()); + JSHandle arrayBuffer(JSNApiHelper::ToJSHandle(this)); + + return arrayBuffer->GetWithNativeAreaAllocator(); +} + +std::tuple ArrayBufferRef::GetFinalizer( + const EcmaVM *vm) { DCHECK_SPECIAL_VALUE_WITH_RETURN(this, std::make_tuple(nullptr, nullptr)); ecmascript::ThreadManagedScope managedScope(vm->GetJSThread()); @@ -3272,6 +3290,7 @@ std::tuple ArrayBufferRef::GetFinalizer(const Ecm JSNativePointer::Cast(bufferData.GetTaggedObject())->GetDeleter(); auto data = JSNativePointer::Cast(bufferData.GetTaggedObject())->GetData(); + // TODO ROCK: Set data and deleter to nullptr?????? JSNativePointer::Cast(bufferData.GetTaggedObject())->SetData(nullptr); JSNativePointer::Cast(bufferData.GetTaggedObject())->SetDeleter(nullptr); -- Gitee