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-inl.h"
17 #include "ecmascript/ecma_global_storage.h"
18 #include "ecmascript/ecma_vm.h"
19 #include "ecmascript/js_handle.h"
20 #include "ecmascript/object_factory.h"
21 #include "ecmascript/tests/test_helper.h"
22
23 using namespace panda::ecmascript;
24
25 namespace panda::test {
26 class JSHandleTest : public testing::Test {
27 public:
SetUpTestCase()28 static void SetUpTestCase()
29 {
30 GTEST_LOG_(INFO) << "SetUpTestCase";
31 }
32
TearDownTestCase()33 static void TearDownTestCase()
34 {
35 GTEST_LOG_(INFO) << "TearDownCase";
36 }
37
SetUp()38 void SetUp() override
39 {
40 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
41 }
42
TearDown()43 void TearDown() override
44 {
45 TestHelper::DestroyEcmaVMWithScope(instance, scope);
46 }
47
48 EcmaVM *instance {nullptr};
49 ecmascript::EcmaHandleScope *scope {nullptr};
50 JSThread *thread {nullptr};
51 };
52
HWTEST_F_L0(JSHandleTest,NewGlobalHandle)53 HWTEST_F_L0(JSHandleTest, NewGlobalHandle)
54 {
55 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
56
57 uintptr_t globalString = 0;
58 {
59 [[maybe_unused]] EcmaHandleScope scope(thread);
60 auto string1 = factory->NewFromASCII("test1");
61 globalString = thread->NewGlobalHandle(string1.GetTaggedType());
62 }
63 // trigger GC
64 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
65
66 // check result
67 EXPECT_EQ(EcmaStringAccessor::Compare(instance,
68 factory->NewFromASCII("test1"),
69 JSHandle<EcmaString>(thread, *reinterpret_cast<EcmaString **>(globalString))),
70 0);
71 }
72
HWTEST_F_L0(JSHandleTest,NewGlobalHandle1)73 HWTEST_F_L0(JSHandleTest, NewGlobalHandle1)
74 {
75 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
76
77 uintptr_t globalString[600] = {0};
78 {
79 [[maybe_unused]] EcmaHandleScope scope(thread);
80 for (int i = 0; i < 600; i++) {
81 std::string test = "test" + std::to_string(i);
82 auto string1 = factory->NewFromUtf8(test.c_str());
83 globalString[i] = thread->NewGlobalHandle(string1.GetTaggedType());
84 }
85 }
86 // trigger GC
87 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
88 for (int i = 300; i > 200; i--) {
89 thread->DisposeGlobalHandle(globalString[i]);
90 }
91 // check result
92 for (int i = 0; i <= 200; i++) {
93 std::string test = "test" + std::to_string(i);
94 EXPECT_EQ(EcmaStringAccessor::Compare(instance,
95 factory->NewFromUtf8(test.c_str()),
96 JSHandle<EcmaString>(thread, *reinterpret_cast<EcmaString **>(globalString[i]))),
97 0);
98 }
99 // trigger GC
100 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
101 for (int i = 301; i < 600; i++) {
102 std::string test = "test" + std::to_string(i);
103 EXPECT_EQ(EcmaStringAccessor::Compare(instance,
104 factory->NewFromUtf8(test.c_str()),
105 JSHandle<EcmaString>(thread, *reinterpret_cast<EcmaString **>(globalString[i]))),
106 0);
107 }
108 }
109
HWTEST_F_L0(JSHandleTest,DisposeGlobalHandle)110 HWTEST_F_L0(JSHandleTest, DisposeGlobalHandle)
111 {
112 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
113
114 uintptr_t globalString[600] = {0};
115 {
116 [[maybe_unused]] EcmaHandleScope scope(thread);
117 for (int i = 0; i < 600; i++) {
118 std::string test = "test" + std::to_string(i);
119 auto string1 = factory->NewFromUtf8(test.c_str());
120 globalString[i] = thread->NewGlobalHandle(string1.GetTaggedType());
121 }
122 }
123 for (int i = 512; i > 200; i--) {
124 thread->DisposeGlobalHandle(globalString[i]);
125 }
126 }
127
HWTEST_F_L0(JSHandleTest,DisposeAndNewGlobalHandle)128 HWTEST_F_L0(JSHandleTest, DisposeAndNewGlobalHandle)
129 {
130 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
131
132 uintptr_t globalString[768] = {0};
133 {
134 [[maybe_unused]] EcmaHandleScope scope(thread);
135 for (int i = 0; i < 768; i++) {
136 std::string test = "test" + std::to_string(i);
137 auto string1 = factory->NewFromUtf8(test.c_str());
138 globalString[i] = thread->NewGlobalHandle(string1.GetTaggedType());
139 }
140 }
141 for (int i = 767; i > 200; i--) {
142 thread->DisposeGlobalHandle(globalString[i]);
143 }
144 // trigger GC
145 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
146 {
147 [[maybe_unused]] EcmaHandleScope scope(thread);
148 for (int i = 200; i < 400; i++) {
149 std::string test = "test" + std::to_string(i);
150 auto string1 = factory->NewFromUtf8(test.c_str());
151 globalString[i] = thread->NewGlobalHandle(string1.GetTaggedType());
152 }
153 }
154 // check result
155 for (int i = 0; i <= 300; i++) {
156 std::string test = "test" + std::to_string(i);
157 EXPECT_EQ(EcmaStringAccessor::Compare(instance,
158 factory->NewFromUtf8(test.c_str()),
159 JSHandle<EcmaString>(thread, *reinterpret_cast<EcmaString **>(globalString[i]))),
160 0);
161 }
162 }
163
HWTEST_F_L0(JSHandleTest,NewWeakGlobalHandle)164 HWTEST_F_L0(JSHandleTest, NewWeakGlobalHandle)
165 {
166 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
167
168 uintptr_t globalString = 0;
169 {
170 [[maybe_unused]] EcmaHandleScope scope(thread);
171 auto string1 = factory->NewFromASCII("test1");
172 globalString = thread->NewGlobalHandle(string1.GetTaggedType());
173 globalString = thread->SetWeak(globalString);
174
175 // trigger GC
176 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
177
178 // check result
179 EXPECT_EQ(EcmaStringAccessor::Compare(instance,
180 factory->NewFromASCII("test1"),
181 JSHandle<EcmaString>(thread, *reinterpret_cast<EcmaString **>(globalString))),
182 0);
183 EXPECT_TRUE(thread->IsWeak(globalString));
184 }
185 // trigger GC
186 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
187
188 // check weak reference
189 JSTaggedType result = *reinterpret_cast<JSTaggedType *>(globalString);
190 EXPECT_EQ(result, JSTaggedValue::Undefined().GetRawData());
191 }
192
HWTEST_F_L0(JSHandleTest,NewWeakGlobalHandle1)193 HWTEST_F_L0(JSHandleTest, NewWeakGlobalHandle1)
194 {
195 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
196
197 uintptr_t globalString[800] = {0};
198 {
199 [[maybe_unused]] EcmaHandleScope scope(thread);
200 for (int i = 0; i < 800; i++) {
201 std::string test = "test" + std::to_string(i);
202 auto string1 = factory->NewFromUtf8(test.c_str());
203 globalString[i] = thread->NewGlobalHandle(string1.GetTaggedType());
204 globalString[i] = thread->SetWeak(globalString[i]);
205 EXPECT_TRUE(thread->IsWeak(globalString[i]));
206 }
207 for (int i = 600; i > 200; i--) {
208 thread->DisposeGlobalHandle(globalString[i]);
209 }
210 // trigger GC
211 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
212 // check result
213 for (int i = 0; i <= 200; i++) {
214 std::string test = "test" + std::to_string(i);
215 EXPECT_EQ(EcmaStringAccessor::Compare(instance,
216 factory->NewFromUtf8(test.c_str()),
217 JSHandle<EcmaString>(thread, *reinterpret_cast<EcmaString **>(globalString[i]))),
218 0);
219 }
220 }
221 // trigger GC
222 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
223 }
224 } // namespace panda::test
225