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 BaseTestWithScope<false> {
27 };
28
HWTEST_F_L0(JSHandleTest,NewGlobalHandle)29 HWTEST_F_L0(JSHandleTest, NewGlobalHandle)
30 {
31 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
32
33 uintptr_t globalString = 0;
34 {
35 [[maybe_unused]] EcmaHandleScope scope(thread);
36 auto string1 = factory->NewFromASCII("test1");
37 globalString = thread->NewGlobalHandle(string1.GetTaggedType());
38 }
39 // trigger GC
40 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
41
42 // check result
43 EXPECT_EQ(EcmaStringAccessor::Compare(instance,
44 factory->NewFromASCII("test1"),
45 JSHandle<EcmaString>(thread, *reinterpret_cast<EcmaString **>(globalString))),
46 0);
47 }
48
GlobalHandleCommon(JSThread * thread,uintptr_t * globalString,uint32_t nums)49 static void GlobalHandleCommon(JSThread *thread, uintptr_t* globalString, uint32_t nums)
50 {
51 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
52 [[maybe_unused]] EcmaHandleScope scope(thread);
53 for (uint32_t i = 0; i < nums; i++) {
54 std::string test = "test" + std::to_string(i);
55 auto string1 = factory->NewFromUtf8(test.c_str());
56 globalString[i] = thread->NewGlobalHandle(string1.GetTaggedType());
57 }
58 }
59
HWTEST_F_L0(JSHandleTest,NewGlobalHandle1)60 HWTEST_F_L0(JSHandleTest, NewGlobalHandle1)
61 {
62 uintptr_t globalString[600] = {0};
63 GlobalHandleCommon(thread, globalString, sizeof(globalString)/sizeof(uintptr_t));
64 // trigger GC
65 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
66 for (int i = 300; i > 200; i--) {
67 thread->DisposeGlobalHandle(globalString[i]);
68 }
69 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
70 // check result
71 for (int i = 0; i <= 200; i++) {
72 std::string test = "test" + std::to_string(i);
73 EXPECT_EQ(EcmaStringAccessor::Compare(instance,
74 factory->NewFromUtf8(test.c_str()),
75 JSHandle<EcmaString>(thread, *reinterpret_cast<EcmaString **>(globalString[i]))),
76 0);
77 }
78 // trigger GC
79 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
80 for (int i = 301; i < 600; i++) {
81 std::string test = "test" + std::to_string(i);
82 EXPECT_EQ(EcmaStringAccessor::Compare(instance,
83 factory->NewFromUtf8(test.c_str()),
84 JSHandle<EcmaString>(thread, *reinterpret_cast<EcmaString **>(globalString[i]))),
85 0);
86 }
87 }
88
HWTEST_F_L0(JSHandleTest,DisposeGlobalHandle)89 HWTEST_F_L0(JSHandleTest, DisposeGlobalHandle)
90 {
91 uintptr_t globalString[600] = {0};
92 GlobalHandleCommon(thread, globalString, sizeof(globalString)/sizeof(uintptr_t));
93 for (int i = 512; i > 200; i--) {
94 thread->DisposeGlobalHandle(globalString[i]);
95 }
96 }
97
HWTEST_F_L0(JSHandleTest,DisposeAndNewGlobalHandle)98 HWTEST_F_L0(JSHandleTest, DisposeAndNewGlobalHandle)
99 {
100 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
101
102 uintptr_t globalString[768] = {0};
103 {
104 [[maybe_unused]] EcmaHandleScope scope(thread);
105 for (int i = 0; i < 768; i++) {
106 std::string test = "test" + std::to_string(i);
107 auto string1 = factory->NewFromUtf8(test.c_str());
108 globalString[i] = thread->NewGlobalHandle(string1.GetTaggedType());
109 }
110 }
111 for (int i = 767; i > 200; i--) {
112 thread->DisposeGlobalHandle(globalString[i]);
113 }
114 // trigger GC
115 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
116 {
117 [[maybe_unused]] EcmaHandleScope scope(thread);
118 for (int i = 200; i < 400; i++) {
119 std::string test = "test" + std::to_string(i);
120 auto string1 = factory->NewFromUtf8(test.c_str());
121 globalString[i] = thread->NewGlobalHandle(string1.GetTaggedType());
122 }
123 }
124 // check result
125 for (int i = 0; i <= 300; i++) {
126 std::string test = "test" + std::to_string(i);
127 EXPECT_EQ(EcmaStringAccessor::Compare(instance,
128 factory->NewFromUtf8(test.c_str()),
129 JSHandle<EcmaString>(thread, *reinterpret_cast<EcmaString **>(globalString[i]))),
130 0);
131 }
132 }
133
HWTEST_F_L0(JSHandleTest,NewWeakGlobalHandle)134 HWTEST_F_L0(JSHandleTest, NewWeakGlobalHandle)
135 {
136 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
137
138 uintptr_t globalString = 0;
139 {
140 [[maybe_unused]] EcmaHandleScope scope(thread);
141 auto string1 = factory->NewFromASCII("test1");
142 globalString = thread->NewGlobalHandle(string1.GetTaggedType());
143 globalString = thread->SetWeak(globalString);
144
145 // trigger GC
146 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
147
148 // check result
149 EXPECT_EQ(EcmaStringAccessor::Compare(instance,
150 factory->NewFromASCII("test1"),
151 JSHandle<EcmaString>(thread, *reinterpret_cast<EcmaString **>(globalString))),
152 0);
153 EXPECT_TRUE(thread->IsWeak(globalString));
154 }
155 // trigger GC
156 SharedHeap::GetInstance()->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::OTHER>(instance->GetJSThread());
157 SharedHeap::GetInstance()->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::OTHER>(instance->GetJSThread());
158
159 // check weak reference
160 JSTaggedType result = *reinterpret_cast<JSTaggedType *>(globalString);
161 EXPECT_EQ(result, JSTaggedValue::Undefined().GetRawData());
162 }
163
HWTEST_F_L0(JSHandleTest,NewWeakGlobalHandle1)164 HWTEST_F_L0(JSHandleTest, NewWeakGlobalHandle1)
165 {
166 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
167
168 uintptr_t globalString[800] = {0};
169 {
170 [[maybe_unused]] EcmaHandleScope scope(thread);
171 for (int i = 0; i < 800; i++) {
172 std::string test = "test" + std::to_string(i);
173 auto string1 = factory->NewFromUtf8(test.c_str());
174 globalString[i] = thread->NewGlobalHandle(string1.GetTaggedType());
175 globalString[i] = thread->SetWeak(globalString[i]);
176 EXPECT_TRUE(thread->IsWeak(globalString[i]));
177 }
178 for (int i = 600; i > 200; i--) {
179 thread->DisposeGlobalHandle(globalString[i]);
180 }
181 // trigger GC
182 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
183 // check result
184 for (int i = 0; i <= 200; i++) {
185 std::string test = "test" + std::to_string(i);
186 EXPECT_EQ(EcmaStringAccessor::Compare(instance,
187 factory->NewFromUtf8(test.c_str()),
188 JSHandle<EcmaString>(thread, *reinterpret_cast<EcmaString **>(globalString[i]))),
189 0);
190 }
191 }
192 // trigger GC
193 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
194 }
195 } // namespace panda::test
196