1 /*
2 * Copyright (c) 2021 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 <chrono>
17 #include <thread>
18
19 #include "assembler/assembly-emitter.h"
20 #include "assembler/assembly-parser.h"
21
22 #include "ecmascript/builtins/builtins_ark_tools.h"
23 #include "ecmascript/containers/containers_bitvector.h"
24 #include "ecmascript/ecma_vm.h"
25 #include "ecmascript/js_api/js_api_bitvector.h"
26 #include "ecmascript/jspandafile/js_pandafile.h"
27 #include "ecmascript/jspandafile/js_pandafile_manager.h"
28 #include "ecmascript/jspandafile/program_object.h"
29 #include "ecmascript/mem/full_gc.h"
30 #include "ecmascript/object_factory-inl.h"
31 #include "ecmascript/mem/concurrent_marker.h"
32 #include "ecmascript/mem/partial_gc.h"
33 #include "ecmascript/mem/sparse_space.h"
34 #include "ecmascript/mem/mem_controller.h"
35 #include "ecmascript/mem/incremental_marker.h"
36 #include "ecmascript/mem/shared_heap/shared_concurrent_marker.h"
37 #include "ecmascript/mem/shared_heap/shared_concurrent_sweeper.h"
38 #include "ecmascript/mem/gc_key_stats.h"
39 #include "ecmascript/mem/gc_stats.h"
40 #include "ecmascript/mem/allocation_inspector.h"
41 #include "ecmascript/dfx/hprof/heap_sampling.h"
42 #include "ecmascript/tests/ecma_test_common.h"
43
44 using namespace panda;
45
46 using namespace panda::ecmascript;
47 using namespace panda::panda_file;
48 using namespace panda::pandasm;
49
50 namespace panda::test {
51 class GCTest : public BaseTestWithScope<false> {
52 public:
SetUp()53 void SetUp() override
54 {
55 JSRuntimeOptions options;
56 instance = JSNApi::CreateEcmaVM(options);
57 ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
58 thread = instance->GetJSThread();
59 thread->ManagedCodeBegin();
60 scope = new EcmaHandleScope(thread);
61 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
62 heap->GetConcurrentMarker()->EnableConcurrentMarking(EnableConcurrentMarkType::ENABLE);
63 heap->GetSweeper()->EnableConcurrentSweep(EnableConcurrentSweepType::ENABLE);
64 }
65 };
66
HWTEST_F_L0(GCTest,ArkToolsHintGC)67 HWTEST_F_L0(GCTest, ArkToolsHintGC)
68 {
69 Heap *heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
70 heap->GetConcurrentMarker()->EnableConcurrentMarking(EnableConcurrentMarkType::CONFIG_DISABLE);
71 auto getSizeAfterCreateAndCallHintGC = [this, heap] (size_t &newSize, size_t &finalSize) -> bool {
72 {
73 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread);
74 for (int i = 0; i < 2048; i++) {
75 [[maybe_unused]] JSHandle<TaggedArray> obj = thread->GetEcmaVM()->GetFactory()->
76 NewTaggedArray(10 * 1024, JSTaggedValue::Hole(), MemSpaceType::OLD_SPACE);
77 }
78 newSize = heap->GetCommittedSize();
79 }
80 std::vector<JSTaggedValue> vals{JSTaggedValue(static_cast<double>(2))};
81 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, vals,
82 6);
83 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
84 JSTaggedValue result = builtins::BuiltinsArkTools::HintGC(ecmaRuntimeCallInfo);
85 finalSize = heap->GetCommittedSize();
86 TestHelper::TearDownFrame(thread, prev);
87
88 return result.ToBoolean();
89 };
90 {
91 // Test HintGC() when sensitive.
92 heap->CollectGarbage(TriggerGCType::FULL_GC);
93 heap->NotifyHighSensitive(true);
94 size_t originSize = heap->GetCommittedSize();
95 size_t newSize = 0;
96 size_t finalSize = 0;
97 bool res = getSizeAfterCreateAndCallHintGC(newSize, finalSize);
98 EXPECT_FALSE(res);
99 EXPECT_TRUE(newSize > originSize);
100 EXPECT_TRUE(finalSize == newSize);
101 heap->NotifyHighSensitive(false);
102 }
103 {
104 #ifdef NDEBUG
105 size_t newSize = 0;
106 size_t finalSize = 0;
107 bool res = getSizeAfterCreateAndCallHintGC(newSize, finalSize);
108 EXPECT_TRUE(res);
109 #endif
110 }
111 }
112
HWTEST_F_L0(GCTest,LargeOverShootSizeTest)113 HWTEST_F_L0(GCTest, LargeOverShootSizeTest)
114 {
115 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
116 size_t originalYoungSize = heap->GetNewSpace()->GetCommittedSize();
117
118 EXPECT_FALSE(heap->GetNewSpace()->CommittedSizeIsLarge());
119 heap->GetConcurrentMarker()->ConfigConcurrentMark(false);
120 heap->NotifyHighSensitive(true);
121 size_t originalCapacity = heap->GetNewSpace()->GetInitialCapacity();
122 size_t originalOverShootSize = heap->GetNewSpace()->GetOvershootSize();
123 {
124 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread);
125 for (int i = 0; i < 300; i++) {
126 [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(
127 10 * 1024, JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE);
128 }
129 size_t newYoungSize = heap->GetNewSpace()->GetCommittedSize();
130 EXPECT_TRUE(originalYoungSize < newYoungSize);
131
132 heap->NotifyHighSensitive(false);
133 heap->CollectGarbage(TriggerGCType::YOUNG_GC);
134 newYoungSize = heap->GetNewSpace()->GetCommittedSize();
135 size_t newOverShootSize = heap->GetNewSpace()->GetOvershootSize();
136 size_t newCapacity = heap->GetNewSpace()->GetInitialCapacity();
137 EXPECT_TRUE(originalYoungSize < newYoungSize);
138 EXPECT_TRUE(originalOverShootSize < newOverShootSize);
139 EXPECT_TRUE(0 < newOverShootSize);
140 EXPECT_TRUE(originalCapacity < newCapacity);
141 EXPECT_TRUE(heap->GetNewSpace()->GetMaximumCapacity() == newCapacity);
142 }
143 originalOverShootSize = heap->GetNewSpace()->GetOvershootSize();
144 {
145 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread);
146 for (int i = 0; i < 2049; i++) {
147 [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(
148 1024, JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE);
149 }
150 }
151 size_t newSize = heap->GetNewSpace()->GetCommittedSize();
152 EXPECT_TRUE(originalYoungSize <= newSize);
153 }
154
HWTEST_F_L0(GCTest,CheckAndTriggerSharedGCTest001)155 HWTEST_F_L0(GCTest, CheckAndTriggerSharedGCTest001)
156 {
157 SharedHeap *heap = SharedHeap::GetInstance();
158 ASSERT_EQ(heap->CheckAndTriggerSharedGC(thread), false);
159 }
160
HWTEST_F_L0(GCTest,CheckHugeAndTriggerSharedGCTest001)161 HWTEST_F_L0(GCTest, CheckHugeAndTriggerSharedGCTest001)
162 {
163 SharedHeap *heap = SharedHeap::GetInstance();
164 ASSERT_EQ(heap->CheckHugeAndTriggerSharedGC(thread, 1374210560), true);
165 }
166
HWTEST_F_L0(GCTest,CheckHugeAndTriggerSharedGCTest002)167 HWTEST_F_L0(GCTest, CheckHugeAndTriggerSharedGCTest002)
168 {
169 SharedHeap *heap = SharedHeap::GetInstance();
170 ASSERT_EQ(heap->CheckHugeAndTriggerSharedGC(thread, 1), false);
171 }
172
HWTEST_F_L0(GCTest,ObjectExceedMaxHeapSizeTest001)173 HWTEST_F_L0(GCTest, ObjectExceedMaxHeapSizeTest001)
174 {
175 SharedHeap *heap = SharedHeap::GetInstance();
176 ASSERT_EQ(heap->ObjectExceedMaxHeapSize(), false);
177 }
178
HWTEST_F_L0(GCTest,CheckAndTriggerHintGCTest001)179 HWTEST_F_L0(GCTest, CheckAndTriggerHintGCTest001)
180 {
181 #ifdef NDEBUG
182 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
183 heap->CollectGarbage(TriggerGCType::OLD_GC);
184 ASSERT_EQ(heap->CheckAndTriggerHintGC(MemoryReduceDegree::LOW, GCReason::HINT_GC), false);
185 {
186 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread);
187 for (int i = 0; i < 4048; i++) {
188 [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(
189 1024, JSTaggedValue::Hole(), MemSpaceType::OLD_SPACE);
190 }
191 }
192 #ifndef PANDA_TARGET_32
193 ASSERT_EQ(heap->CheckAndTriggerHintGC(MemoryReduceDegree::LOW, GCReason::HINT_GC), true);
194 #else
195 ASSERT_EQ(heap->CheckAndTriggerHintGC(MemoryReduceDegree::LOW, GCReason::HINT_GC), false);
196 #endif
197 #endif
198 }
199
HWTEST_F_L0(GCTest,CheckAndTriggerHintGCTest002)200 HWTEST_F_L0(GCTest, CheckAndTriggerHintGCTest002)
201 {
202 #ifdef NDEBUG
203 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
204 heap->CollectGarbage(TriggerGCType::FULL_GC);
205 ASSERT_EQ(heap->CheckAndTriggerHintGC(MemoryReduceDegree::MIDDLE, GCReason::HINT_GC), false);
206 {
207 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread);
208 for (int i = 0; i < 4048; i++) {
209 [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(
210 1024, JSTaggedValue::Hole(), MemSpaceType::OLD_SPACE);
211 }
212 }
213 ASSERT_EQ(heap->CheckAndTriggerHintGC(MemoryReduceDegree::MIDDLE, GCReason::HINT_GC), true);
214 #endif
215 }
216
HWTEST_F_L0(GCTest,CheckAndTriggerHintGCTest003)217 HWTEST_F_L0(GCTest, CheckAndTriggerHintGCTest003)
218 {
219 #ifdef NDEBUG
220 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
221 heap->CollectGarbage(TriggerGCType::FULL_GC);
222 ASSERT_EQ(heap->CheckAndTriggerHintGC(MemoryReduceDegree::HIGH, GCReason::HINT_GC), false);
223 {
224 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread);
225 for (int i = 0; i < 1049; i++) {
226 [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(
227 1024, JSTaggedValue::Hole(), MemSpaceType::OLD_SPACE);
228 }
229 }
230 ASSERT_EQ(heap->CheckAndTriggerHintGC(MemoryReduceDegree::HIGH, GCReason::HINT_GC), true);
231 #endif
232 }
233
HWTEST_F_L0(GCTest,CheckAndTriggerHintGCTest004)234 HWTEST_F_L0(GCTest, CheckAndTriggerHintGCTest004)
235 {
236 #ifdef NDEBUG
237 auto sHeap = SharedHeap::GetInstance();
238 sHeap->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::OTHER>(thread);
239 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
240 ASSERT_EQ(heap->CheckAndTriggerHintGC(MemoryReduceDegree::LOW, GCReason::HINT_GC), false);
241 {
242 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread);
243 for (int i = 0; i < 4048; i++) {
244 [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->
245 NewSOldSpaceTaggedArray(1024, JSTaggedValue::Undefined());
246 }
247 }
248 ASSERT_EQ(heap->CheckAndTriggerHintGC(MemoryReduceDegree::LOW, GCReason::HINT_GC), true);
249 #endif
250 }
251
HWTEST_F_L0(GCTest,CheckAndTriggerHintGCTest005)252 HWTEST_F_L0(GCTest, CheckAndTriggerHintGCTest005)
253 {
254 #ifdef NDEBUG
255 auto sHeap = SharedHeap::GetInstance();
256 sHeap->CollectGarbage<TriggerGCType::SHARED_FULL_GC, GCReason::OTHER>(thread);
257 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
258 ASSERT_EQ(heap->CheckAndTriggerHintGC(MemoryReduceDegree::MIDDLE, GCReason::HINT_GC), false);
259 {
260 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread);
261 for (int i = 0; i < 4048; i++) {
262 [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->
263 NewSOldSpaceTaggedArray(1024, JSTaggedValue::Undefined());
264 }
265 }
266 ASSERT_EQ(heap->CheckAndTriggerHintGC(MemoryReduceDegree::MIDDLE, GCReason::HINT_GC), true);
267 #endif
268 }
269
HWTEST_F_L0(GCTest,CheckAndTriggerHintGCTest006)270 HWTEST_F_L0(GCTest, CheckAndTriggerHintGCTest006)
271 {
272 #ifdef NDEBUG
273 auto sHeap = SharedHeap::GetInstance();
274 sHeap->CollectGarbage<TriggerGCType::SHARED_FULL_GC, GCReason::OTHER>(thread);
275 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
276 ASSERT_EQ(heap->CheckAndTriggerHintGC(MemoryReduceDegree::HIGH, GCReason::HINT_GC), false);
277 {
278 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread);
279 for (int i = 0; i < 2049; i++) {
280 [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->
281 NewSOldSpaceTaggedArray(1024, JSTaggedValue::Undefined());
282 }
283 }
284 ASSERT_EQ(heap->CheckAndTriggerHintGC(MemoryReduceDegree::HIGH, GCReason::HINT_GC), true);
285 #endif
286 }
287
HWTEST_F_L0(GCTest,CalculateIdleDurationTest002)288 HWTEST_F_L0(GCTest, CalculateIdleDurationTest002)
289 {
290 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
291 heap->SetMarkType(MarkType::MARK_YOUNG);
292 ASSERT_EQ(heap->GetMarkType(), MarkType::MARK_YOUNG);
293 heap->CalculateIdleDuration();
294 }
295
HWTEST_F_L0(GCTest,CalculateIdleDurationTest003)296 HWTEST_F_L0(GCTest, CalculateIdleDurationTest003)
297 {
298 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
299 heap->SetMarkType(MarkType::MARK_FULL);
300 ASSERT_EQ(heap->GetMarkType(), MarkType::MARK_FULL);
301 heap->CalculateIdleDuration();
302 }
303
HWTEST_F_L0(GCTest,TryTriggerFullMarkBySharedLimitTest001)304 HWTEST_F_L0(GCTest, TryTriggerFullMarkBySharedLimitTest001)
305 {
306 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
307 ASSERT_EQ(heap->TryTriggerFullMarkBySharedLimit(), false);
308 }
309
HWTEST_F_L0(GCTest,TryTriggerFullMarkBySharedLimitTest002)310 HWTEST_F_L0(GCTest, TryTriggerFullMarkBySharedLimitTest002)
311 {
312 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
313 heap->SetIdleTask(IdleTaskType::FINISH_MARKING);
314 ASSERT_EQ(heap->TryTriggerFullMarkBySharedLimit(), false);
315 }
316
HWTEST_F_L0(GCTest,TryTriggerFullMarkBySharedLimitTest003)317 HWTEST_F_L0(GCTest, TryTriggerFullMarkBySharedLimitTest003)
318 {
319 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
320 for (size_t i = 0; i < 4; i++) {
321 ConcurrentMarker::TryIncreaseTaskCounts();
322 }
323 #ifndef PANDA_TARGET_32
324 ASSERT_EQ(heap->TryTriggerFullMarkBySharedLimit(), true);
325 #else
326 ASSERT_EQ(heap->TryTriggerFullMarkBySharedLimit(), false);
327 #endif
328 }
329
HWTEST_F_L0(GCTest,CheckAndTriggerTaskFinishedGCTest001)330 HWTEST_F_L0(GCTest, CheckAndTriggerTaskFinishedGCTest001)
331 {
332 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
333 heap->CheckAndTriggerTaskFinishedGC();
334 }
335
HWTEST_F_L0(GCTest,TryTriggerFullMarkBySharedSizeTest001)336 HWTEST_F_L0(GCTest, TryTriggerFullMarkBySharedSizeTest001)
337 {
338 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
339 heap->TryTriggerFullMarkBySharedSize(81579214);
340 }
341
HWTEST_F_L0(GCTest,DecreaseNativeBindingSizeTest001)342 HWTEST_F_L0(GCTest, DecreaseNativeBindingSizeTest001)
343 {
344 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
345 heap->DecreaseNativeBindingSize(0);
346 }
347
HWTEST_F_L0(GCTest,TriggerConcurrentMarkingTest001)348 HWTEST_F_L0(GCTest, TriggerConcurrentMarkingTest001)
349 {
350 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
351 heap->SetMarkType(MarkType::MARK_FULL);
352 heap->SetIdleTask(IdleTaskType::YOUNG_GC);
353 heap->TriggerConcurrentMarking();
354 }
355
HWTEST_F_L0(GCTest,TriggerIdleCollectionTest001)356 HWTEST_F_L0(GCTest, TriggerIdleCollectionTest001)
357 {
358 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
359 heap->SetIdleTask(IdleTaskType::NO_TASK);
360 heap->TriggerIdleCollection(1000);
361 }
362
HWTEST_F_L0(GCTest,TriggerIdleCollectionTest002)363 HWTEST_F_L0(GCTest, TriggerIdleCollectionTest002)
364 {
365 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
366 heap->SetIdleTask(IdleTaskType::INCREMENTAL_MARK);
367 heap->TriggerIdleCollection(1000);
368 }
369
HWTEST_F_L0(GCTest,TriggerIdleCollectionTest003)370 HWTEST_F_L0(GCTest, TriggerIdleCollectionTest003)
371 {
372 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
373 heap->SetIdleTask(IdleTaskType::FINISH_MARKING);
374 heap->TriggerIdleCollection(-1);
375 }
376
HWTEST_F_L0(GCTest,TriggerIdleCollectionTest004)377 HWTEST_F_L0(GCTest, TriggerIdleCollectionTest004)
378 {
379 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
380 heap->SetIdleTask(IdleTaskType::FINISH_MARKING);
381 heap->SetMarkType(MarkType::MARK_FULL);
382 heap->TriggerIdleCollection(1000);
383 }
384
HWTEST_F_L0(GCTest,TriggerIdleCollectionTest006)385 HWTEST_F_L0(GCTest, TriggerIdleCollectionTest006)
386 {
387 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
388 heap->SetIdleTask(IdleTaskType::YOUNG_GC);
389 heap->TriggerIdleCollection(1000);
390 }
391
HWTEST_F_L0(GCTest,NotifyFinishColdStartTest001)392 HWTEST_F_L0(GCTest, NotifyFinishColdStartTest001)
393 {
394 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
395 heap->SetIdleTask(IdleTaskType::YOUNG_GC);
396 heap->NotifyFinishColdStart(true);
397 }
398
HWTEST_F_L0(GCTest,NotifyFinishColdStartSoonTest001)399 HWTEST_F_L0(GCTest, NotifyFinishColdStartSoonTest001)
400 {
401 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
402 heap->NotifyFinishColdStartSoon();
403 }
404
HWTEST_F_L0(GCTest,NeedStopCollectionTest001)405 HWTEST_F_L0(GCTest, NeedStopCollectionTest001)
406 {
407 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
408 heap->SetOnSerializeEvent(true);
409 ASSERT_EQ(heap->NeedStopCollection(), true);
410 }
411
HWTEST_F_L0(GCTest,ReclaimTest001)412 HWTEST_F_L0(GCTest, ReclaimTest001)
413 {
414 SharedHeap *heap = SharedHeap::GetInstance();
415 heap->DisableParallelGC(thread);
416 heap->Reclaim(TriggerGCType::YOUNG_GC);
417 }
418
HWTEST_F_L0(GCTest,CollectGarbageTest003)419 HWTEST_F_L0(GCTest, CollectGarbageTest003)
420 {
421 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
422 heap->GetJSThread()->SetMarkStatus(MarkStatus::READY_TO_MARK);
423 heap->CollectGarbage(TriggerGCType::FULL_GC, GCReason::IDLE);
424 }
425
HWTEST_F_L0(GCTest,NeedStopCollectionTest002)426 HWTEST_F_L0(GCTest, NeedStopCollectionTest002)
427 {
428 SharedHeap *heap = SharedHeap::GetInstance();
429 heap->SetSensitiveStatus(AppSensitiveStatus::ENTER_HIGH_SENSITIVE);
430 ASSERT_EQ(heap->NeedStopCollection(), true);
431 }
432
HWTEST_F_L0(GCTest,NeedStopCollectionTest003)433 HWTEST_F_L0(GCTest, NeedStopCollectionTest003)
434 {
435 SharedHeap *heap = SharedHeap::GetInstance();
436 heap->SetSensitiveStatus(AppSensitiveStatus::ENTER_HIGH_SENSITIVE);
437 heap->GetOldSpace()->SetInitialCapacity(1000);
438 ASSERT_EQ(heap->NeedStopCollection(), false);
439 }
440
HWTEST_F_L0(GCTest,TriggerIdleCollectionTest007)441 HWTEST_F_L0(GCTest, TriggerIdleCollectionTest007)
442 {
443 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
444 heap->SetIdleTask(IdleTaskType::INCREMENTAL_MARK);
445 ASSERT_EQ(heap->GetIncrementalMarker()->GetIncrementalGCStates(), IncrementalGCStates::ROOT_SCAN);
446 heap->GetIncrementalMarker()->TriggerIncrementalMark(1000);
447 heap->TriggerIdleCollection(1000);
448 }
449
HWTEST_F_L0(GCTest,CheckAndTriggerSharedGCTest002)450 HWTEST_F_L0(GCTest, CheckAndTriggerSharedGCTest002)
451 {
452 SharedHeap *heap = SharedHeap::GetInstance();
453 heap->GetOldSpace()->SetInitialCapacity(100);
454 ASSERT_EQ(heap->CheckAndTriggerSharedGC(thread), true);
455 }
456
HWTEST_F_L0(GCTest,CheckAndTriggerSharedGCTest003)457 HWTEST_F_L0(GCTest, CheckAndTriggerSharedGCTest003)
458 {
459 SharedHeap *heap = SharedHeap::GetInstance();
460 heap->GetOldSpace()->SetInitialCapacity(100);
461 thread->SetSharedMarkStatus(SharedMarkStatus::CONCURRENT_MARKING_OR_FINISHED);
462 ASSERT_EQ(heap->CheckAndTriggerSharedGC(thread), true);
463 }
464
HWTEST_F_L0(GCTest,CheckAndTriggerSharedGCTest004)465 HWTEST_F_L0(GCTest, CheckAndTriggerSharedGCTest004)
466 {
467 SharedHeap *heap = SharedHeap::GetInstance();
468 thread->SetSharedMarkStatus(SharedMarkStatus::CONCURRENT_MARKING_OR_FINISHED);
469 ASSERT_EQ(heap->CheckAndTriggerSharedGC(thread), false);
470 }
471
HWTEST_F_L0(GCTest,CheckHugeAndTriggerSharedGCTest003)472 HWTEST_F_L0(GCTest, CheckHugeAndTriggerSharedGCTest003)
473 {
474 SharedHeap *heap = SharedHeap::GetInstance();
475 heap->GetOldSpace()->SetInitialCapacity(100);
476 ASSERT_EQ(heap->CheckHugeAndTriggerSharedGC(thread, 1), false);
477 }
478
HWTEST_F_L0(GCTest,CheckHugeAndTriggerSharedGCTest004)479 HWTEST_F_L0(GCTest, CheckHugeAndTriggerSharedGCTest004)
480 {
481 SharedHeap *heap = SharedHeap::GetInstance();
482 heap->GetOldSpace()->SetInitialCapacity(100);
483 thread->SetSharedMarkStatus(SharedMarkStatus::CONCURRENT_MARKING_OR_FINISHED);
484 ASSERT_EQ(heap->CheckHugeAndTriggerSharedGC(thread, 1), false);
485 }
486
HWTEST_F_L0(GCTest,CheckHugeAndTriggerSharedGCTest005)487 HWTEST_F_L0(GCTest, CheckHugeAndTriggerSharedGCTest005)
488 {
489 SharedHeap *heap = SharedHeap::GetInstance();
490 thread->SetSharedMarkStatus(SharedMarkStatus::CONCURRENT_MARKING_OR_FINISHED);
491 ASSERT_EQ(heap->CheckHugeAndTriggerSharedGC(thread, 1), false);
492 }
493
HWTEST_F_L0(GCTest,CheckOngoingConcurrentMarkingTest001)494 HWTEST_F_L0(GCTest, CheckOngoingConcurrentMarkingTest001)
495 {
496 SharedHeap *heap = SharedHeap::GetInstance();
497 heap->GetConcurrentMarker()->ConfigConcurrentMark(false);
498 ASSERT_EQ(heap->CheckOngoingConcurrentMarking(), false);
499 }
500
HWTEST_F_L0(GCTest,CheckOngoingConcurrentMarkingTest002)501 HWTEST_F_L0(GCTest, CheckOngoingConcurrentMarkingTest002)
502 {
503 SharedHeap *heap = SharedHeap::GetInstance();
504 heap->GetConcurrentMarker()->ConfigConcurrentMark(true);
505 ASSERT_EQ(heap->CheckOngoingConcurrentMarking(), false);
506 }
507
HWTEST_F_L0(GCTest,SelectGCTypeTest001)508 HWTEST_F_L0(GCTest, SelectGCTypeTest001)
509 {
510 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
511 heap->GetOldSpace()->SetInitialCapacity(100);
512 ASSERT_EQ(heap->SelectGCType(), OLD_GC);
513 }
514
HWTEST_F_L0(GCTest,SelectGCTypeTest002)515 HWTEST_F_L0(GCTest, SelectGCTypeTest002)
516 {
517 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
518 heap->GetOldSpace()->SetMaximumCapacity(1000);
519 heap->GetOldSpace()->SetOvershootSize(1000);
520 heap->GetNewSpace()->IncreaseCommitted(100000);
521 ASSERT_EQ(heap->SelectGCType(), OLD_GC);
522 }
523
HWTEST_F_L0(GCTest,CollectGarbageTest008)524 HWTEST_F_L0(GCTest, CollectGarbageTest008)
525 {
526 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
527 heap->GetIncrementalMarker()->TriggerIncrementalMark(1000);
528 heap->CollectGarbage(TriggerGCType::YOUNG_GC, GCReason::TRIGGER_BY_TASKPOOL);
529 }
530
HWTEST_F_L0(GCTest,CollectGarbageTest009)531 HWTEST_F_L0(GCTest, CollectGarbageTest009)
532 {
533 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
534 heap->GetConcurrentMarker()->EnableConcurrentMarking(EnableConcurrentMarkType::REQUEST_DISABLE);
535 #ifndef PANDA_TARGET_32
536 ASSERT_TRUE(heap->GetConcurrentMarker()->IsRequestDisabled());
537 #else
538 ASSERT_FALSE(heap->GetConcurrentMarker()->IsRequestDisabled());
539 #endif
540 heap->CollectGarbage(TriggerGCType::YOUNG_GC, GCReason::TRIGGER_BY_TASKPOOL);
541 }
542
HWTEST_F_L0(GCTest,TryTriggerIdleCollectionTest007)543 HWTEST_F_L0(GCTest, TryTriggerIdleCollectionTest007)
544 {
545 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
546 heap->SetIdleTask(IdleTaskType::NO_TASK);
547 heap->TryTriggerIdleCollection();
548 }
549
HWTEST_F_L0(GCTest,TryTriggerFullMarkBySharedLimitTest004)550 HWTEST_F_L0(GCTest, TryTriggerFullMarkBySharedLimitTest004)
551 {
552 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
553 heap->GetConcurrentMarker()->ConfigConcurrentMark(true);
554 heap->TryTriggerFullMarkBySharedLimit();
555 heap->GetConcurrentMarker()->ConfigConcurrentMark(false);
556 heap->TryTriggerFullMarkBySharedLimit();
557 }
558
HWTEST_F_L0(GCTest,TriggerConcurrentMarkingTest003)559 HWTEST_F_L0(GCTest, TriggerConcurrentMarkingTest003)
560 {
561 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
562 heap->GetConcurrentMarker()->ConfigConcurrentMark(true);
563 heap->TriggerConcurrentMarking();
564 heap->GetConcurrentMarker()->ConfigConcurrentMark(false);
565 heap->TriggerConcurrentMarking();
566 }
567
HWTEST_F_L0(GCTest,TriggerIdleCollectionTest008)568 HWTEST_F_L0(GCTest, TriggerIdleCollectionTest008)
569 {
570 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
571 heap->TriggerIdleCollection(1000);
572 heap->ClearIdleTask();
573 heap->TriggerIdleCollection(1000);
574 }
575
HWTEST_F_L0(GCTest,TriggerIdleCollectionTest009)576 HWTEST_F_L0(GCTest, TriggerIdleCollectionTest009)
577 {
578 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
579 heap->SetIdleTask(IdleTaskType::YOUNG_GC);
580 heap->TriggerIdleCollection(5);
581 }
582
HWTEST_F_L0(GCTest,NotifyFinishColdStartTest002)583 HWTEST_F_L0(GCTest, NotifyFinishColdStartTest002)
584 {
585 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
586 heap->NotifyPostFork();
587 heap->NotifyFinishColdStart(true);
588 }
589
HWTEST_F_L0(GCTest,NeedStopCollectionTest004)590 HWTEST_F_L0(GCTest, NeedStopCollectionTest004)
591 {
592 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
593 heap->SetOnSerializeEvent(false);
594 heap->SetSensitiveStatus(AppSensitiveStatus::ENTER_HIGH_SENSITIVE);
595 ASSERT_EQ(heap->NeedStopCollection(), true);
596 }
597
HWTEST_F_L0(GCTest,TryToGetSuitableSweptRegionTest001)598 HWTEST_F_L0(GCTest, TryToGetSuitableSweptRegionTest001)
599 {
600 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
601 SparseSpace *space = heap->GetSpaceWithType(MemSpaceType::OLD_SPACE);
602 space->FinishFillSweptRegion();
603 ASSERT_EQ(space->TryToGetSuitableSweptRegion(100), nullptr);
604 }
605
HWTEST_F_L0(GCTest,CalculateGrowingFactorTest001)606 HWTEST_F_L0(GCTest, CalculateGrowingFactorTest001)
607 {
608 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
609 heap->SetMemGrowingType(MemGrowingType::CONSERVATIVE);
610 MemController *memController = new MemController(heap);
611 memController->CalculateGrowingFactor(0, 0);
612 }
613
HWTEST_F_L0(GCTest,CalculateGrowingFactorTest002)614 HWTEST_F_L0(GCTest, CalculateGrowingFactorTest002)
615 {
616 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
617 heap->SetMemGrowingType(MemGrowingType::PRESSURE);
618 MemController *memController = new MemController(heap);
619 memController->CalculateGrowingFactor(0, 0);
620 }
621
HWTEST_F_L0(GCTest,StartCalculationBeforeGCTest001)622 HWTEST_F_L0(GCTest, StartCalculationBeforeGCTest001)
623 {
624 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
625 MemController *memController = new MemController(heap);
626 std::this_thread::sleep_for(std::chrono::milliseconds(10));
627 memController->StartCalculationBeforeGC();
628 memController->StopCalculationAfterGC(TriggerGCType::YOUNG_GC);
629 }
630
HWTEST_F_L0(GCTest,StartCalculationBeforeGCTest002)631 HWTEST_F_L0(GCTest, StartCalculationBeforeGCTest002)
632 {
633 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
634 MemController *memController = new MemController(heap);
635 memController->StopCalculationAfterGC(TriggerGCType::YOUNG_GC);
636 }
637
HWTEST_F_L0(GCTest,DryTrunkExpandTest001)638 HWTEST_F_L0(GCTest, DryTrunkExpandTest001)
639 {
640 auto trunk = thread->GetEcmaVM()->GetChunk();
641 DynChunk *dynChunk = new DynChunk(trunk);
642 ASSERT_TRUE(dynChunk->GetAllocatedSize() < 1000);
643 dynChunk->SetError();
644 ASSERT_EQ(dynChunk->Expand(1000), -1);
645 }
646
HWTEST_F_L0(GCTest,DryTrunkInsertTest001)647 HWTEST_F_L0(GCTest, DryTrunkInsertTest001)
648 {
649 auto trunk = thread->GetEcmaVM()->GetChunk();
650 DynChunk *dynChunk = new DynChunk(trunk);
651 ASSERT_EQ(dynChunk->Insert(5, 5), -1);
652 }
653
HWTEST_F_L0(GCTest,DryTrunkInsertTest002)654 HWTEST_F_L0(GCTest, DryTrunkInsertTest002)
655 {
656 auto trunk = thread->GetEcmaVM()->GetChunk();
657 DynChunk *dynChunk = new DynChunk(trunk);
658 dynChunk->SetError();
659 ASSERT_EQ(dynChunk->Insert(0, 5), -1);
660 }
661
HWTEST_F_L0(GCTest,AdvanceAllocationInspectorTest001)662 HWTEST_F_L0(GCTest, AdvanceAllocationInspectorTest001)
663 {
664 auto counter = new AllocationCounter();
665 counter->AdvanceAllocationInspector(100);
666 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
667 auto profiler = new HeapSampling(thread->GetEcmaVM(), heap, 10, 3);
668 auto inspector = new AllocationInspector(heap, 10, profiler);
669 counter->AddAllocationInspector(inspector);
670 counter->AdvanceAllocationInspector(0);
671 }
672
HWTEST_F_L0(GCTest,InvokeAllocationInspectorTest001)673 HWTEST_F_L0(GCTest, InvokeAllocationInspectorTest001)
674 {
675 auto counter = new AllocationCounter();
676 counter->InvokeAllocationInspector(10000, 100, 100);
677 auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
678 auto profiler = new HeapSampling(thread->GetEcmaVM(), heap, 10, 3);
679 auto inspector = new AllocationInspector(heap, 10, profiler);
680 counter->AddAllocationInspector(inspector);
681 counter->InvokeAllocationInspector(10000, 100, 100);
682 }
683
HWTEST_F_L0(GCTest,OldSpaceValidCheck)684 HWTEST_F_L0(GCTest, OldSpaceValidCheck)
685 {
686 static constexpr size_t kLength = 10 * 1024;
687 static constexpr size_t kCount = 2;
688 static constexpr size_t kLimit = 380 * 1024 * 1024;
689 instance->GetJSOptions().SetEnableForceGC(false);
690 Heap *heap = const_cast<Heap *>(instance->GetHeap());
691 ObjectFactory *factory = heap->GetEcmaVM()->GetFactory();
692 auto array = factory->NewTaggedArray(kLength, JSTaggedValue::Hole(), MemSpaceType::OLD_SPACE);
693 heap->ShouldThrowOOMError(true);
694 heap->GetOldSpace()->IncreaseLiveObjectSize(kLimit);
695 for (size_t i = 0; i < kCount; i++) {
696 array = factory->NewTaggedArray(kLength, JSTaggedValue::Hole(), MemSpaceType::OLD_SPACE);
697 Region *objectRegion = Region::ObjectAddressToRange(*array);
698 bool inHeap = false;
699 heap->GetOldSpace()->EnumerateRegions([objectRegion, &inHeap](Region *each) {
700 if (objectRegion == each) {
701 inHeap = true;
702 }
703 });
704 EXPECT_TRUE(inHeap);
705 }
706 }
707
HWTEST_F_L0(GCTest,DisableSharedConcurrentSweep)708 HWTEST_F_L0(GCTest, DisableSharedConcurrentSweep)
709 {
710 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
711 SharedHeap *sHeap = SharedHeap::GetInstance();
712 sHeap->GetSweeper()->ConfigConcurrentSweep(false);
713 {
714 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread);
715 [[maybe_unused]] JSHandle<EcmaString> key1(factory->NewFromASCII("error1"));
716 [[maybe_unused]] JSHandle<EcmaString> key2(factory->NewFromASCII("error2"));
717 [[maybe_unused]] JSHandle<EcmaString> msg(factory->NewFromASCII("this is error"));
718 [[maybe_unused]] JSHandle<EcmaString> key3(factory->NewFromASCII("error3"));
719 [[maybe_unused]] JSHandle<EcmaString> key4(factory->NewFromASCII("error4"));
720 [[maybe_unused]] JSHandle<EcmaString> msg2(factory->NewFromASCII("this is error2"));
721 auto* newBitSetVector = new std::vector<std::bitset<JSAPIBitVector::BIT_SET_LENGTH>>();
722 int32_t capacity = 256;
723 std::bitset<JSAPIBitVector::BIT_SET_LENGTH> initBitSet;
724 newBitSetVector->resize(capacity, initBitSet);
725 auto deleter = []([[maybe_unused]] void *env, void *pointer, [[maybe_unused]] void *data) {
726 if (pointer == nullptr) {
727 return;
728 }
729 delete reinterpret_cast<std::vector<std::bitset<JSAPIBitVector::BIT_SET_LENGTH>> *>(pointer);
730 };
731 [[maybe_unused]] JSHandle<JSNativePointer> pointer = factory->NewSJSNativePointer(newBitSetVector,
732 deleter,
733 newBitSetVector);
734 const char *filename1 = "__JSPandaFileManagerTest1.pa";
735 const char *filename2 = "__JSPandaFileManagerTest2.pa";
736 const char *data = R"(
737 .function void foo() {}
738 )";
739 JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
740 Parser parser;
741 auto res = parser.Parse(data);
742 std::unique_ptr<const File> pfPtr1 = pandasm::AsmEmitter::Emit(res.Value());
743 std::unique_ptr<const File> pfPtr2 = pandasm::AsmEmitter::Emit(res.Value());
744 std::shared_ptr<JSPandaFile> pf1 = pfManager->NewJSPandaFile(pfPtr1.release(), CString(filename1));
745 std::shared_ptr<JSPandaFile> pf2 = pfManager->NewJSPandaFile(pfPtr2.release(), CString(filename2));
746 pfManager->AddJSPandaFile(pf1);
747 pfManager->AddJSPandaFile(pf2);
748
749 JSHandle<ConstantPool> constpool1 = instance->GetFactory()->NewSConstantPool(1);
750 JSHandle<ConstantPool> constpool2 = instance->GetFactory()->NewSConstantPool(2);
751 constpool1 = Runtime::GetInstance()->AddOrUpdateConstpool(pf1.get(), constpool1, 0);
752 constpool2 = Runtime::GetInstance()->AddOrUpdateConstpool(pf2.get(), constpool2, 0);
753 }
754 sHeap->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::OTHER>(thread);
755 sHeap->WaitGCFinished(thread);
756 sHeap->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::OTHER>(thread);
757 sHeap->WaitGCFinished(thread);
758 sHeap->GetSweeper()->ConfigConcurrentSweep(true);
759 };
760
HWTEST_F_L0(GCTest,RawHeapSendSysEventDataSize)761 HWTEST_F_L0(GCTest, RawHeapSendSysEventDataSize)
762 {
763 const std::string fileName = "/data/log/faultlog/temp/jsheap.rawheap";
764 uint64_t fileSize = 256;
765 std::vector<std::string> filePaths;
766 std::vector<uint64_t> fileSizes;
767
768 filePaths.emplace_back(fileName);
769 fileSizes.emplace_back(fileSize);
770 GCKeyStats *keystats = thread->GetEcmaVM()->GetEcmaGCKeyStats();
771 int32_t ret = keystats->SendSysEventDataSize(filePaths, fileSizes);
772 ASSERT_EQ(ret, 0);
773 }
774 } // namespace panda::test
775