From 2b52d33845626d3d749df98b7eaebe9f53cca978 Mon Sep 17 00:00:00 2001 From: ivagin Date: Fri, 6 Jun 2025 14:14:30 +0300 Subject: [PATCH] Support object pinning in CMC GC Issue: ICD92C Signed-off-by: ivagin --- common_interfaces/heap/heap_allocator.h | 3 ++ static_core/runtime/include/mem/allocator.h | 4 +- .../cmc-gc-adapter/cmc-allocator-adapter.cpp | 16 ++++++++ .../gc/cmc-gc-adapter/cmc-allocator-adapter.h | 3 ++ .../mem/gc/cmc-gc-adapter/cmc-gc-adapter.cpp | 4 ++ .../mem/gc/cmc-gc-adapter/cmc-gc-adapter.h | 2 +- static_core/tools/ark_js_napi_cli/BUILD.gn | 6 ++- .../tests/cmc_gc_object_pinning.ts | 38 +++++++++++++++++++ .../tests/ets/gc_test_sts_common.ets | 29 ++++++++++++++ .../tests/test_list_hybrid.txt | 1 + 10 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 static_core/tools/ark_js_napi_cli/tests/cmc_gc_object_pinning.ts create mode 100644 static_core/tools/ark_js_napi_cli/tests/test_list_hybrid.txt diff --git a/common_interfaces/heap/heap_allocator.h b/common_interfaces/heap/heap_allocator.h index 0ac0955b8b..5c2a969e18 100644 --- a/common_interfaces/heap/heap_allocator.h +++ b/common_interfaces/heap/heap_allocator.h @@ -39,6 +39,9 @@ public: static Address AllocateRegion(); static Address AllocatePinnedRegion(); static Address AllocateLargeRegion(size_t size); + + static void PinObject(Address obj); + static void UnpinObject(Address obj); }; } // namespace panda #endif // COMMON_INTERFACES_HEAP_ALLOCATOR_H diff --git a/static_core/runtime/include/mem/allocator.h b/static_core/runtime/include/mem/allocator.h index a5909f198f..6d6e852a2f 100644 --- a/static_core/runtime/include/mem/allocator.h +++ b/static_core/runtime/include/mem/allocator.h @@ -686,9 +686,9 @@ public: return false; } - void PinObject([[maybe_unused]] ObjectHeader *object) final {} + void PinObject([[maybe_unused]] ObjectHeader *object) override {} - void UnpinObject([[maybe_unused]] ObjectHeader *object) final {} + void UnpinObject([[maybe_unused]] ObjectHeader *object) override {} const std::vector &GetYoungSpaceMemRanges() final { diff --git a/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-allocator-adapter.cpp b/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-allocator-adapter.cpp index e58ce7376d..a3ecef25ea 100644 --- a/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-allocator-adapter.cpp +++ b/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-allocator-adapter.cpp @@ -55,6 +55,22 @@ void *CMCObjectAllocatorAdapter::AllocateNonMovable( #endif } +template +void CMCObjectAllocatorAdapter::PinObject([[maybe_unused]] ObjectHeader *object) +{ +#if defined(ARK_HYBRID) + panda::HeapAllocator::PinObject((panda::Address)object); +#endif +} + +template +void CMCObjectAllocatorAdapter::UnpinObject([[maybe_unused]] ObjectHeader *object) +{ +#if defined(ARK_HYBRID) + panda::HeapAllocator::UnpinObject((panda::Address)object); +#endif +} + template class CMCObjectAllocatorAdapter; template class CMCObjectAllocatorAdapter; template class CMCObjectAllocatorAdapter; diff --git a/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-allocator-adapter.h b/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-allocator-adapter.h index 91d65be1a5..67cbbf8cf3 100644 --- a/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-allocator-adapter.h +++ b/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-allocator-adapter.h @@ -38,6 +38,9 @@ public: [[nodiscard]] void *AllocateNonMovable(size_t size, Alignment align, ark::ManagedThread *thread, ObjectAllocatorBase::ObjMemInitPolicy objInit) override; + + void PinObject([[maybe_unused]] ObjectHeader *object) override; + void UnpinObject([[maybe_unused]] ObjectHeader *object) override; }; } // namespace ark::mem diff --git a/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-gc-adapter.cpp b/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-gc-adapter.cpp index 0e9f8f5520..6af155d3ad 100644 --- a/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-gc-adapter.cpp +++ b/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-gc-adapter.cpp @@ -68,6 +68,10 @@ void CMCGCAdapter::InitGCBitsForAllocationInTLAB([[maybe_unused] template bool CMCGCAdapter::Trigger([[maybe_unused]] PandaUniquePtr task) { +#ifdef ARK_HYBRID + panda::BaseRuntime::RequestGC(panda::GcType::FULL); + return true; +#endif return false; } diff --git a/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-gc-adapter.h b/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-gc-adapter.h index c1f2e7f139..ae9c3cd59c 100644 --- a/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-gc-adapter.h +++ b/static_core/runtime/mem/gc/cmc-gc-adapter/cmc-gc-adapter.h @@ -42,7 +42,7 @@ public: bool IsPinningSupported() const final { - return false; + return true; } void InitGCBits(ark::ObjectHeader *objHeader) override; diff --git a/static_core/tools/ark_js_napi_cli/BUILD.gn b/static_core/tools/ark_js_napi_cli/BUILD.gn index b1116c15cc..43f8f82cf9 100755 --- a/static_core/tools/ark_js_napi_cli/BUILD.gn +++ b/static_core/tools/ark_js_napi_cli/BUILD.gn @@ -95,8 +95,12 @@ template("host_hybridtest_action") { action("${_target_name_}") { testonly = true script = "tests/test_runner.py" + _test_list = rebase_path("tests/test_list.txt") + if (ark_hybrid) { + _test_list = rebase_path("tests/test_list_hybrid.txt") + } args = [ - "--tests-list=" + rebase_path("tests/test_list.txt"), + "--tests-list=$_test_list", "--build-dir=" + rebase_path("$root_out_dir"), "--tests-dir=" + rebase_path("tests"), ] diff --git a/static_core/tools/ark_js_napi_cli/tests/cmc_gc_object_pinning.ts b/static_core/tools/ark_js_napi_cli/tests/cmc_gc_object_pinning.ts new file mode 100644 index 0000000000..6444d0f7e7 --- /dev/null +++ b/static_core/tools/ark_js_napi_cli/tests/cmc_gc_object_pinning.ts @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// This test check basic cases of interop objects +// are not collected by normal GC + +globalThis.test = {}; +globalThis.test.etsVm = requireNapiPreview('ets_interop_js_napi', true); +if (!globalThis.test.etsVm.createRuntime({ + 'log-level': 'debug', + 'load-runtimes': 'ets', + 'boot-panda-files': 'etsstdlib.abc:gc_test_sts_common.abc', + 'gc-trigger-type': 'heap-trigger', + 'compiler-enable-jit': 'false', + 'interpreter-type': 'cpp', + 'coroutine-workers-count': '1', + 'gc-type': 'cmc-gc', +})) { + throw new Error('Failed to create ETS runtime'); +} + +function main(): void { + const ObjectPinningTest = globalThis.test.etsVm.getFunction('LPandaGC/ETSGLOBAL;', 'ObjectPinningTest'); + ObjectPinningTest(); +} +main(); diff --git a/static_core/tools/ark_js_napi_cli/tests/ets/gc_test_sts_common.ets b/static_core/tools/ark_js_napi_cli/tests/ets/gc_test_sts_common.ets index 83d9d9aac9..33b6547b94 100644 --- a/static_core/tools/ark_js_napi_cli/tests/ets/gc_test_sts_common.ets +++ b/static_core/tools/ark_js_napi_cli/tests/ets/gc_test_sts_common.ets @@ -126,3 +126,32 @@ class PandaBaseClass { } } } + +function FillCurrentRegion() { + for (let i = 0; i < 10000; i++) { + let obj: Object = new Object(); + } +} + +function RunGC() { + let gc_id = GC.startGC(GC.Cause.FULL); + assertTrue(gc_id != -1, "startGC failed"); +} + +function ObjectPinningTest(): int { + let obj: Object = new Object(); + let addr_before_gc: long = GC.getObjectAddress(obj); + GC.pinObject(obj); + FillCurrentRegion(); + RunGC() + let addr_after_gc_1: long = GC.getObjectAddress(obj); + assertEQ(addr_before_gc, addr_after_gc_1, "Pinned object must has a fixed address"); + + GC.unpinObject(obj); + RunGC() + RunGC() + let addr_after_gc_2: long = GC.getObjectAddress(obj); + assertNE(addr_before_gc, addr_after_gc_2, "Unpinned object must be moved"); + + return 0 +} diff --git a/static_core/tools/ark_js_napi_cli/tests/test_list_hybrid.txt b/static_core/tools/ark_js_napi_cli/tests/test_list_hybrid.txt new file mode 100644 index 0000000000..fd8fa3a281 --- /dev/null +++ b/static_core/tools/ark_js_napi_cli/tests/test_list_hybrid.txt @@ -0,0 +1 @@ +cmc_gc_object_pinning.ts, gc_test_sts_common.ets -- Gitee