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
24 using namespace panda::ecmascript;
25 using namespace panda::ecmascript::base;
26 using TRIGGER_IDLE_GC_TYPE = panda::JSNApi::TRIGGER_IDLE_GC_TYPE;
27 using TriggerGCData = std::pair<void*, uint8_t>;
28 using TriggerGCTaskCallback = std::function<void(TriggerGCData& data)>;
29
30 namespace panda::test {
31 class IdleGCTriggerTest : public BaseTestWithScope<false> {
32 public:
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
HWTEST_F_L0(IdleGCTriggerTest, NotifyLooperIdleStartTest001)48 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, NotifyLooperIdleStartTest002)56 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, NotifyLooperIdleEndTest001)68 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerHandleMarkFinishedTest001)76 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerLocalConcurrentMarkTest001)88 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerLocalConcurrentMarkTest002)98 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerLocalConcurrentMarkTest003)108 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleSharedOldGCTest001)118 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleSharedOldGCTest002)127 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleSharedOldGCTest003)138 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleSharedOldGCTest004)151 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleLocalOldGCTest001)161 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleLocalOldGCTest002)173 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleLocalOldGCTest003)183 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleLocalOldGCTest004)195 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleLocalOldGCTest005)211 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleLocalOldGCTest006)223 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, ReachIdleLocalOldGCThresholdsTest001)239 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, ReachIdleLocalOldGCThresholdsTest002)248 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryPostHandleMarkFinishedTest001)261 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryPostHandleMarkFinishedTest002)270 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleGCTest002)278 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleGCTest003)289 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleGCTest004)300 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleGCTest011)308 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleGCTest012)317 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, TryTriggerIdleGCTest013)328 HWTEST_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
HWTEST_F_L0(IdleGCTriggerTest, ShouldCheckIdleOldGCTest001)339 HWTEST_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