• 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     auto ecmaVm = thread->GetEcmaVM();
130     auto heap = const_cast<Heap *>(ecmaVm->GetHeap());
131     auto memController = heap->GetMemController();
132 
133     double allocTimeMsBefore = memController->GetAllocTimeMs();
134     size_t oldSpaceSizeBefore = memController->GetOldSpaceAllocAccumulatedSize();
135     size_t nonMovableSpaceSizeBefore = memController->GetNonMovableSpaceAllocAccumulatedSize();
136     size_t codeSpaceSizeBefore = memController->GetCodeSpaceAllocAccumulatedSize();
137 
138     sleep(1);
139     memController->StartCalculationBeforeGC();
140     memController->CheckLowAllocationUsageState();
141 
142     double allocTimeMsAfter = memController->GetAllocTimeMs();
143     size_t oldSpaceSizeAfter = memController->GetOldSpaceAllocAccumulatedSize();
144     size_t nonMovableSpaceSizeAfter = memController->GetNonMovableSpaceAllocAccumulatedSize();
145     size_t codeSpaceSizeAfter = memController->GetCodeSpaceAllocAccumulatedSize();
146     double allocDurationSinceGc = memController->GetAllocDurationSinceGc();
147 
148     EXPECT_TRUE(allocTimeMsAfter - allocTimeMsBefore > 1000);
149     EXPECT_TRUE(oldSpaceSizeAfter > oldSpaceSizeBefore);
150     EXPECT_TRUE(nonMovableSpaceSizeAfter > nonMovableSpaceSizeBefore);
151     EXPECT_TRUE(codeSpaceSizeAfter == codeSpaceSizeBefore);
152     EXPECT_TRUE(allocDurationSinceGc == allocTimeMsAfter - allocTimeMsBefore);
153 }
154 
HWTEST_F_L0(MemControllerTest,StopCalculationAfterGC)155 HWTEST_F_L0(MemControllerTest, StopCalculationAfterGC)
156 {
157     auto ecmaVm = thread->GetEcmaVM();
158     auto heap = const_cast<Heap *>(ecmaVm->GetHeap());
159     auto objectFactory = ecmaVm->GetFactory();
160     auto memController = heap->GetMemController();
161     heap->CollectGarbage(TriggerGCType::FULL_GC);
162 
163     [[maybe_unused]] auto newArray =
164         objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::SEMI_SPACE);
165     [[maybe_unused]] auto oldArray =
166         objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE);
167     [[maybe_unused]] auto nonMovableArray =
168         objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::NON_MOVABLE);
169     static constexpr size_t SIZE = 1_MB;
170     [[maybe_unused]] auto hugeArray = objectFactory->NewTaggedArray(SIZE);
171 
172     heap->CollectGarbage(TriggerGCType::YOUNG_GC);
173 
174     double allocDurationSinceGc = memController->GetAllocDurationSinceGc();
175     size_t codeSpaceAllocSizeSinceGC = memController->GetCodeSpaceAllocAccumulatedSize();
176     EXPECT_EQ(allocDurationSinceGc, static_cast<double>(0.0));
177     EXPECT_EQ(codeSpaceAllocSizeSinceGC, static_cast<size_t>(0));
178     size_t hugeObjectSize = heap->GetHugeObjectSpace()->GetHeapObjectSize();
179     size_t hugeAllocSizeSinceGC = memController->GetHugeObjectAllocSizeSinceGC();
180     EXPECT_EQ(hugeAllocSizeSinceGC, hugeObjectSize);
181     double markCompactSpeed = memController->CalculateMarkCompactSpeedPerMS();
182     EXPECT_GE(markCompactSpeed, 0);
183 }
184 
HWTEST_F_L0(MemControllerTest,MemControllerUtilsTest001)185 HWTEST_F_L0(MemControllerTest, MemControllerUtilsTest001)
186 {
187     base::GCRingBuffer<BytesAndDuration, 10> buffer;
188     BytesAndDuration initial = {1_GB + 1, 1};
189     double timeMs = 1;
190     double result = MemControllerUtils::CalculateAverageSpeed(buffer, initial, timeMs);
191     EXPECT_GE(result, 1_GB);
192 }
193 
HWTEST_F_L0(MemControllerTest,MemControllerUtilsTest002)194 HWTEST_F_L0(MemControllerTest, MemControllerUtilsTest002)
195 {
196     base::GCRingBuffer<BytesAndDuration, 10> buffer;
197     BytesAndDuration initial = {0, 0};
198     double timeMs = 0;
199     double result = MemControllerUtils::CalculateAverageSpeed(buffer, initial, timeMs);
200     EXPECT_GE(result, 0);
201 }
202 
HWTEST_F_L0(MemControllerTest,MemControllerUtilsTest003)203 HWTEST_F_L0(MemControllerTest, MemControllerUtilsTest003)
204 {
205     base::GCRingBuffer<BytesAndDuration, 10> buffer;
206     BytesAndDuration initial = {1, 1_GB + 1};
207     double timeMs = 1;
208     double result = MemControllerUtils::CalculateAverageSpeed(buffer, initial, timeMs);
209     EXPECT_GE(result, 1);
210 }
211 
HWTEST_F_L0(MemControllerTest,MemControllerUtilsTest004)212 HWTEST_F_L0(MemControllerTest, MemControllerUtilsTest004)
213 {
214     base::GCRingBuffer<BytesAndDuration, 10> buffer;
215     BytesAndDuration initial = {1_GB / 2, 1};
216     double timeMs = 1;
217     double result = MemControllerUtils::CalculateAverageSpeed(buffer, initial, timeMs);
218     EXPECT_GE(result, 1_GB / 2);
219 }
220 
HWTEST_F_L0(MemControllerTest,MemControllerUtilsTest005)221 HWTEST_F_L0(MemControllerTest, MemControllerUtilsTest005)
222 {
223     base::GCRingBuffer<BytesAndDuration, 10> buffer;
224     double result = MemControllerUtils::CalculateAverageSpeed(buffer);
225     EXPECT_GE(result, 0);
226 }
227 
228 }  // namespace panda::test
229