From f46d42d76062a7b51d2df5f6bb4f2c1cb6baafbe Mon Sep 17 00:00:00 2001 From: Onlynagesha Date: Fri, 11 Jul 2025 11:42:22 +0800 Subject: [PATCH] Optimize read barrier with CMC-GC for ArkTS 1.2 Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/ICLMRW Signed-off-by: Onlynagesha Change-Id: I404d0dc33434b70395924e956aa45015367d3919 --- common_components/base_runtime/hooks.h | 2 ++ .../common_runtime/src/mutator/mutator.cpp | 3 +++ common_components/thread/thread_holder.cpp | 7 ++++++- ecmascript/mem/cmc_gc/hooks.cpp | 14 ++++++++++++++ libark_jsruntime.map | 2 ++ 5 files changed, 27 insertions(+), 1 deletion(-) diff --git a/common_components/base_runtime/hooks.h b/common_components/base_runtime/hooks.h index f13d2d1208..8f41bbe112 100644 --- a/common_components/base_runtime/hooks.h +++ b/common_components/base_runtime/hooks.h @@ -33,6 +33,8 @@ PUBLIC_API void RemoveXRefFromDynamicRoots(); PUBLIC_API void VisitJSThread(void *jsThread, CommonRootVisitor visitor); PUBLIC_API void SynchronizeGCPhaseToJSThread(void *jsThread, GCPhase gcPhase); +PUBLIC_API void RegisterSynchronizeGCPhaseToETSMainCoroutineHook(void (*syncFn)(void *coroutine, GCPhase phase)); +PUBLIC_API void SynchronizeGCPhaseToETSMainCoroutine(void *coroutine, GCPhase gcPhase); // CMC-GC dependent interface PUBLIC_API void FillFreeObject(void *object, size_t size); diff --git a/common_components/common_runtime/src/mutator/mutator.cpp b/common_components/common_runtime/src/mutator/mutator.cpp index e6f42b6ed7..d17c88612a 100755 --- a/common_components/common_runtime/src/mutator/mutator.cpp +++ b/common_components/common_runtime/src/mutator/mutator.cpp @@ -259,6 +259,9 @@ void MutatorBase::TransitionToGCPhaseExclusive(GCPhase newPhase) // the JSThread local gc state SynchronizeGCPhaseToJSThread(jsThread_, newPhase); } + if (etsMainCoroutine_ != nullptr) { + SynchronizeGCPhaseToETSMainCoroutine(etsMainCoroutine_, newPhase); + } // Clear mutator's suspend request after phase transition ClearSuspensionFlag(SUSPENSION_FOR_GC_PHASE); // atomic seq-cst } diff --git a/common_components/thread/thread_holder.cpp b/common_components/thread/thread_holder.cpp index c88d58d7ce..adaf058e95 100755 --- a/common_components/thread/thread_holder.cpp +++ b/common_components/thread/thread_holder.cpp @@ -110,12 +110,16 @@ void ThreadHolder::UnregisterJSThread(JSThread *jsThread) } } -void ThreadHolder::RegisterCoroutine(Coroutine *coroutine) +void ThreadHolder::RegisterCoroutine(Coroutine *coroutine, bool isMainCoroutine) { // Expect in Native when calling this func TransferToRunning(); DCHECK_CC(coroutines_.find(coroutine) == coroutines_.end()); coroutines_.insert(coroutine); + if (isMainCoroutine) { + mutatorBase_->RegisterETSMainCoroutine(coroutine); + SynchronizeGCPhaseToETSMainCoroutine(coroutine, mutatorBase_->GetMutatorPhase()); + } TransferToNative(); } @@ -125,6 +129,7 @@ void ThreadHolder::UnregisterCoroutine(Coroutine *coroutine) TransferToRunning(); DCHECK_CC(coroutines_.find(coroutine) != coroutines_.end()); coroutines_.erase(coroutine); + mutatorBase_->UnregisterETSMainCoroutine(); if (coroutines_.empty() && jsThread_ == nullptr) { ThreadHolder::DestroyThreadHolder(this); } diff --git a/ecmascript/mem/cmc_gc/hooks.cpp b/ecmascript/mem/cmc_gc/hooks.cpp index 2b2fd64b43..ef26c019b8 100644 --- a/ecmascript/mem/cmc_gc/hooks.cpp +++ b/ecmascript/mem/cmc_gc/hooks.cpp @@ -33,6 +33,8 @@ using ecmascript::ObjectXRay; using ecmascript::FreeObject; using ecmascript::ObjectSlot; +static void (*g_synchronizeGCPhaseToETSMainCoroutineHook)(void *coroutine, GCPhase gcPhase) = nullptr; + // A fake EcmaVM which will never used, only for unify the BaseRuntime::Init&Fini static ecmascript::EcmaVM *g_fakeEcmaVM = nullptr; static std::mutex g_rtMutexForStatic; @@ -199,6 +201,18 @@ void SynchronizeGCPhaseToJSThread(void *jsThread, GCPhase gcPhase) #endif } +void RegisterSynchronizeGCPhaseToETSMainCoroutineHook(void (*syncFn)(void *, GCPhase)) +{ + g_synchronizeGCPhaseToETSMainCoroutineHook = syncFn; +} + +void SynchronizeGCPhaseToETSMainCoroutine(void *coroutine, GCPhase gcPhase) +{ + if (g_synchronizeGCPhaseToETSMainCoroutineHook != nullptr) { + g_synchronizeGCPhaseToETSMainCoroutineHook(coroutine, gcPhase); + } +} + void SweepThreadLocalJitFort() { ecmascript::Runtime* runtime = ecmascript::Runtime::GetInstance(); diff --git a/libark_jsruntime.map b/libark_jsruntime.map index f3ad4eeefe..e5c1c75113 100644 --- a/libark_jsruntime.map +++ b/libark_jsruntime.map @@ -106,6 +106,8 @@ panda::ThreadHolder::*; panda::VisitJSThread*; panda::SynchronizeGCPhaseToJSThread*; + panda::RegisterSynchronizeGCPhaseToETSMainCoroutineHook*; + panda::SynchronizeGCPhaseToETSMainCoroutine*; panda::FillFreeObject*; panda::SetBaseAddress*; panda::JSGCCallback*; -- Gitee