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(
68 *factory->NewFromASCII("test1"), *reinterpret_cast<EcmaString **>(globalString)), 0);
69 }
70
HWTEST_F_L0(JSHandleTest,NewGlobalHandle1)71 HWTEST_F_L0(JSHandleTest, NewGlobalHandle1)
72 {
73 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
74
75 uintptr_t globalString[600] = {0};
76 {
77 [[maybe_unused]] EcmaHandleScope scope(thread);
78 for (int i = 0; i < 600; i++) {
79 std::string test = "test" + std::to_string(i);
80 auto string1 = factory->NewFromUtf8(test.c_str());
81 globalString[i] = thread->NewGlobalHandle(string1.GetTaggedType());
82 }
83 }
84 // trigger GC
85 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
86 for (int i = 300; i > 200; i--) {
87 thread->DisposeGlobalHandle(globalString[i]);
88 }
89 // check result
90 for (int i = 0; i <= 200; i++) {
91 std::string test = "test" + std::to_string(i);
92 EXPECT_EQ(EcmaStringAccessor::Compare(
93 *factory->NewFromUtf8(test.c_str()), *reinterpret_cast<EcmaString **>(globalString[i])), 0);
94 }
95 // trigger GC
96 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
97 for (int i = 301; i < 600; i++) {
98 std::string test = "test" + std::to_string(i);
99 EXPECT_EQ(EcmaStringAccessor::Compare(
100 *factory->NewFromUtf8(test.c_str()), *reinterpret_cast<EcmaString **>(globalString[i])), 0);
101 }
102 }
103
HWTEST_F_L0(JSHandleTest,DisposeGlobalHandle)104 HWTEST_F_L0(JSHandleTest, DisposeGlobalHandle)
105 {
106 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
107
108 uintptr_t globalString[600] = {0};
109 {
110 [[maybe_unused]] EcmaHandleScope scope(thread);
111 for (int i = 0; i < 600; i++) {
112 std::string test = "test" + std::to_string(i);
113 auto string1 = factory->NewFromUtf8(test.c_str());
114 globalString[i] = thread->NewGlobalHandle(string1.GetTaggedType());
115 }
116 }
117 for (int i = 512; i > 200; i--) {
118 thread->DisposeGlobalHandle(globalString[i]);
119 }
120 }
121
HWTEST_F_L0(JSHandleTest,DisposeAndNewGlobalHandle)122 HWTEST_F_L0(JSHandleTest, DisposeAndNewGlobalHandle)
123 {
124 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
125
126 uintptr_t globalString[768] = {0};
127 {
128 [[maybe_unused]] EcmaHandleScope scope(thread);
129 for (int i = 0; i < 768; i++) {
130 std::string test = "test" + std::to_string(i);
131 auto string1 = factory->NewFromUtf8(test.c_str());
132 globalString[i] = thread->NewGlobalHandle(string1.GetTaggedType());
133 }
134 }
135 for (int i = 767; i > 200; i--) {
136 thread->DisposeGlobalHandle(globalString[i]);
137 }
138 // trigger GC
139 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
140 {
141 [[maybe_unused]] EcmaHandleScope scope(thread);
142 for (int i = 200; i < 400; i++) {
143 std::string test = "test" + std::to_string(i);
144 auto string1 = factory->NewFromUtf8(test.c_str());
145 globalString[i] = thread->NewGlobalHandle(string1.GetTaggedType());
146 }
147 }
148 // check result
149 for (int i = 0; i <= 300; i++) {
150 std::string test = "test" + std::to_string(i);
151 EXPECT_EQ(EcmaStringAccessor::Compare(
152 *factory->NewFromUtf8(test.c_str()), *reinterpret_cast<EcmaString **>(globalString[i])), 0);
153 }
154 }
155
HWTEST_F_L0(JSHandleTest,NewWeakGlobalHandle)156 HWTEST_F_L0(JSHandleTest, NewWeakGlobalHandle)
157 {
158 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
159
160 uintptr_t globalString = 0;
161 {
162 [[maybe_unused]] EcmaHandleScope scope(thread);
163 auto string1 = factory->NewFromASCII("test1");
164 globalString = thread->NewGlobalHandle(string1.GetTaggedType());
165 globalString = thread->SetWeak(globalString);
166
167 // trigger GC
168 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
169
170 // check result
171 EXPECT_EQ(EcmaStringAccessor::Compare(
172 *factory->NewFromASCII("test1"), *reinterpret_cast<EcmaString **>(globalString)), 0);
173 EXPECT_TRUE(thread->IsWeak(globalString));
174 }
175 // trigger GC
176 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
177
178 // check weak reference
179 JSTaggedType result = *reinterpret_cast<JSTaggedType *>(globalString);
180 EXPECT_EQ(result, JSTaggedValue::Undefined().GetRawData());
181 }
182
HWTEST_F_L0(JSHandleTest,NewWeakGlobalHandle1)183 HWTEST_F_L0(JSHandleTest, NewWeakGlobalHandle1)
184 {
185 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
186
187 uintptr_t globalString[800] = {0};
188 {
189 [[maybe_unused]] EcmaHandleScope scope(thread);
190 for (int i = 0; i < 800; i++) {
191 std::string test = "test" + std::to_string(i);
192 auto string1 = factory->NewFromUtf8(test.c_str());
193 globalString[i] = thread->NewGlobalHandle(string1.GetTaggedType());
194 globalString[i] = thread->SetWeak(globalString[i]);
195 EXPECT_TRUE(thread->IsWeak(globalString[i]));
196 }
197 for (int i = 600; i > 200; i--) {
198 thread->DisposeGlobalHandle(globalString[i]);
199 }
200 // trigger GC
201 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
202 // check result
203 for (int i = 0; i <= 200; i++) {
204 std::string test = "test" + std::to_string(i);
205 EXPECT_EQ(EcmaStringAccessor::Compare(
206 *factory->NewFromUtf8(test.c_str()), *reinterpret_cast<EcmaString **>(globalString[i])), 0);
207 }
208 }
209 // trigger GC
210 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
211 for (int i = 601; i < 800; i++) {
212 EXPECT_EQ(*reinterpret_cast<JSTaggedType *>(globalString[i]), JSTaggedValue::Undefined().GetRawData());
213 }
214 }
215 } // namespace panda::test
216