• 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/builtins/builtins_ark_tools.h"
17 #include "ecmascript/ecma_vm.h"
18 #include "ecmascript/mem/full_gc.h"
19 #include "ecmascript/object_factory-inl.h"
20 #include "ecmascript/mem/concurrent_marker.h"
21 #include "ecmascript/mem/stw_young_gc.h"
22 #include "ecmascript/mem/partial_gc.h"
23 #include "ecmascript/tests/ecma_test_common.h"
24 
25 using namespace panda;
26 
27 using namespace panda::ecmascript;
28 
29 namespace panda::test {
30 class GCTest : public BaseTestWithScope<false> {
31 public:
SetUp()32     void SetUp() override
33     {
34         JSRuntimeOptions options;
35         options.SetEnableEdenGC(true);
36         instance = JSNApi::CreateEcmaVM(options);
37         ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
38         thread = instance->GetJSThread();
39         thread->ManagedCodeBegin();
40         scope = new EcmaHandleScope(thread);
41         auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
42         heap->GetConcurrentMarker()->EnableConcurrentMarking(EnableConcurrentMarkType::ENABLE);
43         heap->GetSweeper()->EnableConcurrentSweep(EnableConcurrentSweepType::ENABLE);
44     }
45 };
46 
HWTEST_F_L0(GCTest,ArkToolsHintGC)47 HWTEST_F_L0(GCTest, ArkToolsHintGC)
48 {
49     Heap *heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
50     heap->GetConcurrentMarker()->EnableConcurrentMarking(EnableConcurrentMarkType::CONFIG_DISABLE);
51     auto getSizeAfterCreateAndCallHintGC = [this, heap] (size_t &newSize, size_t &finalSize) -> bool {
52         {
53             [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread);
54             for (int i = 0; i < 500; i++) {
55                 [[maybe_unused]] JSHandle<TaggedArray> obj = thread->GetEcmaVM()->GetFactory()->
56                     NewTaggedArray(10 * 1024, JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE);
57             }
58             newSize = heap->GetCommittedSize();
59         }
60 
61         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 0);
62         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
63         JSTaggedValue result = builtins::BuiltinsArkTools::HintGC(ecmaRuntimeCallInfo);
64         finalSize = heap->GetCommittedSize();
65         TestHelper::TearDownFrame(thread, prev);
66 
67         return result.ToBoolean();
68     };
69     {
70         // Test HintGC() when sensitive.
71         heap->CollectGarbage(TriggerGCType::FULL_GC);
72         heap->NotifyHighSensitive(true);
73         size_t originSize = heap->GetCommittedSize();
74         size_t newSize = 0;
75         size_t finalSize = 0;
76         bool res = getSizeAfterCreateAndCallHintGC(newSize, finalSize);
77         EXPECT_FALSE(res);
78         EXPECT_TRUE(newSize > originSize);
79         EXPECT_TRUE(finalSize == newSize);
80         heap->NotifyHighSensitive(false);
81     }
82     {
83         // Test HintGC() when in background.
84         heap->CollectGarbage(TriggerGCType::FULL_GC);
85         heap->ChangeGCParams(true);
86         size_t originSize = heap->GetCommittedSize();
87         size_t newSize = 0;
88         size_t finalSize = 0;
89         bool res = getSizeAfterCreateAndCallHintGC(newSize, finalSize);
90         EXPECT_TRUE(res);
91         EXPECT_TRUE(newSize > originSize);
92         EXPECT_TRUE(finalSize < newSize);
93         heap->ChangeGCParams(false);
94     }
95 }
96 
HWTEST_F_L0(GCTest,LargeOverShootSizeTest)97 HWTEST_F_L0(GCTest, LargeOverShootSizeTest)
98 {
99     auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
100     size_t originalYoungSize = heap->GetNewSpace()->GetCommittedSize();
101 
102     EXPECT_FALSE(heap->GetNewSpace()->CommittedSizeIsLarge());
103     heap->GetConcurrentMarker()->ConfigConcurrentMark(false);
104     heap->NotifyHighSensitive(true);
105     {
106         [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread);
107         for (int i = 0; i < 500; i++) {
108             [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(
109                 10 * 1024, JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE);
110         }
111     }
112     size_t newYoungSize = heap->GetNewSpace()->GetCommittedSize();
113     size_t originalOverShootSize = heap->GetNewSpace()->GetOvershootSize();
114     EXPECT_TRUE(heap->GetNewSpace()->CommittedSizeIsLarge());
115     EXPECT_TRUE(originalYoungSize < newYoungSize);
116 
117     heap->NotifyHighSensitive(false);
118     heap->CollectGarbage(TriggerGCType::YOUNG_GC);
119     newYoungSize = heap->GetNewSpace()->GetCommittedSize();
120     size_t newOverShootSize = heap->GetNewSpace()->GetOvershootSize();
121 
122     EXPECT_TRUE(originalYoungSize < newYoungSize);
123     EXPECT_TRUE(originalOverShootSize < newOverShootSize);
124     EXPECT_TRUE(0 < newOverShootSize);
125     {
126         [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread);
127         for (int i = 0; i < 2049; i++) {
128             [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(
129                 1024, JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE);
130         }
131     }
132     size_t newSize = heap->GetNewSpace()->GetCommittedSize();
133     EXPECT_TRUE(originalYoungSize <= newSize);
134 }
135 } // namespace panda::test
136