• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/mem_controller_utils.h"
24 #include "ecmascript/mem/heap.h"
25 #include "ecmascript/mem/space.h"
26 #include "ecmascript/object_factory.h"
27 #include "ecmascript/tagged_array-inl.h"
28 #include "ecmascript/tests/test_helper.h"
29 
30 using namespace panda::ecmascript;
31 using namespace panda::ecmascript::base;
32 
33 namespace panda::test {
34 class MemControllerTest : public BaseTestWithScope<false> {
35 };
36 
HWTEST_F_L0(MemControllerTest,AllocationVerify)37 HWTEST_F_L0(MemControllerTest, AllocationVerify)
38 {
39 #ifdef NDEBUG
40     auto ecmaVm = thread->GetEcmaVM();
41     auto heap = const_cast<Heap *>(ecmaVm->GetHeap());
42     auto objectFactory = ecmaVm->GetFactory();
43     auto memController = heap->GetMemController();
44 
45     heap->CollectGarbage(TriggerGCType::FULL_GC);
46 
47     for (int i = 0; i < 1024; i++) {
48         // old space object
49         [[maybe_unused]] auto oldArray = objectFactory->NewTaggedArray(128, JSTaggedValue::Undefined(),
50                                                                        MemSpaceType::OLD_SPACE);
51     }
52     sleep(5);
53     heap->CollectGarbage(TriggerGCType::FULL_GC);
54     double mutatorSpeed1 = memController->GetCurrentOldSpaceAllocationThroughputPerMS(0);
55     for (int i = 0; i < 1024; i++) {
56         // old space object
57         [[maybe_unused]] auto oldArray = objectFactory->NewTaggedArray(128, JSTaggedValue::Undefined(),
58                                                                        MemSpaceType::OLD_SPACE);
59     }
60     sleep(10);
61 
62     heap->CollectGarbage(TriggerGCType::FULL_GC);
63     double mutatorSpeed2 = memController->GetCurrentOldSpaceAllocationThroughputPerMS(0);
64     ASSERT_TRUE(mutatorSpeed2 < mutatorSpeed1);
65 #endif
66 }
67 
HWTEST_F_L0(MemControllerTest,VerifyMutatorSpeed)68 HWTEST_F_L0(MemControllerTest, VerifyMutatorSpeed)
69 {
70 #ifdef NDEBUG
71     auto ecmaVm = thread->GetEcmaVM();
72     auto heap = const_cast<Heap *>(ecmaVm->GetHeap());
73     auto objectFactory = ecmaVm->GetFactory();
74     auto memController = heap->GetMemController();
75 
76     heap->CollectGarbage(TriggerGCType::YOUNG_GC);
77     size_t oldSpaceAllocatedSizeBefore = memController->GetOldSpaceAllocAccumulatedSize();
78     size_t nonMovableSpaceAllocatedSizeBefore = memController->GetNonMovableSpaceAllocAccumulatedSize();
79     double allocDurationBefore = memController->GetAllocTimeMs();
80     sleep(1);
81 
82     // new space object
83     [[maybe_unused]] auto newArray =
84         objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::SEMI_SPACE);
85     // old space object
86     auto oldArray = objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE);
87     // non movable object
88     auto nonMovableArray = objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::NON_MOVABLE);
89     // huge space object
90     static constexpr size_t SIZE = 1_MB;
91     auto hugeArray = objectFactory->NewTaggedArray(SIZE);
92 
93     auto newSpace = heap->GetNewSpace();
94     size_t newSpaceAllocBytesSinceGC = newSpace->GetAllocatedSizeSinceGC(newSpace->GetTop());
95     ASSERT_EQ(newSpaceAllocBytesSinceGC, TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), 2));
96     heap->CollectGarbage(TriggerGCType::YOUNG_GC);
97     newSpace = heap->GetNewSpace();
98     ASSERT_EQ(newSpace->GetAllocatedSizeSinceGC(newSpace->GetTop()), static_cast<size_t>(0));
99 
100     size_t oldSpaceAllocatedSizeAfter = memController->GetOldSpaceAllocAccumulatedSize();
101     size_t nonMovableSpaceAllocatedSizeAfter = memController->GetNonMovableSpaceAllocAccumulatedSize();
102     double allocDurationAfter = memController->GetAllocTimeMs();
103 
104     size_t hugeObjectAllocSizeInLastGC = memController->GetHugeObjectAllocSizeSinceGC();
105 
106     ASSERT_TRUE(allocDurationAfter - allocDurationBefore > 1000);
107     ASSERT_TRUE(oldSpaceAllocatedSizeAfter - oldSpaceAllocatedSizeBefore
108                 == oldArray->ComputeSize(JSTaggedValue::TaggedTypeSize(), 2));
109     ASSERT_TRUE(nonMovableSpaceAllocatedSizeAfter - nonMovableSpaceAllocatedSizeBefore
110                 == nonMovableArray->ComputeSize(JSTaggedValue::TaggedTypeSize(), 2));
111     // The allocated size of huge object must be larger than the object size.
112     ASSERT_TRUE(hugeObjectAllocSizeInLastGC > hugeArray->ComputeSize(JSTaggedValue::TaggedTypeSize(), SIZE));
113 #endif
114 }
115 
HWTEST_F_L0(MemControllerTest,CalculateMarkCompactSpeedPerMSTest)116 HWTEST_F_L0(MemControllerTest, CalculateMarkCompactSpeedPerMSTest)
117 {
118 #ifdef NDEBUG
119     auto ecmaVm = thread->GetEcmaVM();
120     auto heap = const_cast<Heap *>(ecmaVm->GetHeap());
121     auto memController = heap->GetMemController();
122     auto compactSpeed = memController->CalculateMarkCompactSpeedPerMS();
123     EXPECT_TRUE(compactSpeed == 0);
124 #endif
125 }
126 
HWTEST_F_L0(MemControllerTest,StartCalculationBeforeGC)127 HWTEST_F_L0(MemControllerTest, StartCalculationBeforeGC)
128 {
129     JSNApi::InitHybridVMEnv(thread->GetEcmaVM());
130     auto ecmaVm = thread->GetEcmaVM();
131     auto heap = const_cast<Heap *>(ecmaVm->GetHeap());
132     auto memController = heap->GetMemController();
133     auto objectFactory = ecmaVm->GetFactory();
134 
135     // huge space object
136     static constexpr size_t SIZE = 1_MB;
137     objectFactory->NewTaggedArray(SIZE);
138 
139     double allocTimeMsBefore = memController->GetAllocTimeMs();
140     size_t oldSpaceSizeBefore = memController->GetOldSpaceAllocAccumulatedSize();
141     size_t nonMovableSpaceSizeBefore = memController->GetNonMovableSpaceAllocAccumulatedSize();
142     size_t codeSpaceSizeBefore = memController->GetCodeSpaceAllocAccumulatedSize();
143     {
144         [[maybe_unused]] auto newArray =
145             objectFactory->NewTaggedArray(20, JSTaggedValue::Undefined(), MemSpaceType::SEMI_SPACE);
146         // old space object
147         [[maybe_unused]] auto oldArray =
148             objectFactory->NewTaggedArray(20, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE);
149         // non movable object
150         [[maybe_unused]] auto nonMovableArray =
151             objectFactory->NewTaggedArray(20, JSTaggedValue::Undefined(), MemSpaceType::NON_MOVABLE);
152     }
153 
154     sleep(1);
155     heap->CollectGarbage(TriggerGCType::FULL_GC);
156     memController->StartCalculationBeforeGC();
157     memController->CheckLowAllocationUsageState();
158 
159     double allocTimeMsAfter = memController->GetAllocTimeMs();
160     size_t oldSpaceSizeAfter = memController->GetOldSpaceAllocAccumulatedSize();
161     size_t nonMovableSpaceSizeAfter = memController->GetNonMovableSpaceAllocAccumulatedSize();
162     size_t codeSpaceSizeAfter = memController->GetCodeSpaceAllocAccumulatedSize();
163 
164     EXPECT_TRUE(allocTimeMsAfter - allocTimeMsBefore > 1000);
165     EXPECT_TRUE(oldSpaceSizeAfter > oldSpaceSizeBefore);
166     EXPECT_TRUE(nonMovableSpaceSizeAfter > nonMovableSpaceSizeBefore);
167     EXPECT_TRUE(codeSpaceSizeAfter == codeSpaceSizeBefore);
168 }
169 
HWTEST_F_L0(MemControllerTest,StopCalculationAfterGC)170 HWTEST_F_L0(MemControllerTest, StopCalculationAfterGC)
171 {
172     auto ecmaVm = thread->GetEcmaVM();
173     auto heap = const_cast<Heap *>(ecmaVm->GetHeap());
174     auto objectFactory = ecmaVm->GetFactory();
175     auto memController = heap->GetMemController();
176     heap->CollectGarbage(TriggerGCType::FULL_GC);
177 
178     [[maybe_unused]] auto newArray =
179         objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::SEMI_SPACE);
180     [[maybe_unused]] auto oldArray =
181         objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE);
182     [[maybe_unused]] auto nonMovableArray =
183         objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::NON_MOVABLE);
184     static constexpr size_t SIZE = 1_MB;
185     [[maybe_unused]] auto hugeArray = objectFactory->NewTaggedArray(SIZE);
186 
187     heap->CollectGarbage(TriggerGCType::YOUNG_GC);
188 
189     double allocDurationSinceGc = memController->GetAllocDurationSinceGc();
190     size_t codeSpaceAllocSizeSinceGC = memController->GetCodeSpaceAllocAccumulatedSize();
191     EXPECT_EQ(allocDurationSinceGc, static_cast<double>(0.0));
192     EXPECT_EQ(codeSpaceAllocSizeSinceGC, static_cast<size_t>(0));
193     size_t hugeObjectSize = heap->GetHugeObjectSpace()->GetHeapObjectSize();
194     size_t hugeAllocSizeSinceGC = memController->GetHugeObjectAllocSizeSinceGC();
195     EXPECT_EQ(hugeAllocSizeSinceGC, hugeObjectSize);
196     double markCompactSpeed = memController->CalculateMarkCompactSpeedPerMS();
197     EXPECT_GE(markCompactSpeed, 0);
198 }
199 
HWTEST_F_L0(MemControllerTest,MemControllerUtilsTest001)200 HWTEST_F_L0(MemControllerTest, MemControllerUtilsTest001)
201 {
202     base::GCRingBuffer<BytesAndDuration, 10> buffer;
203     BytesAndDuration initial = {1_GB + 1, 1};
204     double timeMs = 1;
205     double result = MemControllerUtils::CalculateAverageSpeed(buffer, initial, timeMs);
206     EXPECT_GE(result, 1_GB);
207 }
208 
HWTEST_F_L0(MemControllerTest,MemControllerUtilsTest002)209 HWTEST_F_L0(MemControllerTest, MemControllerUtilsTest002)
210 {
211     base::GCRingBuffer<BytesAndDuration, 10> buffer;
212     BytesAndDuration initial = {0, 0};
213     double timeMs = 0;
214     double result = MemControllerUtils::CalculateAverageSpeed(buffer, initial, timeMs);
215     EXPECT_GE(result, 0);
216 }
217 
HWTEST_F_L0(MemControllerTest,MemControllerUtilsTest003)218 HWTEST_F_L0(MemControllerTest, MemControllerUtilsTest003)
219 {
220     base::GCRingBuffer<BytesAndDuration, 10> buffer;
221     BytesAndDuration initial = {1, 1_GB + 1};
222     double timeMs = 1;
223     double result = MemControllerUtils::CalculateAverageSpeed(buffer, initial, timeMs);
224     EXPECT_GE(result, 1);
225 }
226 
HWTEST_F_L0(MemControllerTest,MemControllerUtilsTest004)227 HWTEST_F_L0(MemControllerTest, MemControllerUtilsTest004)
228 {
229     base::GCRingBuffer<BytesAndDuration, 10> buffer;
230     BytesAndDuration initial = {1_GB / 2, 1};
231     double timeMs = 1;
232     double result = MemControllerUtils::CalculateAverageSpeed(buffer, initial, timeMs);
233     EXPECT_GE(result, 1_GB / 2);
234 }
235 
HWTEST_F_L0(MemControllerTest,MemControllerUtilsTest005)236 HWTEST_F_L0(MemControllerTest, MemControllerUtilsTest005)
237 {
238     base::GCRingBuffer<BytesAndDuration, 10> buffer;
239     double result = MemControllerUtils::CalculateAverageSpeed(buffer);
240     EXPECT_GE(result, 0);
241 }
242 
243 }  // namespace panda::test
244