• 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_vm.h"
17 #include "ecmascript/global_env.h"
18 #include "ecmascript/js_handle.h"
19 #include "ecmascript/mem/mem_common.h"
20 #include "ecmascript/mem/space.h"
21 #include "ecmascript/mem/verification.h"
22 #include "ecmascript/object_factory.h"
23 #include "ecmascript/tagged_array-inl.h"
24 #include "ecmascript/tests/test_helper.h"
25 
26 using namespace panda::ecmascript;
27 
28 namespace panda::test {
29 class HugeObjectTest : public testing::Test {
30 public:
SetUpTestCase()31     static void SetUpTestCase()
32     {
33         GTEST_LOG_(INFO) << "SetUpTestCase";
34     }
35 
TearDownTestCase()36     static void TearDownTestCase()
37     {
38         GTEST_LOG_(INFO) << "TearDownCase";
39     }
40 
SetUp()41     void SetUp() override
42     {
43         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
44         thread->GetEcmaVM()->SetEnableForceGC(false);
45         const_cast<Heap *>(thread->GetEcmaVM()->GetHeap())->SetMarkType(MarkType::MARK_FULL);
46     }
47 
TearDown()48     void TearDown() override
49     {
50         TestHelper::DestroyEcmaVMWithScope(instance, scope);
51     }
52 
53     JSThread *thread {nullptr};
54     EcmaVM *instance {nullptr};
55     ecmascript::EcmaHandleScope *scope {nullptr};
56 };
57 
JSObjectTestCreate(JSThread * thread)58 static JSObject *JSObjectTestCreate(JSThread *thread)
59 {
60     [[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
61     EcmaVM *ecmaVM = thread->GetEcmaVM();
62     auto globalEnv = ecmaVM->GetGlobalEnv();
63     JSHandle<JSTaggedValue> jsFunc = globalEnv->GetObjectFunction();
64     JSHandle<JSObject> newObj =
65         ecmaVM->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(jsFunc), jsFunc);
66     return *newObj;
67 }
68 
LargeArrayTestCreate(JSThread * thread)69 static TaggedArray *LargeArrayTestCreate(JSThread *thread)
70 {
71     [[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
72     static constexpr size_t SIZE = 1_MB;
73     JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(SIZE);
74     return *array;
75 }
76 
77 
HWTEST_F_L0(HugeObjectTest,LargeArrayKeep)78 HWTEST_F_L0(HugeObjectTest, LargeArrayKeep)
79 {
80     TaggedArray *array = LargeArrayTestCreate(thread);
81     EXPECT_TRUE(array != nullptr);
82     JSHandle<TaggedArray> arrayHandle(thread, array);
83     JSHandle<JSObject> newObj(thread, JSObjectTestCreate(thread));
84     arrayHandle->Set(thread, 0, newObj.GetTaggedValue());
85     auto ecmaVm = thread->GetEcmaVM();
86     EXPECT_EQ(*arrayHandle, reinterpret_cast<TaggedObject *>(array));
87     ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);   // Trigger GC.
88     ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);  // Trigger GC.
89     EXPECT_EQ(*newObj, array->Get(0).GetTaggedObject());
90     EXPECT_EQ(*arrayHandle, reinterpret_cast<TaggedObject *>(array));
91 }
92 
HWTEST_F_L0(HugeObjectTest,MultipleArrays)93 HWTEST_F_L0(HugeObjectTest, MultipleArrays)
94 {
95     auto ecmaVm = thread->GetEcmaVM();
96     auto heap = ecmaVm->GetHeap();
97     {
98         [[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
99         for (int i = 0; i <= 14; i++) {
100             JSHandle<TaggedArray> array1(thread, LargeArrayTestCreate(thread));
101         }
102     }
103 
104     {
105         [[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
106         for (int i = 0; i <= 14; i++) {
107             JSHandle<TaggedArray> array2(thread, LargeArrayTestCreate(thread));
108         }
109     }
110 
111     {
112         [[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
113         for (int i = 0; i <= 14; i++) {
114             JSHandle<TaggedArray> array2(thread, LargeArrayTestCreate(thread));
115         }
116     }
117     size_t failCount = 0;
118     VerifyObjectVisitor objVerifier(heap, &failCount);
119     heap->GetHugeObjectSpace()->IterateOverObjects(objVerifier);  // newspace reference the old space
120     EXPECT_EQ(failCount, 0U);
121 }
122 }  // namespace panda::test
123