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 "ecmascript/ecma_string.h"
17 #include "ecmascript/ecma_vm.h"
18 #include "ecmascript/js_hclass.h"
19 #include "ecmascript/js_object-inl.h"
20 #include "ecmascript/js_thread.h"
21
22 #include "ecmascript/mem/mem_common.h"
23 #include "ecmascript/mem/heap.h"
24 #include "ecmascript/mem/space.h"
25 #include "ecmascript/object_factory.h"
26 #include "ecmascript/tagged_array-inl.h"
27 #include "ecmascript/tests/test_helper.h"
28
29 using namespace panda::ecmascript;
30 using namespace panda::ecmascript::base;
31
32 namespace panda::test {
33 class MemControllerTest : public BaseTestWithScope<false> {
34 };
35
HWTEST_F_L0(MemControllerTest,AllocationVerify)36 HWTEST_F_L0(MemControllerTest, AllocationVerify)
37 {
38 #ifdef NDEBUG
39 auto ecmaVm = thread->GetEcmaVM();
40 auto heap = const_cast<Heap *>(ecmaVm->GetHeap());
41 auto objectFactory = ecmaVm->GetFactory();
42 auto memController = heap->GetMemController();
43
44 heap->CollectGarbage(TriggerGCType::FULL_GC);
45
46 for (int i = 0; i < 1024; i++) {
47 // old space object
48 [[maybe_unused]] auto oldArray = objectFactory->NewTaggedArray(128, JSTaggedValue::Undefined(),
49 MemSpaceType::OLD_SPACE);
50 }
51 sleep(5);
52 heap->CollectGarbage(TriggerGCType::FULL_GC);
53 double mutatorSpeed1 = memController->GetCurrentOldSpaceAllocationThroughputPerMS(0);
54 for (int i = 0; i < 1024; i++) {
55 // old space object
56 [[maybe_unused]] auto oldArray = objectFactory->NewTaggedArray(128, JSTaggedValue::Undefined(),
57 MemSpaceType::OLD_SPACE);
58 }
59 sleep(10);
60
61 heap->CollectGarbage(TriggerGCType::FULL_GC);
62 double mutatorSpeed2 = memController->GetCurrentOldSpaceAllocationThroughputPerMS(0);
63 ASSERT_TRUE(mutatorSpeed2 < mutatorSpeed1);
64 #endif
65 }
66
HWTEST_F_L0(MemControllerTest,VerifyMutatorSpeed)67 HWTEST_F_L0(MemControllerTest, VerifyMutatorSpeed)
68 {
69 #ifdef NDEBUG
70 auto ecmaVm = thread->GetEcmaVM();
71 auto heap = const_cast<Heap *>(ecmaVm->GetHeap());
72 auto objectFactory = ecmaVm->GetFactory();
73 auto memController = heap->GetMemController();
74
75 heap->CollectGarbage(TriggerGCType::YOUNG_GC);
76 size_t oldSpaceAllocatedSizeBefore = memController->GetOldSpaceAllocAccumulatedSize();
77 size_t nonMovableSpaceAllocatedSizeBefore = memController->GetNonMovableSpaceAllocAccumulatedSize();
78 double allocDurationBefore = memController->GetAllocTimeMs();
79 sleep(1);
80
81 // new space object
82 [[maybe_unused]] auto newArray =
83 objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::SEMI_SPACE);
84 // old space object
85 auto oldArray = objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE);
86 // non movable object
87 auto nonMovableArray = objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::NON_MOVABLE);
88 // huge space object
89 static constexpr size_t SIZE = 1_MB;
90 auto hugeArray = objectFactory->NewTaggedArray(SIZE);
91
92 auto newSpace = heap->GetNewSpace();
93 size_t newSpaceAllocBytesSinceGC = newSpace->GetAllocatedSizeSinceGC(newSpace->GetTop());
94 ASSERT_EQ(newSpaceAllocBytesSinceGC, TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), 2));
95 heap->CollectGarbage(TriggerGCType::YOUNG_GC);
96 newSpace = heap->GetNewSpace();
97 ASSERT_EQ(newSpace->GetAllocatedSizeSinceGC(newSpace->GetTop()), static_cast<size_t>(0));
98
99 size_t oldSpaceAllocatedSizeAfter = memController->GetOldSpaceAllocAccumulatedSize();
100 size_t nonMovableSpaceAllocatedSizeAfter = memController->GetNonMovableSpaceAllocAccumulatedSize();
101 double allocDurationAfter = memController->GetAllocTimeMs();
102
103 size_t hugeObjectAllocSizeInLastGC = memController->GetHugeObjectAllocSizeSinceGC();
104
105 ASSERT_TRUE(allocDurationAfter - allocDurationBefore > 1000);
106 ASSERT_TRUE(oldSpaceAllocatedSizeAfter - oldSpaceAllocatedSizeBefore
107 == oldArray->ComputeSize(JSTaggedValue::TaggedTypeSize(), 2));
108 ASSERT_TRUE(nonMovableSpaceAllocatedSizeAfter - nonMovableSpaceAllocatedSizeBefore
109 == nonMovableArray->ComputeSize(JSTaggedValue::TaggedTypeSize(), 2));
110 // The allocated size of huge object must be larger than the object size.
111 ASSERT_TRUE(hugeObjectAllocSizeInLastGC > hugeArray->ComputeSize(JSTaggedValue::TaggedTypeSize(), SIZE));
112 #endif
113 }
114
HWTEST_F_L0(MemControllerTest,CalculateMarkCompactSpeedPerMSTest)115 HWTEST_F_L0(MemControllerTest, CalculateMarkCompactSpeedPerMSTest)
116 {
117 #ifdef NDEBUG
118 auto ecmaVm = thread->GetEcmaVM();
119 auto heap = const_cast<Heap *>(ecmaVm->GetHeap());
120 auto memController = heap->GetMemController();
121 auto compactSpeed = memController->CalculateMarkCompactSpeedPerMS();
122 EXPECT_TRUE(compactSpeed == 0);
123 #endif
124 }
125
HWTEST_F_L0(MemControllerTest,StartCalculationBeforeGC)126 HWTEST_F_L0(MemControllerTest, StartCalculationBeforeGC)
127 {
128 auto ecmaVm = thread->GetEcmaVM();
129 auto heap = const_cast<Heap *>(ecmaVm->GetHeap());
130 auto memController = heap->GetMemController();
131
132 double allocTimeMsBefore = memController->GetAllocTimeMs();
133 size_t oldSpaceSizeBefore = memController->GetOldSpaceAllocAccumulatedSize();
134 size_t nonMovableSpaceSizeBefore = memController->GetNonMovableSpaceAllocAccumulatedSize();
135 size_t codeSpaceSizeBefore = memController->GetCodeSpaceAllocAccumulatedSize();
136
137 sleep(1);
138 memController->StartCalculationBeforeGC();
139
140 double allocTimeMsAfter = memController->GetAllocTimeMs();
141 size_t oldSpaceSizeAfter = memController->GetOldSpaceAllocAccumulatedSize();
142 size_t nonMovableSpaceSizeAfter = memController->GetNonMovableSpaceAllocAccumulatedSize();
143 size_t codeSpaceSizeAfter = memController->GetCodeSpaceAllocAccumulatedSize();
144 double allocDurationSinceGc = memController->GetAllocDurationSinceGc();
145
146 EXPECT_TRUE(allocTimeMsAfter - allocTimeMsBefore > 1000);
147 EXPECT_TRUE(oldSpaceSizeAfter > oldSpaceSizeBefore);
148 EXPECT_TRUE(nonMovableSpaceSizeAfter > nonMovableSpaceSizeBefore);
149 EXPECT_TRUE(codeSpaceSizeAfter == codeSpaceSizeBefore);
150 EXPECT_TRUE(allocDurationSinceGc == allocTimeMsAfter - allocTimeMsBefore);
151 }
152
HWTEST_F_L0(MemControllerTest,StopCalculationAfterGC)153 HWTEST_F_L0(MemControllerTest, StopCalculationAfterGC)
154 {
155 auto ecmaVm = thread->GetEcmaVM();
156 auto heap = const_cast<Heap *>(ecmaVm->GetHeap());
157 auto objectFactory = ecmaVm->GetFactory();
158 auto memController = heap->GetMemController();
159 heap->CollectGarbage(TriggerGCType::FULL_GC);
160
161 [[maybe_unused]] auto newArray =
162 objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::SEMI_SPACE);
163 [[maybe_unused]] auto oldArray =
164 objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE);
165 [[maybe_unused]] auto nonMovableArray =
166 objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::NON_MOVABLE);
167 static constexpr size_t SIZE = 1_MB;
168 [[maybe_unused]] auto hugeArray = objectFactory->NewTaggedArray(SIZE);
169
170 heap->CollectGarbage(TriggerGCType::YOUNG_GC);
171
172 double allocDurationSinceGc = memController->GetAllocDurationSinceGc();
173 size_t codeSpaceAllocSizeSinceGC = memController->GetCodeSpaceAllocAccumulatedSize();
174 EXPECT_EQ(allocDurationSinceGc, static_cast<double>(0.0));
175 EXPECT_EQ(codeSpaceAllocSizeSinceGC, static_cast<size_t>(0));
176 size_t hugeObjectSize = heap->GetHugeObjectSpace()->GetHeapObjectSize();
177 size_t hugeAllocSizeSinceGC = memController->GetHugeObjectAllocSizeSinceGC();
178 EXPECT_EQ(hugeAllocSizeSinceGC, hugeObjectSize);
179 double markCompactSpeed = memController->CalculateMarkCompactSpeedPerMS();
180 EXPECT_GE(markCompactSpeed, 0);
181 }
182 } // namespace panda::test
183