14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include "ecmascript/builtins/builtins_ark_tools.h" 174514f5e3Sopenharmony_ci#include "ecmascript/ecma_vm.h" 184514f5e3Sopenharmony_ci#include "ecmascript/mem/full_gc.h" 194514f5e3Sopenharmony_ci#include "ecmascript/object_factory-inl.h" 204514f5e3Sopenharmony_ci#include "ecmascript/mem/concurrent_marker.h" 214514f5e3Sopenharmony_ci#include "ecmascript/mem/partial_gc.h" 224514f5e3Sopenharmony_ci#include "ecmascript/tests/ecma_test_common.h" 234514f5e3Sopenharmony_ci#include "ecmascript/napi/include/jsnapi_expo.h" 244514f5e3Sopenharmony_ci 254514f5e3Sopenharmony_ciusing namespace panda; 264514f5e3Sopenharmony_ci 274514f5e3Sopenharmony_ciusing namespace panda::ecmascript; 284514f5e3Sopenharmony_ciusing TRIGGER_IDLE_GC_TYPE = panda::JSNApi::TRIGGER_IDLE_GC_TYPE; 294514f5e3Sopenharmony_ci 304514f5e3Sopenharmony_cinamespace panda::test { 314514f5e3Sopenharmony_ciclass GCTest : public BaseTestWithScope<false> { 324514f5e3Sopenharmony_cipublic: 334514f5e3Sopenharmony_ci void SetUp() override 344514f5e3Sopenharmony_ci { 354514f5e3Sopenharmony_ci JSRuntimeOptions options; 364514f5e3Sopenharmony_ci options.SetEnableEdenGC(true); 374514f5e3Sopenharmony_ci instance = JSNApi::CreateEcmaVM(options); 384514f5e3Sopenharmony_ci ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM"; 394514f5e3Sopenharmony_ci thread = instance->GetJSThread(); 404514f5e3Sopenharmony_ci thread->ManagedCodeBegin(); 414514f5e3Sopenharmony_ci scope = new EcmaHandleScope(thread); 424514f5e3Sopenharmony_ci auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 434514f5e3Sopenharmony_ci heap->GetConcurrentMarker()->EnableConcurrentMarking(EnableConcurrentMarkType::ENABLE); 444514f5e3Sopenharmony_ci heap->GetSweeper()->EnableConcurrentSweep(EnableConcurrentSweepType::ENABLE); 454514f5e3Sopenharmony_ci } 464514f5e3Sopenharmony_ci}; 474514f5e3Sopenharmony_ci 484514f5e3Sopenharmony_ciHWTEST_F_L0(GCTest, NativeGCTestConcurrentMarkDisabled) 494514f5e3Sopenharmony_ci{ 504514f5e3Sopenharmony_ci auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 514514f5e3Sopenharmony_ci // Disable concurrent mark. 524514f5e3Sopenharmony_ci heap->GetConcurrentMarker()->ConfigConcurrentMark(false); 534514f5e3Sopenharmony_ci size_t oldNativeSize = heap->GetNativeBindingSize(); 544514f5e3Sopenharmony_ci EcmaTestCommon::GcCommonCase(thread, heap, false); 554514f5e3Sopenharmony_ci const_cast<Heap *>(thread->GetEcmaVM()->GetHeap())->CollectGarbage(TriggerGCType::OLD_GC); 564514f5e3Sopenharmony_ci auto newNativeSize = heap->GetNativeBindingSize(); 574514f5e3Sopenharmony_ci EXPECT_EQ(newNativeSize - oldNativeSize, 0UL); 584514f5e3Sopenharmony_ci} 594514f5e3Sopenharmony_ci 604514f5e3Sopenharmony_ciHWTEST_F_L0(GCTest, NonNewSpaceNativeGCTestConcurrentMarkDisabled) 614514f5e3Sopenharmony_ci{ 624514f5e3Sopenharmony_ci auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 634514f5e3Sopenharmony_ci // Disable concurrent mark. 644514f5e3Sopenharmony_ci heap->GetConcurrentMarker()->ConfigConcurrentMark(false); 654514f5e3Sopenharmony_ci size_t oldNativeSize = heap->GetNativeBindingSize(); 664514f5e3Sopenharmony_ci EcmaTestCommon::GcCommonCase(thread, heap); 674514f5e3Sopenharmony_ci const_cast<Heap *>(thread->GetEcmaVM()->GetHeap())->CollectGarbage(TriggerGCType::OLD_GC); 684514f5e3Sopenharmony_ci auto newNativeSize = heap->GetNativeBindingSize(); 694514f5e3Sopenharmony_ci EXPECT_EQ(newNativeSize - oldNativeSize, 0UL); 704514f5e3Sopenharmony_ci} 714514f5e3Sopenharmony_ci 724514f5e3Sopenharmony_ciHWTEST_F_L0(GCTest, ArkToolsForceFullGC) 734514f5e3Sopenharmony_ci{ 744514f5e3Sopenharmony_ci const_cast<Heap *>(thread->GetEcmaVM()->GetHeap())->CollectGarbage(TriggerGCType::FULL_GC); 754514f5e3Sopenharmony_ci size_t originalHeapSize = thread->GetEcmaVM()->GetHeap()->GetCommittedSize(); 764514f5e3Sopenharmony_ci size_t newSize = originalHeapSize; 774514f5e3Sopenharmony_ci { 784514f5e3Sopenharmony_ci [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread); 794514f5e3Sopenharmony_ci 804514f5e3Sopenharmony_ci for (int i = 0; i < 10; i++) { 814514f5e3Sopenharmony_ci [[maybe_unused]] JSHandle<TaggedArray> obj = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(1024 * 1024); 824514f5e3Sopenharmony_ci } 834514f5e3Sopenharmony_ci newSize = thread->GetEcmaVM()->GetHeap()->GetCommittedSize(); 844514f5e3Sopenharmony_ci } 854514f5e3Sopenharmony_ci EXPECT_TRUE(newSize > originalHeapSize); 864514f5e3Sopenharmony_ci auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 0); 874514f5e3Sopenharmony_ci 884514f5e3Sopenharmony_ci [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 894514f5e3Sopenharmony_ci [[maybe_unused]] JSTaggedValue result1 = builtins::BuiltinsArkTools::ForceFullGC(ecmaRuntimeCallInfo); 904514f5e3Sopenharmony_ci 914514f5e3Sopenharmony_ci ASSERT_TRUE(thread->GetEcmaVM()->GetHeap()->GetCommittedSize() < newSize); 924514f5e3Sopenharmony_ci} 934514f5e3Sopenharmony_ci 944514f5e3Sopenharmony_ciHWTEST_F_L0(GCTest, ColdStartForceExpand) 954514f5e3Sopenharmony_ci{ 964514f5e3Sopenharmony_ci auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 974514f5e3Sopenharmony_ci size_t originalHeapSize = heap->GetCommittedSize(); 984514f5e3Sopenharmony_ci heap->GetConcurrentMarker()->ConfigConcurrentMark(false); 994514f5e3Sopenharmony_ci heap->NotifyPostFork(); 1004514f5e3Sopenharmony_ci heap->NotifyFinishColdStartSoon(); 1014514f5e3Sopenharmony_ci { 1024514f5e3Sopenharmony_ci [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread); 1034514f5e3Sopenharmony_ci for (int i = 0; i < 500; i++) { 1044514f5e3Sopenharmony_ci [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray( 1054514f5e3Sopenharmony_ci 10 * 1024, JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE); 1064514f5e3Sopenharmony_ci } 1074514f5e3Sopenharmony_ci } 1084514f5e3Sopenharmony_ci size_t expandHeapSize = thread->GetEcmaVM()->GetHeap()->GetCommittedSize(); 1094514f5e3Sopenharmony_ci usleep(2500000); 1104514f5e3Sopenharmony_ci size_t newSize = EcmaTestCommon::GcCommonCase(thread); 1114514f5e3Sopenharmony_ci EXPECT_TRUE(originalHeapSize < expandHeapSize); 1124514f5e3Sopenharmony_ci EXPECT_TRUE(expandHeapSize > newSize); 1134514f5e3Sopenharmony_ci} 1144514f5e3Sopenharmony_ci 1154514f5e3Sopenharmony_ciHWTEST_F_L0(GCTest, HighSensitiveForceExpand) 1164514f5e3Sopenharmony_ci{ 1174514f5e3Sopenharmony_ci auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 1184514f5e3Sopenharmony_ci size_t originalHeapSize = heap->GetCommittedSize(); 1194514f5e3Sopenharmony_ci heap->GetConcurrentMarker()->ConfigConcurrentMark(false); 1204514f5e3Sopenharmony_ci heap->NotifyHighSensitive(true); 1214514f5e3Sopenharmony_ci { 1224514f5e3Sopenharmony_ci [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread); 1234514f5e3Sopenharmony_ci for (int i = 0; i < 500; i++) { 1244514f5e3Sopenharmony_ci [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray( 1254514f5e3Sopenharmony_ci 10 * 1024, JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE); 1264514f5e3Sopenharmony_ci } 1274514f5e3Sopenharmony_ci } 1284514f5e3Sopenharmony_ci size_t expandHeapSize = thread->GetEcmaVM()->GetHeap()->GetCommittedSize(); 1294514f5e3Sopenharmony_ci const_cast<Heap *>(thread->GetEcmaVM()->GetHeap())->NotifyHighSensitive(false); 1304514f5e3Sopenharmony_ci size_t newSize = EcmaTestCommon::GcCommonCase(thread); 1314514f5e3Sopenharmony_ci EXPECT_TRUE(originalHeapSize < expandHeapSize); 1324514f5e3Sopenharmony_ci EXPECT_TRUE(expandHeapSize > newSize); 1334514f5e3Sopenharmony_ci} 1344514f5e3Sopenharmony_ci 1354514f5e3Sopenharmony_ciHWTEST_F_L0(GCTest, HighSensitiveExceedMaxHeapSize) 1364514f5e3Sopenharmony_ci{ 1374514f5e3Sopenharmony_ci auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 1384514f5e3Sopenharmony_ci heap->NotifyHighSensitive(true); 1394514f5e3Sopenharmony_ci // First allocate about 250M TaggedArray, not reach max heap size 1404514f5e3Sopenharmony_ci { 1414514f5e3Sopenharmony_ci [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread); 1424514f5e3Sopenharmony_ci for (int i = 0; i < 16 * 1000; i++) { 1434514f5e3Sopenharmony_ci [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray( 1444514f5e3Sopenharmony_ci 1024, JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE); 1454514f5e3Sopenharmony_ci } 1464514f5e3Sopenharmony_ci } 1474514f5e3Sopenharmony_ci // Continue allocate about 250M TaggedArray, now reach max heap size, must trigger gc to avoid OOM 1484514f5e3Sopenharmony_ci { 1494514f5e3Sopenharmony_ci [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread); 1504514f5e3Sopenharmony_ci for (int i = 0; i < 10 * 1000; i++) { 1514514f5e3Sopenharmony_ci [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray( 1524514f5e3Sopenharmony_ci 1024, JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE); 1534514f5e3Sopenharmony_ci } 1544514f5e3Sopenharmony_ci } 1554514f5e3Sopenharmony_ci size_t commitSize = thread->GetEcmaVM()->GetHeap()->GetCommittedSize(); 1564514f5e3Sopenharmony_ci const_cast<Heap *>(thread->GetEcmaVM()->GetHeap())->NotifyHighSensitive(false); 1574514f5e3Sopenharmony_ci EXPECT_TRUE(commitSize < thread->GetEcmaVM()->GetEcmaParamConfiguration().GetMaxHeapSize()); 1584514f5e3Sopenharmony_ci} 1594514f5e3Sopenharmony_ci 1604514f5e3Sopenharmony_ciHWTEST_F_L0(GCTest, ColdStartNoConcurrentMark) 1614514f5e3Sopenharmony_ci{ 1624514f5e3Sopenharmony_ci auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 1634514f5e3Sopenharmony_ci heap->NotifyPostFork(); 1644514f5e3Sopenharmony_ci heap->NotifyHighSensitive(true); 1654514f5e3Sopenharmony_ci { 1664514f5e3Sopenharmony_ci [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread); 1674514f5e3Sopenharmony_ci for (int i = 0; i < 500; i++) { 1684514f5e3Sopenharmony_ci [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray( 1694514f5e3Sopenharmony_ci 10 * 1024, JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE); 1704514f5e3Sopenharmony_ci } 1714514f5e3Sopenharmony_ci } 1724514f5e3Sopenharmony_ci EXPECT_FALSE(heap->HandleExitHighSensitiveEvent()); 1734514f5e3Sopenharmony_ci heap->NotifyHighSensitive(false); 1744514f5e3Sopenharmony_ci EXPECT_FALSE(heap->HandleExitHighSensitiveEvent()); 1754514f5e3Sopenharmony_ci heap->FinishStartupEvent(); 1764514f5e3Sopenharmony_ci 1774514f5e3Sopenharmony_ci heap->NotifyHighSensitive(true); 1784514f5e3Sopenharmony_ci heap->NotifyHighSensitive(false); 1794514f5e3Sopenharmony_ci EXPECT_TRUE(heap->HandleExitHighSensitiveEvent()); 1804514f5e3Sopenharmony_ci} 1814514f5e3Sopenharmony_ci 1824514f5e3Sopenharmony_ciHWTEST_F_L0(GCTest, CallbackTask) 1834514f5e3Sopenharmony_ci{ 1844514f5e3Sopenharmony_ci auto vm = thread->GetEcmaVM(); 1854514f5e3Sopenharmony_ci Heap *heap = const_cast<Heap *>(vm->GetHeap()); 1864514f5e3Sopenharmony_ci auto factory = vm->GetFactory(); 1874514f5e3Sopenharmony_ci { 1884514f5e3Sopenharmony_ci [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread); 1894514f5e3Sopenharmony_ci 1904514f5e3Sopenharmony_ci for (int i = 0; i < 10; i++) { 1914514f5e3Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) 1924514f5e3Sopenharmony_ci void *externalPointer = malloc(10); 1934514f5e3Sopenharmony_ci [[maybe_unused]] JSHandle<JSNativePointer> nativePointer = factory->NewJSNativePointer( 1944514f5e3Sopenharmony_ci externalPointer, []([[maybe_unused]] void *env, void* pointer, [[maybe_unused]] void* data) { 1954514f5e3Sopenharmony_ci if (pointer != nullptr) { 1964514f5e3Sopenharmony_ci free(pointer); 1974514f5e3Sopenharmony_ci } 1984514f5e3Sopenharmony_ci }, 1994514f5e3Sopenharmony_ci nullptr, false, 10, Concurrent::YES); 2004514f5e3Sopenharmony_ci } 2014514f5e3Sopenharmony_ci } 2024514f5e3Sopenharmony_ci size_t number = heap->concurrentNativePointerList_.size(); 2034514f5e3Sopenharmony_ci EXPECT_TRUE(number > 0); 2044514f5e3Sopenharmony_ci heap->CollectGarbage(TriggerGCType::OLD_GC); 2054514f5e3Sopenharmony_ci size_t newNumber = heap->concurrentNativePointerList_.size(); 2064514f5e3Sopenharmony_ci EXPECT_TRUE(number > newNumber); 2074514f5e3Sopenharmony_ci} 2084514f5e3Sopenharmony_ci 2094514f5e3Sopenharmony_ciHWTEST_F_L0(GCTest, RecomputeLimitsTest) 2104514f5e3Sopenharmony_ci{ 2114514f5e3Sopenharmony_ci auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 2124514f5e3Sopenharmony_ci auto oldCapacity = heap->GetOldSpace()->GetInitialCapacity(); 2134514f5e3Sopenharmony_ci heap->CollectGarbage(TriggerGCType::FULL_GC); 2144514f5e3Sopenharmony_ci EXPECT_FALSE(heap->IsConcurrentFullMark()); 2154514f5e3Sopenharmony_ci EXPECT_FALSE(heap->IsFullMarkRequested()); 2164514f5e3Sopenharmony_ci auto newCapacity = heap->GetOldSpace()->GetInitialCapacity(); 2174514f5e3Sopenharmony_ci EXPECT_NE(newCapacity, oldCapacity); 2184514f5e3Sopenharmony_ci double gcSpeed = heap->GetMemController()->CalculateMarkCompactSpeedPerMS(); 2194514f5e3Sopenharmony_ci double mutatorSpeed = heap->GetMemController()->GetCurrentOldSpaceAllocationThroughputPerMS(); 2204514f5e3Sopenharmony_ci size_t oldSpaceSize = heap->GetOldSpace()->GetHeapObjectSize() + heap->GetHugeObjectSpace()->GetHeapObjectSize() + 2214514f5e3Sopenharmony_ci heap->GetHugeMachineCodeSpace()->GetHeapObjectSize(); 2224514f5e3Sopenharmony_ci size_t newSpaceCapacity = heap->GetNewSpace()->GetInitialCapacity(); 2234514f5e3Sopenharmony_ci double growingFactor = heap->GetMemController()->CalculateGrowingFactor(gcSpeed, mutatorSpeed); 2244514f5e3Sopenharmony_ci size_t maxOldSpaceCapacity = heap->GetOldSpace()->GetMaximumCapacity() - newSpaceCapacity; 2254514f5e3Sopenharmony_ci auto newOldSpaceLimit = heap->GetMemController()->CalculateAllocLimit(oldSpaceSize, MIN_OLD_SPACE_LIMIT, 2264514f5e3Sopenharmony_ci maxOldSpaceCapacity, newSpaceCapacity, growingFactor); 2274514f5e3Sopenharmony_ci EXPECT_EQ(newCapacity, newOldSpaceLimit); 2284514f5e3Sopenharmony_ci} 2294514f5e3Sopenharmony_ci 2304514f5e3Sopenharmony_ciHWTEST_F_L0(GCTest, GlobalNativeSizeLargerThanLimitTest) 2314514f5e3Sopenharmony_ci{ 2324514f5e3Sopenharmony_ci auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 2334514f5e3Sopenharmony_ci auto ret = heap->GlobalNativeSizeLargerThanLimit(); 2344514f5e3Sopenharmony_ci EXPECT_FALSE(ret); 2354514f5e3Sopenharmony_ci heap->GetNativeAreaAllocator()->IncreaseNativeMemoryUsage(300*1000*1000); 2364514f5e3Sopenharmony_ci ret = heap->GlobalNativeSizeLargerThanLimit(); 2374514f5e3Sopenharmony_ci EXPECT_TRUE(ret); 2384514f5e3Sopenharmony_ci} 2394514f5e3Sopenharmony_ci#ifdef NDEBUG 2404514f5e3Sopenharmony_ciHWTEST_F_L0(GCTest, IdleGCTriggerTest) 2414514f5e3Sopenharmony_ci{ 2424514f5e3Sopenharmony_ci auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 2434514f5e3Sopenharmony_ci auto idleGCTrigger = heap->GetIdleGCTrigger(); 2444514f5e3Sopenharmony_ci auto sHeap = SharedHeap::GetInstance(); 2454514f5e3Sopenharmony_ci heap->CollectGarbage(TriggerGCType::FULL_GC); 2464514f5e3Sopenharmony_ci int baseLocalGCCount = heap->GetEcmaGCStats()->GetGCCount(); 2474514f5e3Sopenharmony_ci int baseSharedGCCount = sHeap->GetEcmaGCStats()->GetGCCount(); 2484514f5e3Sopenharmony_ci heap->GetConcurrentMarker()->ConfigConcurrentMark(false); 2494514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 2504514f5e3Sopenharmony_ci // Apply for some memory that cannot be released to simulate the actual situation 2514514f5e3Sopenharmony_ci for (int i = 0; i < 5120; i++) { 2524514f5e3Sopenharmony_ci factory->NewTaggedArray(1024, JSTaggedValue::Hole(), MemSpaceType::OLD_SPACE); 2534514f5e3Sopenharmony_ci factory->NewSOldSpaceTaggedArray(1024, JSTaggedValue::Hole()); 2544514f5e3Sopenharmony_ci } 2554514f5e3Sopenharmony_ci for (size_t i = 0; i < 10240; i++) 2564514f5e3Sopenharmony_ci { 2574514f5e3Sopenharmony_ci factory->NewTaggedArray(512, JSTaggedValue::Hole(), MemSpaceType::OLD_SPACE); 2584514f5e3Sopenharmony_ci factory->NewSOldSpaceTaggedArray(512, JSTaggedValue::Hole()); 2594514f5e3Sopenharmony_ci [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread); 2604514f5e3Sopenharmony_ci [[maybe_unused]] JSHandle<TaggedArray> array = factory->NewTaggedArray(1024, JSTaggedValue::Hole(), 2614514f5e3Sopenharmony_ci MemSpaceType::OLD_SPACE); 2624514f5e3Sopenharmony_ci [[maybe_unused]] JSHandle<TaggedArray> sArray = factory->NewSOldSpaceTaggedArray(1024, 2634514f5e3Sopenharmony_ci JSTaggedValue::Hole()); 2644514f5e3Sopenharmony_ci if (i%340 == 0) { 2654514f5e3Sopenharmony_ci idleGCTrigger->NotifyVsyncIdleStart(); 2664514f5e3Sopenharmony_ci } 2674514f5e3Sopenharmony_ci } 2684514f5e3Sopenharmony_ci idleGCTrigger->TryTriggerIdleGC(TRIGGER_IDLE_GC_TYPE::FULL_GC); 2694514f5e3Sopenharmony_ci idleGCTrigger->TryTriggerIdleGC(TRIGGER_IDLE_GC_TYPE::SHARED_FULL_GC); 2704514f5e3Sopenharmony_ci int afterLocalGCCount = heap->GetEcmaGCStats()->GetGCCount(); 2714514f5e3Sopenharmony_ci int afterSharedGCCount = sHeap->GetEcmaGCStats()->GetGCCount(); 2724514f5e3Sopenharmony_ci EXPECT_TRUE(afterLocalGCCount - baseLocalGCCount < 10); 2734514f5e3Sopenharmony_ci EXPECT_TRUE(afterSharedGCCount - baseSharedGCCount < 10); 2744514f5e3Sopenharmony_ci heap->CollectGarbage(TriggerGCType::FULL_GC); 2754514f5e3Sopenharmony_ci} 2764514f5e3Sopenharmony_ci#endif // #ifndef NDEBUG 2774514f5e3Sopenharmony_ci 2784514f5e3Sopenharmony_ciHWTEST_F_L0(GCTest, AdjustCapacity) 2794514f5e3Sopenharmony_ci{ 2804514f5e3Sopenharmony_ci#if defined(PANDA_TARGET_ARM64) 2814514f5e3Sopenharmony_ci auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 2824514f5e3Sopenharmony_ci SemiSpace * space = heap->GetNewSpace(); 2834514f5e3Sopenharmony_ci 2844514f5e3Sopenharmony_ci EXPECT_EQ(space->GetSurvivalObjectSize(), 0); 2854514f5e3Sopenharmony_ci { 2864514f5e3Sopenharmony_ci [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread); 2874514f5e3Sopenharmony_ci for (int i = 0; i < 300; i++) { 2884514f5e3Sopenharmony_ci [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray( 2894514f5e3Sopenharmony_ci 10 * 1024, JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE); 2904514f5e3Sopenharmony_ci } 2914514f5e3Sopenharmony_ci } 2924514f5e3Sopenharmony_ci EXPECT_GT(space->GetSurvivalObjectSize(), 0); 2934514f5e3Sopenharmony_ci 2944514f5e3Sopenharmony_ci EXPECT_FALSE(space->AdjustCapacity(0, thread)); 2954514f5e3Sopenharmony_ci size_t size = space->GetInitialCapacity() * GROW_OBJECT_SURVIVAL_RATE / 2; 2964514f5e3Sopenharmony_ci EXPECT_FALSE(space->AdjustCapacity(size, thread)); 2974514f5e3Sopenharmony_ci 2984514f5e3Sopenharmony_ci space->SetInitialCapacity(space->GetSurvivalObjectSize() / GROW_OBJECT_SURVIVAL_RATE - 1); 2994514f5e3Sopenharmony_ci size = space->GetSurvivalObjectSize() / GROW_OBJECT_SURVIVAL_RATE - 1; 3004514f5e3Sopenharmony_ci size_t oldMaxCapacity = space->GetMaximumCapacity(); 3014514f5e3Sopenharmony_ci space->SetMaximumCapacity(space->GetInitialCapacity()); 3024514f5e3Sopenharmony_ci EXPECT_FALSE(space->AdjustCapacity(size, thread)); 3034514f5e3Sopenharmony_ci space->SetMaximumCapacity(oldMaxCapacity); 3044514f5e3Sopenharmony_ci EXPECT_TRUE(space->AdjustCapacity(size, thread)); 3054514f5e3Sopenharmony_ci#endif 3064514f5e3Sopenharmony_ci} 3074514f5e3Sopenharmony_ci 3084514f5e3Sopenharmony_ciHWTEST_F_L0(GCTest, NativeMemAllocInSensitive) 3094514f5e3Sopenharmony_ci{ 3104514f5e3Sopenharmony_ci auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 3114514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 3124514f5e3Sopenharmony_ci heap->NotifyHighSensitive(true); 3134514f5e3Sopenharmony_ci for (size_t i = 0; i < 20; i++) { 3144514f5e3Sopenharmony_ci [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread); 3154514f5e3Sopenharmony_ci factory->NewJSArrayBuffer(300 * 1024 * 1024); // 300MB 3164514f5e3Sopenharmony_ci } 3174514f5e3Sopenharmony_ci EXPECT_TRUE(heap->GetGlobalNativeSize() < 1 * 1024 * 1024* 1024); // 1GB 3184514f5e3Sopenharmony_ci} 3194514f5e3Sopenharmony_ci} // namespace panda::test 320