From 4b18215b0596207084ad97ecfeb254b476e8064a Mon Sep 17 00:00:00 2001 From: yanzhiqi1 Date: Wed, 30 Jul 2025 11:04:17 +0800 Subject: [PATCH 1/2] add SuspendThreadScope Issue: #IC9MK3 Signed-off-by: yanzhiqi1 Change-Id: I4d4952d2d8916cdb8f2031a771930a46bef94fd9 --- .../checkpoint/thread_state_transition.h | 25 +++++++ ecmascript/common.h | 4 +- ecmascript/mem/gc_stats.cpp | 6 +- ecmascript/napi/dfx_jsnapi.cpp | 14 ++-- ecmascript/runtime.cpp | 65 +++++++++++++++++++ ecmascript/runtime.h | 4 ++ 6 files changed, 112 insertions(+), 6 deletions(-) diff --git a/ecmascript/checkpoint/thread_state_transition.h b/ecmascript/checkpoint/thread_state_transition.h index 99e679ee93..04f6fda5e8 100644 --- a/ecmascript/checkpoint/thread_state_transition.h +++ b/ecmascript/checkpoint/thread_state_transition.h @@ -175,5 +175,30 @@ private: ThreadStateTransitionScope scope_; NO_COPY_SEMANTIC(SuspendAllScope); }; + +template +class SuspendOtherScope final { + static_assert(std::is_base_of_v); + static_assert(!std::is_same_v); +public: + explicit SuspendOtherScope(T* self, T* target) + : self_(self), target_(target), scope_(self) + { + TRACE_GC(GCStats::Scope::ScopeId::SuspendOther, SharedHeap::GetInstance()->GetEcmaGCStats()); + ECMA_BYTRACE_NAME(HITRACE_LEVEL_COMMERCIAL, HITRACE_TAG_ARK, "SuspendOther", ""); + Runtime::GetInstance()->SuspendOther(self_, target_); + } + ~SuspendOtherScope() + { + TRACE_GC(GCStats::Scope::ScopeId::ResumeOther, SharedHeap::GetInstance()->GetEcmaGCStats()); + ECMA_BYTRACE_NAME(HITRACE_LEVEL_COMMERCIAL, HITRACE_TAG_ARK, "ResumeOther", ""); + Runtime::GetInstance()->ResumeOther(self_, target_); + } +private: + T* self_; + T* target_; + ThreadStateTransitionScope scope_; + NO_COPY_SEMANTIC(SuspendOtherScope); +}; } // namespace panda::ecmascript #endif // ECMASCRIPT_CHECKPOINT_THREAD_STATE_TRANSITION_H diff --git a/ecmascript/common.h b/ecmascript/common.h index 1c916b79dd..87ac89e995 100644 --- a/ecmascript/common.h +++ b/ecmascript/common.h @@ -53,7 +53,9 @@ namespace ecmascript { V(UpdateWeekRef) \ V(EvacuateRegion) \ V(WaitFinish) \ - V(InvokeNativeFinalizeCallbacks) + V(InvokeNativeFinalizeCallbacks) \ + V(SuspendOther) \ + V(ResumeOther) #define RECORD_DATA(V) \ V(START_OBJ_SIZE) \ diff --git a/ecmascript/mem/gc_stats.cpp b/ecmascript/mem/gc_stats.cpp index 9d4a114544..f34889d986 100644 --- a/ecmascript/mem/gc_stats.cpp +++ b/ecmascript/mem/gc_stats.cpp @@ -799,7 +799,11 @@ void SharedGCStats::PrintSharedGCDuration() << STATS_DESCRIPTION_FORMAT("SuspendAll:") << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::SuspendAll]) << "ms\n" << STATS_DESCRIPTION_FORMAT("ResumeAll:") - << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::ResumeAll]) << "ms"; + << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::ResumeAll]) << "ms\n" + << STATS_DESCRIPTION_FORMAT("SuspendOther:") + << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::SuspendOther]) << "ms\n" + << STATS_DESCRIPTION_FORMAT("ResumeOther:") + << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::ResumeOther]) << "ms"; } size_t SharedGCStats::GetAccumulatedAllocateSize() diff --git a/ecmascript/napi/dfx_jsnapi.cpp b/ecmascript/napi/dfx_jsnapi.cpp index e377c9b54f..f661a89eae 100644 --- a/ecmascript/napi/dfx_jsnapi.cpp +++ b/ecmascript/napi/dfx_jsnapi.cpp @@ -1140,11 +1140,17 @@ void DFXJSNApi::GetMainThreadStackTrace(const EcmaVM *vm, std::string &stackTrac stackTraceStr = ecmascript::JsStackInfo::BuildJsStackTrace( thread, false, false, ecmascript::JS_STACK_TRACE_DEPTH_MAX); } else { - ecmascript::ThreadManagedScope runningScope(thread); - ecmascript::SuspendAllScope suspendScope(thread); auto mainThread = ecmascript::Runtime::GetInstance()->GetMainThread(); - stackTraceStr = ecmascript::JsStackInfo::BuildJsStackTrace( - mainThread, false, false, ecmascript::JS_STACK_TRACE_DEPTH_MAX); + ecmascript::ThreadManagedScope runningScope(thread); + if (g_isEnableCMCGC) { + ecmascript::SuspendAllScope suspendAllScope(thread); + stackTraceStr = ecmascript::JsStackInfo::BuildJsStackTrace( + mainThread, false, false, ecmascript::JS_STACK_TRACE_DEPTH_MAX); + } else { + ecmascript::SuspendOtherScope suspendOtherScope(thread, mainThread); + stackTraceStr = ecmascript::JsStackInfo::BuildJsStackTrace( + mainThread, false, false, ecmascript::JS_STACK_TRACE_DEPTH_MAX); + } } auto sourceMapcb = vm->GetSourceMapCallback(); if (sourceMapcb != nullptr && !stackTraceStr.empty()) { diff --git a/ecmascript/runtime.cpp b/ecmascript/runtime.cpp index a3af7df74a..6a469477d6 100644 --- a/ecmascript/runtime.cpp +++ b/ecmascript/runtime.cpp @@ -362,6 +362,71 @@ void Runtime::ResumeAllThreadsImpl(JSThread *current) } } +void Runtime::SuspendOther(JSThread *current, JSThread *target) +{ + ASSERT(!g_isEnableCMCGC); + ASSERT(current != nullptr); + ASSERT(!current->IsInRunningState()); + SuspendOtherThreadImpl(current, target); +} + +void Runtime::ResumeOther(JSThread *current, JSThread *target) +{ + ASSERT(!g_isEnableCMCGC); + ASSERT(current != nullptr); + ASSERT(!current->IsInRunningState()); + ResumeOtherThreadImpl(current, target); +} + +void Runtime::SuspendOtherThreadImpl(JSThread *current, JSThread *target) +{ + SuspendBarrier barrier; + for (uint32_t iterCount = 1U;; ++iterCount) { + { + LockHolder lock(threadsLock_); + if (suspendNewCount_ == 0) { + suspendNewCount_++; + if (current == target || + std::find(threads_.begin(), threads_.end(), target) == threads_.end()) { + LOG_ECMA(FATAL) << "Invalid target thread!"; + UNREACHABLE(); + } + barrier.Initialize(1); + target->SuspendThread(+1, &barrier); + if (target->IsSuspended()) { + target->PassSuspendBarrier(); + } + return; + } + } + if (iterCount < MAX_SUSPEND_RETRIES) { + LockHolder lock(threadsLock_); + if (suspendNewCount_ != 0) { + threadSuspendCondVar_.Wait(&threadsLock_); + } + } else { + LOG_ECMA(FATAL) << "Too many SuspendOther retries!"; + UNREACHABLE(); + } + } + barrier.Wait(); +} + +void Runtime::ResumeOtherThreadImpl(JSThread *current, JSThread *target) +{ + LockHolder lock(threadsLock_); + if (suspendNewCount_ > 0) { + suspendNewCount_--; + } + if (suspendNewCount_ == 0) { + // Signal to waiting to suspend thread + threadSuspendCondVar_.Signal(); + } + if (target != current) { + target->ResumeThread(true); + } +} + void Runtime::IterateSharedRoot(RootVisitor &visitor) { IterateSerializeRoot(visitor); diff --git a/ecmascript/runtime.h b/ecmascript/runtime.h index f5064272ea..8124b2ba21 100644 --- a/ecmascript/runtime.h +++ b/ecmascript/runtime.h @@ -51,6 +51,8 @@ public: void SuspendAll(JSThread *current); void ResumeAll(JSThread *current); + void SuspendOther(JSThread *current, JSThread *target); + void ResumeOther(JSThread *current, JSThread *target); void IterateSerializeRoot(RootVisitor &v); JSThread *GetMainThread() const @@ -315,6 +317,8 @@ private: ~Runtime(); void SuspendAllThreadsImpl(JSThread *current); void ResumeAllThreadsImpl(JSThread *current); + void SuspendOtherThreadImpl(JSThread *current, JSThread *target); + void ResumeOtherThreadImpl(JSThread *current, JSThread *target); void PreInitialization(const EcmaVM *vm); void PostInitialization(const EcmaVM *vm); -- Gitee From 5816e7aff166a5455742fd29cabe4f61c0dda112 Mon Sep 17 00:00:00 2001 From: yanzhiqi1 Date: Sat, 16 Aug 2025 21:12:53 +0800 Subject: [PATCH 2/2] delete rpath in linux Issue: #ICTB72 Signed-off-by: yanzhiqi1 Change-Id: Ia9a2337d7f153003d61aa68a26f6ad04851a3452 --- ecmascript/dfx/hprof/rawheap_translate/BUILD.gn | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ecmascript/dfx/hprof/rawheap_translate/BUILD.gn b/ecmascript/dfx/hprof/rawheap_translate/BUILD.gn index aa1f90bc8e..f45bb13bc3 100644 --- a/ecmascript/dfx/hprof/rawheap_translate/BUILD.gn +++ b/ecmascript/dfx/hprof/rawheap_translate/BUILD.gn @@ -36,6 +36,10 @@ ohos_executable("rawheap_translator") { "cJSON:cjson_static", ] + if (is_linux) { + remove_configs = [ "//build/config:executable_config" ] + } + install_enable = true part_name = "ets_runtime" subsystem_name = "arkcompiler" -- Gitee