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 29using namespace panda::ecmascript; 30using namespace panda::ecmascript::base; 31 32namespace panda::test { 33class MemControllerTest : public BaseTestWithScope<false> { 34}; 35 36HWTEST_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 67HWTEST_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 115HWTEST_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 126HWTEST_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 memController->CheckLowAllocationUsageState(); 140 141 double allocTimeMsAfter = memController->GetAllocTimeMs(); 142 size_t oldSpaceSizeAfter = memController->GetOldSpaceAllocAccumulatedSize(); 143 size_t nonMovableSpaceSizeAfter = memController->GetNonMovableSpaceAllocAccumulatedSize(); 144 size_t codeSpaceSizeAfter = memController->GetCodeSpaceAllocAccumulatedSize(); 145 double allocDurationSinceGc = memController->GetAllocDurationSinceGc(); 146 147 EXPECT_TRUE(allocTimeMsAfter - allocTimeMsBefore > 1000); 148 EXPECT_TRUE(oldSpaceSizeAfter > oldSpaceSizeBefore); 149 EXPECT_TRUE(nonMovableSpaceSizeAfter > nonMovableSpaceSizeBefore); 150 EXPECT_TRUE(codeSpaceSizeAfter == codeSpaceSizeBefore); 151 EXPECT_TRUE(allocDurationSinceGc == allocTimeMsAfter - allocTimeMsBefore); 152} 153 154HWTEST_F_L0(MemControllerTest, StopCalculationAfterGC) 155{ 156 auto ecmaVm = thread->GetEcmaVM(); 157 auto heap = const_cast<Heap *>(ecmaVm->GetHeap()); 158 auto objectFactory = ecmaVm->GetFactory(); 159 auto memController = heap->GetMemController(); 160 heap->CollectGarbage(TriggerGCType::FULL_GC); 161 162 [[maybe_unused]] auto newArray = 163 objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::SEMI_SPACE); 164 [[maybe_unused]] auto oldArray = 165 objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE); 166 [[maybe_unused]] auto nonMovableArray = 167 objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::NON_MOVABLE); 168 static constexpr size_t SIZE = 1_MB; 169 [[maybe_unused]] auto hugeArray = objectFactory->NewTaggedArray(SIZE); 170 171 heap->CollectGarbage(TriggerGCType::YOUNG_GC); 172 173 double allocDurationSinceGc = memController->GetAllocDurationSinceGc(); 174 size_t codeSpaceAllocSizeSinceGC = memController->GetCodeSpaceAllocAccumulatedSize(); 175 EXPECT_EQ(allocDurationSinceGc, static_cast<double>(0.0)); 176 EXPECT_EQ(codeSpaceAllocSizeSinceGC, static_cast<size_t>(0)); 177 size_t hugeObjectSize = heap->GetHugeObjectSpace()->GetHeapObjectSize(); 178 size_t hugeAllocSizeSinceGC = memController->GetHugeObjectAllocSizeSinceGC(); 179 EXPECT_EQ(hugeAllocSizeSinceGC, hugeObjectSize); 180 double markCompactSpeed = memController->CalculateMarkCompactSpeedPerMS(); 181 EXPECT_GE(markCompactSpeed, 0); 182} 183} // namespace panda::test 184