1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "ecmascript/ecma_vm.h" 17#include "ecmascript/mem/idle_gc_trigger.h" 18#include "ecmascript/mem/heap.h" 19#include "ecmascript/mem/heap-inl.h" 20#include "ecmascript/tests/test_helper.h" 21#include "ecmascript/mem/concurrent_marker.h" 22#include "ecmascript/mem/partial_gc.h" 23 24using namespace panda::ecmascript; 25using namespace panda::ecmascript::base; 26using TRIGGER_IDLE_GC_TYPE = panda::JSNApi::TRIGGER_IDLE_GC_TYPE; 27using TriggerGCData = std::pair<void*, uint8_t>; 28using TriggerGCTaskCallback = std::function<void(TriggerGCData& data)>; 29 30namespace panda::test { 31class IdleGCTriggerTest : public BaseTestWithScope<false> { 32public: 33 void SetUp() override 34 { 35 JSRuntimeOptions options; 36 options.SetEnableEdenGC(true); 37 instance = JSNApi::CreateEcmaVM(options); 38 ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM"; 39 thread = instance->GetJSThread(); 40 thread->ManagedCodeBegin(); 41 scope = new EcmaHandleScope(thread); 42 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 43 heap->GetConcurrentMarker()->EnableConcurrentMarking(EnableConcurrentMarkType::ENABLE); 44 heap->GetSweeper()->EnableConcurrentSweep(EnableConcurrentSweepType::ENABLE); 45 } 46}; 47 48HWTEST_F_L0(IdleGCTriggerTest, NotifyLooperIdleStartTest001) 49{ 50 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 51 SharedHeap *sheap = SharedHeap::GetInstance(); 52 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 53 trigger->NotifyLooperIdleStart(1, 1); 54} 55 56HWTEST_F_L0(IdleGCTriggerTest, NotifyLooperIdleStartTest002) 57{ 58 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 59 SharedHeap *sheap = SharedHeap::GetInstance(); 60 heap->GetConcurrentMarker()->Mark(); 61 heap->GetJSThread()->SetMarkStatus(MarkStatus::MARK_FINISHED); 62 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 63 trigger->ClearPostGCTask(TRIGGER_IDLE_GC_TYPE::LOCAL_CONCURRENT_MARK); 64 trigger->SetPostGCTask(TRIGGER_IDLE_GC_TYPE::LOCAL_CONCURRENT_MARK); 65 trigger->NotifyLooperIdleStart(1, 1); 66} 67 68HWTEST_F_L0(IdleGCTriggerTest, NotifyLooperIdleEndTest001) 69{ 70 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 71 SharedHeap *sheap = SharedHeap::GetInstance(); 72 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 73 trigger->NotifyLooperIdleEnd(1); 74} 75 76HWTEST_F_L0(IdleGCTriggerTest, TryTriggerHandleMarkFinishedTest001) 77{ 78 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 79 SharedHeap *sheap = SharedHeap::GetInstance(); 80 81 heap->GetConcurrentMarker()->Mark(); 82 heap->GetConcurrentMarker()->ProcessConcurrentMarkTask(0); 83 84 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 85 trigger->TryTriggerHandleMarkFinished(); 86} 87 88HWTEST_F_L0(IdleGCTriggerTest, TryTriggerLocalConcurrentMarkTest001) 89{ 90 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 91 SharedHeap *sheap = SharedHeap::GetInstance(); 92 heap->SetIdleTask(IdleTaskType::NO_TASK); 93 94 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 95 trigger->TryTriggerLocalConcurrentMark(); 96} 97 98HWTEST_F_L0(IdleGCTriggerTest, TryTriggerLocalConcurrentMarkTest002) 99{ 100 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 101 SharedHeap *sheap = SharedHeap::GetInstance(); 102 heap->SetIdleTask(IdleTaskType::NO_TASK); 103 heap->GetConcurrentMarker()->ConfigConcurrentMark(false); 104 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 105 trigger->TryTriggerLocalConcurrentMark(); 106} 107 108HWTEST_F_L0(IdleGCTriggerTest, TryTriggerLocalConcurrentMarkTest003) 109{ 110 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 111 SharedHeap *sheap = SharedHeap::GetInstance(); 112 heap->SetIdleTask(IdleTaskType::NO_TASK); 113 thread->SetMarkStatus(MarkStatus::MARK_FINISHED); 114 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 115 trigger->TryTriggerLocalConcurrentMark(); 116} 117 118HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleSharedOldGCTest001) 119{ 120 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 121 SharedHeap *sheap = SharedHeap::GetInstance(); 122 123 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 124 ASSERT_EQ(trigger->TryTriggerIdleSharedOldGC(), false); 125} 126 127HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleSharedOldGCTest002) 128{ 129 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 130 SharedHeap *sheap = SharedHeap::GetInstance(); 131 sheap->GetOldSpace()->SetInitialCapacity(10000); 132 sheap->GetOldSpace()->IncreaseLiveObjectSize(5242889); 133 sheap->NotifyHeapAliveSizeAfterGC(1); 134 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 135 ASSERT_EQ(trigger->TryTriggerIdleSharedOldGC(), true); 136} 137 138HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleSharedOldGCTest003) 139{ 140 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 141 SharedHeap *sheap = SharedHeap::GetInstance(); 142 sheap->GetOldSpace()->SetInitialCapacity(10000); 143 sheap->GetOldSpace()->IncreaseLiveObjectSize(5242889); 144 sheap->NotifyHeapAliveSizeAfterGC(1); 145 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 146 trigger->ClearPostGCTask(TRIGGER_IDLE_GC_TYPE::SHARED_CONCURRENT_MARK); 147 trigger->SetPostGCTask(TRIGGER_IDLE_GC_TYPE::SHARED_CONCURRENT_MARK); 148 ASSERT_EQ(trigger->TryTriggerIdleSharedOldGC(), true); 149} 150 151HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleSharedOldGCTest004) 152{ 153 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 154 SharedHeap *sheap = SharedHeap::GetInstance(); 155 heap->SetOnSerializeEvent(true); 156 157 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 158 ASSERT_EQ(trigger->TryTriggerIdleSharedOldGC(), false); 159} 160 161HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleLocalOldGCTest001) 162{ 163 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 164 SharedHeap *sheap = SharedHeap::GetInstance(); 165 heap->SetIdleTask(IdleTaskType::NO_TASK); 166 heap->GetOldSpace()->SetInitialCapacity(10000); 167 heap->GetOldSpace()->IncreaseLiveObjectSize(5242889); 168 heap->NotifyHeapAliveSizeAfterGC(1); 169 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 170 ASSERT_EQ(trigger->TryTriggerIdleLocalOldGC(), true); 171} 172 173HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleLocalOldGCTest002) 174{ 175 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 176 SharedHeap *sheap = SharedHeap::GetInstance(); 177 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 178 trigger->ClearPostGCTask(TRIGGER_IDLE_GC_TYPE::LOCAL_CONCURRENT_MARK); 179 trigger->SetPostGCTask(TRIGGER_IDLE_GC_TYPE::LOCAL_CONCURRENT_MARK); 180 ASSERT_EQ(trigger->TryTriggerIdleLocalOldGC(), true); 181} 182 183HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleLocalOldGCTest003) 184{ 185 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 186 SharedHeap *sheap = SharedHeap::GetInstance(); 187 heap->GetConcurrentMarker()->Mark(); 188 heap->GetJSThread()->SetMarkStatus(MarkStatus::MARK_FINISHED); 189 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 190 trigger->ClearPostGCTask(TRIGGER_IDLE_GC_TYPE::LOCAL_REMARK); 191 trigger->SetPostGCTask(TRIGGER_IDLE_GC_TYPE::LOCAL_REMARK); 192 ASSERT_EQ(trigger->TryTriggerIdleLocalOldGC(), true); 193} 194 195HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleLocalOldGCTest004) 196{ 197 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 198 SharedHeap *sheap = SharedHeap::GetInstance(); 199 heap->SetIdleTask(IdleTaskType::NO_TASK); 200 heap->GetOldSpace()->SetInitialCapacity(10000); 201 heap->GetOldSpace()->IncreaseLiveObjectSize(5242889); 202 heap->NotifyHeapAliveSizeAfterGC(1); 203 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 204 TriggerGCTaskCallback callback = [](TriggerGCData& data) { 205 data.second = 1; 206 }; 207 trigger->SetTriggerGCTaskCallback(callback); 208 ASSERT_EQ(trigger->TryTriggerIdleLocalOldGC(), true); 209} 210 211HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleLocalOldGCTest005) 212{ 213 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 214 SharedHeap *sheap = SharedHeap::GetInstance(); 215 heap->GetConcurrentMarker()->Mark(); 216 heap->GetJSThread()->SetMarkStatus(MarkStatus::MARK_FINISHED); 217 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 218 trigger->ClearPostGCTask(TRIGGER_IDLE_GC_TYPE::LOCAL_CONCURRENT_MARK); 219 trigger->SetPostGCTask(TRIGGER_IDLE_GC_TYPE::LOCAL_CONCURRENT_MARK); 220 ASSERT_EQ(trigger->TryTriggerIdleLocalOldGC(), true); 221} 222 223HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleLocalOldGCTest006) 224{ 225 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 226 SharedHeap *sheap = SharedHeap::GetInstance(); 227 heap->SetIdleTask(IdleTaskType::FINISH_MARKING); 228 heap->GetOldSpace()->SetInitialCapacity(10000); 229 heap->GetOldSpace()->IncreaseLiveObjectSize(5242889); 230 heap->NotifyHeapAliveSizeAfterGC(1); 231 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 232 TriggerGCTaskCallback callback = [](TriggerGCData& data) { 233 data.second = 1; 234 }; 235 trigger->SetTriggerGCTaskCallback(callback); 236 ASSERT_EQ(trigger->TryTriggerIdleLocalOldGC(), true); 237} 238 239HWTEST_F_L0(IdleGCTriggerTest, ReachIdleLocalOldGCThresholdsTest001) 240{ 241 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 242 SharedHeap *sheap = SharedHeap::GetInstance(); 243 heap->GetNativeAreaAllocator()->IncreaseNativeMemoryUsage(83886100); 244 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 245 ASSERT_EQ(trigger->ReachIdleLocalOldGCThresholds(), true); 246} 247 248HWTEST_F_L0(IdleGCTriggerTest, ReachIdleLocalOldGCThresholdsTest002) 249{ 250 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 251 SharedHeap *sheap = SharedHeap::GetInstance(); 252 heap->GetNativeAreaAllocator()->IncreaseNativeMemoryUsage(1); 253 heap->GetOldSpace()->IncreaseCommitted(83886100); 254 heap->GetOldSpace()->SetMaximumCapacity(100000); 255 heap->GetOldSpace()->SetOvershootSize(100000); 256 heap->GetOldSpace()->SetOvershootSize(100000); 257 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 258 ASSERT_EQ(trigger->ReachIdleLocalOldGCThresholds(), true); 259} 260 261HWTEST_F_L0(IdleGCTriggerTest, TryPostHandleMarkFinishedTest001) 262{ 263 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 264 SharedHeap *sheap = SharedHeap::GetInstance(); 265 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 266 trigger->NotifyLooperIdleStart(1, 1); 267 trigger->TryPostHandleMarkFinished(); 268} 269 270HWTEST_F_L0(IdleGCTriggerTest, TryPostHandleMarkFinishedTest002) 271{ 272 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 273 SharedHeap *sheap = SharedHeap::GetInstance(); 274 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 275 trigger->TryPostHandleMarkFinished(); 276} 277 278HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleGCTest002) 279{ 280 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 281 SharedHeap *sheap = SharedHeap::GetInstance(); 282 sheap->NotifyHeapAliveSizeAfterGC(1); 283 sheap->GetOldSpace()->SetInitialCapacity(10000); 284 sheap->GetOldSpace()->IncreaseLiveObjectSize(5242889); 285 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 286 trigger->TryTriggerIdleGC(TRIGGER_IDLE_GC_TYPE::SHARED_CONCURRENT_MARK); 287} 288 289HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleGCTest003) 290{ 291 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 292 SharedHeap *sheap = SharedHeap::GetInstance(); 293 heap->NotifyHeapAliveSizeAfterGC(1); 294 heap->GetOldSpace()->SetInitialCapacity(10000); 295 heap->GetOldSpace()->IncreaseLiveObjectSize(5242889); 296 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 297 trigger->TryTriggerIdleGC(TRIGGER_IDLE_GC_TYPE::LOCAL_CONCURRENT_MARK); 298} 299 300HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleGCTest004) 301{ 302 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 303 SharedHeap *sheap = SharedHeap::GetInstance(); 304 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 305 trigger->TryTriggerIdleGC(TRIGGER_IDLE_GC_TYPE::LOCAL_REMARK); 306} 307 308HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleGCTest011) 309{ 310 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 311 SharedHeap *sheap = SharedHeap::GetInstance(); 312 heap->SetOnSerializeEvent(true); 313 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 314 trigger->TryTriggerIdleGC(TRIGGER_IDLE_GC_TYPE::LOCAL_REMARK); 315} 316 317HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleGCTest012) 318{ 319 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 320 SharedHeap *sheap = SharedHeap::GetInstance(); 321 sheap->NotifyHeapAliveSizeAfterGC(0); 322 sheap->GetOldSpace()->SetInitialCapacity(10000); 323 sheap->GetOldSpace()->IncreaseLiveObjectSize(5242889); 324 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 325 trigger->TryTriggerIdleGC(TRIGGER_IDLE_GC_TYPE::FULL_GC); 326} 327 328HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleGCTest013) 329{ 330 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 331 SharedHeap *sheap = SharedHeap::GetInstance(); 332 sheap->NotifyHeapAliveSizeAfterGC(0); 333 sheap->GetOldSpace()->SetInitialCapacity(10000); 334 sheap->GetOldSpace()->IncreaseLiveObjectSize(5242889); 335 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 336 trigger->TryTriggerIdleGC(TRIGGER_IDLE_GC_TYPE::SHARED_FULL_GC); 337} 338 339HWTEST_F_L0(IdleGCTriggerTest, ShouldCheckIdleOldGCTest001) 340{ 341 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap()); 342 SharedHeap *sheap = SharedHeap::GetInstance(); 343 heap->NotifyHeapAliveSizeAfterGC(0); 344 heap->GetOldSpace()->SetInitialCapacity(10000); 345 heap->GetOldSpace()->IncreaseLiveObjectSize(5242889); 346 IdleGCTrigger *trigger = new IdleGCTrigger(heap, sheap, thread); 347 trigger->TryTriggerIdleGC(TRIGGER_IDLE_GC_TYPE::LOCAL_CONCURRENT_MARK); 348} 349 350} // namespace panda::test