From dcc487b9df031a0549e021c3692752f89a60c68d Mon Sep 17 00:00:00 2001 From: zhaoziming Date: Sun, 8 Jun 2025 01:43:33 +0800 Subject: [PATCH] Isolate napi_ref for cross reference Issue: https://gitee.com/openharmony/arkui_napi/issues/ICDESQ Signed-off-by: zhaoziming Change-Id: I9183b2a8568e96fba704429aac098921d1a8e14b --- native_engine/impl/ark/ark_native_engine.cpp | 4 +- .../impl/ark/ark_native_reference.cpp | 78 ++++++++++++------- native_engine/impl/ark/ark_native_reference.h | 46 +++++++---- 3 files changed, 87 insertions(+), 41 deletions(-) diff --git a/native_engine/impl/ark/ark_native_engine.cpp b/native_engine/impl/ark/ark_native_engine.cpp index 7e5fd80b2..a2937b02c 100644 --- a/native_engine/impl/ark/ark_native_engine.cpp +++ b/native_engine/impl/ark/ark_native_engine.cpp @@ -1582,8 +1582,8 @@ NativeReference* ArkNativeEngine::CreateReference(napi_value value, uint32_t ini NativeReference* ArkNativeEngine::CreateXRefReference(napi_value value, uint32_t initialRefcount, bool flag, NapiNativeFinalize callback, void* data) { - ArkNativeReferenceConfig config(initialRefcount, true, flag, callback, data); - return new ArkNativeReference(this, value, config); + ArkNativeReferenceConfig config(initialRefcount, flag, callback, data); + return new ArkXRefNativeReference(this, value, config); } NativeReference* ArkNativeEngine::CreateAsyncReference(napi_value value, uint32_t initialRefcount, diff --git a/native_engine/impl/ark/ark_native_reference.cpp b/native_engine/impl/ark/ark_native_reference.cpp index f086ba26a..720549904 100644 --- a/native_engine/impl/ark/ark_native_reference.cpp +++ b/native_engine/impl/ark/ark_native_reference.cpp @@ -39,23 +39,9 @@ ArkNativeReference::ArkNativeReference(ArkNativeEngine* engine, hint_(hint), nativeBindingSize_(nativeBindingSize) { - ArkNativeReferenceConstructor(initialRefcount, deleteSelf); + ArkNativeReferenceConstructor(initialRefcount, deleteSelf, FreeGlobalCallBack); } -ArkNativeReference::ArkNativeReference(ArkNativeEngine* engine, - napi_value value, - ArkNativeReferenceConfig &config) - : engine_(engine), - value_(), - refCount_(config.initialRefcount), - isProxyReference_(config.isProxyReference), - deleteSelf_(config.deleteSelf), - napiCallback_(config.napiCallback), - data_(config.data) -{ - value_.CreateXRefGloablReference(engine->GetEcmaVm(), LocalValueFromJsValue(value)); - ArkNativeReferenceConstructor(config.initialRefcount, config.deleteSelf); -} ArkNativeReference::ArkNativeReference(ArkNativeEngine* engine, Local value, @@ -76,7 +62,7 @@ ArkNativeReference::ArkNativeReference(ArkNativeEngine* engine, hint_(hint), nativeBindingSize_(nativeBindingSize) { - ArkNativeReferenceConstructor(initialRefcount, deleteSelf); + ArkNativeReferenceConstructor(initialRefcount, deleteSelf, FreeGlobalCallBack); } ArkNativeReference::~ArkNativeReference() @@ -92,11 +78,7 @@ ArkNativeReference::~ArkNativeReference() return; } hasDelete_ = true; - if (isProxyReference_) { - value_.FreeXRefGlobalHandleAddr(); - } else { - value_.FreeGlobalHandleAddr(); - } + value_.FreeGlobalHandleAddr(); FinalizeCallback(FinalizerState::DESTRUCTION); } @@ -179,11 +161,7 @@ void ArkNativeReference::FinalizeCallback(FinalizerState state) void ArkNativeReference::FreeGlobalCallBack(void* ref) { auto that = reinterpret_cast(ref); - if (that->isProxyReference_) { - that->value_.FreeXRefGlobalHandleAddr(); - } else { - that->value_.FreeGlobalHandleAddr(); - } + that->value_.FreeGlobalHandleAddr(); } void ArkNativeReference::NativeFinalizeCallBack(void* ref) @@ -241,3 +219,51 @@ bool ArkNativeReference::IsValidHeapObject() } #endif // PANDA_JS_ETS_HYBRID_MODE + +ArkXRefNativeReference::ArkXRefNativeReference(ArkNativeEngine* engine, + napi_value value, + const ArkNativeReferenceConfig &config) + : ArkNativeReference(engine, config) +{ + value_.CreateXRefGloablReference(engine->GetEcmaVm(), LocalValueFromJsValue(value)); + ArkNativeReferenceConstructor(config.initialRefcount, config.deleteSelf, + FreeXRefGlobalCallBack); +} + +ArkXRefNativeReference::~ArkXRefNativeReference() +{ + VALID_ENGINE_CHECK(engine_, engine_, engineId_); + + if (deleteSelf_ && engine_->GetReferenceManager()) { + engine_->GetReferenceManager()->ReleaseHandler(this); + prev_ = nullptr; + next_ = nullptr; + } + if (value_.IsEmpty()) { + return; + } + hasDelete_ = true; + value_.FreeXRefGlobalHandleAddr(); + FinalizeCallback(FinalizerState::DESTRUCTION); +} + +void ArkXRefNativeReference::FreeXRefGlobalCallBack(void* ref) +{ + auto that = reinterpret_cast(ref); + that->value_.FreeXRefGlobalHandleAddr(); +} + +uint32_t ArkXRefNativeReference::Unref() +{ + if (refCount_ == 0) { + return refCount_; + } + --refCount_; + if (value_.IsEmpty()) { + return refCount_; + } + if (refCount_ == 0) { + value_.SetWeakCallback(reinterpret_cast(this), FreeXRefGlobalCallBack, NativeFinalizeCallBack); + } + return refCount_; +} \ No newline at end of file diff --git a/native_engine/impl/ark/ark_native_reference.h b/native_engine/impl/ark/ark_native_reference.h index 10b0c7367..a13af084d 100644 --- a/native_engine/impl/ark/ark_native_reference.h +++ b/native_engine/impl/ark/ark_native_reference.h @@ -36,23 +36,23 @@ enum class FinalizerState { struct ArkNativeReferenceConfig { uint32_t initialRefcount; - bool isProxyReference; bool deleteSelf; NapiNativeFinalize napiCallback; void* data; - ArkNativeReferenceConfig(uint32_t initialRefcount, - bool isProxyReference, + explicit ArkNativeReferenceConfig(uint32_t initialRefcount, bool deleteSelf = false, NapiNativeFinalize napiCallback = nullptr, void* data = nullptr) : initialRefcount(initialRefcount), - isProxyReference(isProxyReference), deleteSelf(deleteSelf), napiCallback(napiCallback), - data(data) {} + data(data) + {} }; +using WeakRefClearCallBack = void (*)(void*); + class ArkNativeReference : public NativeReference { public: ArkNativeReference(ArkNativeEngine* engine, @@ -64,9 +64,6 @@ public: void* hint = nullptr, bool isAsyncCall = false, size_t nativeBindingSize = 0); - ArkNativeReference(ArkNativeEngine* engine, - napi_value value, - ArkNativeReferenceConfig &config); ArkNativeReference(ArkNativeEngine* engine, Local value, uint32_t initialRefcount, @@ -96,11 +93,22 @@ public: bool IsValidHeapObject(); #endif // PANDA_JS_ETS_HYBRID_MODE -private: - inline void ArkNativeReferenceConstructor(uint32_t initialRefCount, bool deleteSelf) +protected: + ArkNativeReference(ArkNativeEngine* engine, + const ArkNativeReferenceConfig &config) + : engine_(engine), + value_(), + refCount_(config.initialRefcount), + deleteSelf_(config.deleteSelf), + napiCallback_(config.napiCallback), + data_(config.data) + {} + + inline void ArkNativeReferenceConstructor(uint32_t initialRefCount, bool deleteSelf, + WeakRefClearCallBack weakCallback) { if (initialRefCount == 0) { - value_.SetWeakCallback(reinterpret_cast(this), FreeGlobalCallBack, NativeFinalizeCallBack); + value_.SetWeakCallback(reinterpret_cast(this), weakCallback, NativeFinalizeCallBack); } if (deleteSelf) { @@ -118,7 +126,6 @@ private: Global value_; uint32_t refCount_ {0}; - bool isProxyReference_{false}; bool deleteSelf_ {false}; bool isAsyncCall_ {false}; @@ -134,9 +141,22 @@ private: void FinalizeCallback(FinalizerState state); - static void FreeGlobalCallBack(void* ref); static void NativeFinalizeCallBack(void* ref); +private: + static void FreeGlobalCallBack(void* ref); friend class NativeReferenceManager; }; +class ArkXRefNativeReference : public ArkNativeReference { +public: + ArkXRefNativeReference(ArkNativeEngine* engine, + napi_value value, + const ArkNativeReferenceConfig &config); + ~ArkXRefNativeReference() override; + uint32_t Unref() override; + +private: + static void FreeXRefGlobalCallBack(void* ref); +}; + #endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_ARK_NATIVE_REFERENCE_H */ -- Gitee