• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 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_global_storage.h"
17 #include "ecmascript/ecma_vm.h"
18 #include "ecmascript/js_array.h"
19 #include "ecmascript/js_handle.h"
20 #include "ecmascript/js_tagged_value.h"
21 #include "ecmascript/js_thread.h"
22 
23 #include "ecmascript/object_factory.h"
24 #include "ecmascript/tests/test_helper.h"
25 
26 using namespace panda::ecmascript;
27 constexpr int32_t INT_VALUE_0 = 0;
28 constexpr int32_t INT_VALUE_1 = 1;
29 constexpr int32_t INT_VALUE_2 = 2;
30 
31 namespace panda::test {
32 class EcmaGlobalStorageTest : public BaseTestWithScope<false> {
33 public:
CalculateGlobalNodeCount(uint64_t & allGlobalNodeCount,uint64_t & normalGlobalNodeCount,EcmaGlobalStorage<Node> * globalStorage)34     void CalculateGlobalNodeCount(uint64_t &allGlobalNodeCount, uint64_t &normalGlobalNodeCount,
35                                   EcmaGlobalStorage<Node> *globalStorage)
36     {
37         globalStorage->SetNodeKind(NodeKind::UNIFIED_NODE);
38         ASSERT(globalStorage->GetNodeKind() == NodeKind::UNIFIED_NODE);
39         globalStorage->IterateUsageGlobal([&normalGlobalNodeCount] ([[maybe_unused]] Node *node) {
40             normalGlobalNodeCount++;
41         });
42         globalStorage->SetNodeKind(NodeKind::NORMAL_NODE);
43         ASSERT(globalStorage->GetNodeKind() == NodeKind::NORMAL_NODE);
44         globalStorage->IterateUsageGlobal([&allGlobalNodeCount] ([[maybe_unused]] Node *node) {
45             allGlobalNodeCount++;
46         });
47     }
48 };
49 
HWTEST_F_L0(EcmaGlobalStorageTest,XRefGlobalNodes)50 HWTEST_F_L0(EcmaGlobalStorageTest, XRefGlobalNodes)
51 {
52     EcmaVM *vm = thread->GetEcmaVM();
53     JSNApi::InitHybridVMEnv(vm);
54     JSHandle<TaggedArray> weakRefArray = vm->GetFactory()->NewTaggedArray(INT_VALUE_2, JSTaggedValue::Hole());
55     uintptr_t xRefArrayAddress;
56     vm->SetEnableForceGC(false);
57     {
58         [[maybe_unused]] EcmaHandleScope scope(thread);
59         JSHandle<JSTaggedValue> xRefArray = JSArray::ArrayCreate(thread, JSTaggedNumber(INT_VALUE_1));
60         JSHandle<JSTaggedValue> normalArray = JSArray::ArrayCreate(thread, JSTaggedNumber(INT_VALUE_2));
61         xRefArrayAddress = thread->NewXRefGlobalHandle(xRefArray.GetTaggedType());
62         weakRefArray->Set(thread, INT_VALUE_0, xRefArray.GetTaggedValue().CreateAndGetWeakRef());
63         weakRefArray->Set(thread, INT_VALUE_1, normalArray.GetTaggedValue().CreateAndGetWeakRef());
64     }
65     vm->CollectGarbage(TriggerGCType::FULL_GC);
66     EXPECT_TRUE(!weakRefArray->Get(thread, INT_VALUE_0).IsUndefined());
67     EXPECT_TRUE(weakRefArray->Get(thread, INT_VALUE_1).IsUndefined());
68 
69     thread->DisposeXRefGlobalHandle(xRefArrayAddress);
70     vm->CollectGarbage(TriggerGCType::FULL_GC);
71     vm->SetEnableForceGC(true);
72     EXPECT_TRUE(weakRefArray->Get(thread, INT_VALUE_0).IsUndefined());
73 }
74 
HWTEST_F_L0(EcmaGlobalStorageTest,SetNodeKind)75 HWTEST_F_L0(EcmaGlobalStorageTest, SetNodeKind)
76 {
77     EcmaVM *vm = thread->GetEcmaVM();
78     JSNApi::InitHybridVMEnv(vm);
79     JSHandle<TaggedArray> weakRefArray = vm->GetFactory()->NewTaggedArray(INT_VALUE_1, JSTaggedValue::Hole());
80     vm->SetEnableForceGC(false);
81     uintptr_t xrefAddr = 0;
82     {
83         [[maybe_unused]] EcmaHandleScope scope(thread);
84         JSHandle<JSTaggedValue> xRefArray = JSArray::ArrayCreate(thread, JSTaggedNumber(INT_VALUE_1));
85         xrefAddr = thread->NewXRefGlobalHandle(xRefArray.GetTaggedType());
86         weakRefArray->Set(thread, INT_VALUE_0, xRefArray.GetTaggedValue().CreateAndGetWeakRef());
87     }
88     thread->SetNodeKind(NodeKind::UNIFIED_NODE);
89     vm->CollectGarbage(TriggerGCType::FULL_GC);
90     thread->SetNodeKind(NodeKind::NORMAL_NODE);
91     thread->DisposeXRefGlobalHandle(xrefAddr);
92     vm->SetEnableForceGC(true);
93     EXPECT_TRUE(weakRefArray->Get(thread, INT_VALUE_0).IsUndefined());
94 }
95 
HWTEST_F_L0(EcmaGlobalStorageTest,EcmaGlobalStorage)96 HWTEST_F_L0(EcmaGlobalStorageTest, EcmaGlobalStorage)
97 {
98     EcmaVM *vm = thread->GetEcmaVM();
99     auto chunk = vm->GetChunk();
100     EcmaGlobalStorage<Node> *globalStorage =
101         chunk->New<EcmaGlobalStorage<Node>>(nullptr, vm->GetNativeAreaAllocator());
102     uintptr_t xRefArrayAddress;
103     uintptr_t normalArrayAddress;
104     JSHandle<JSTaggedValue> xRefArray = JSArray::ArrayCreate(thread, JSTaggedNumber(INT_VALUE_1));
105     JSHandle<JSTaggedValue> normalArray = JSArray::ArrayCreate(thread, JSTaggedNumber(INT_VALUE_2));
106 
107     uint64_t allGlobalNodeCountBefore = INT_VALUE_0;
108     uint64_t normalGlobalNodeCountBefore = INT_VALUE_0;
109     ASSERT(globalStorage->GetNodeKind() == NodeKind::NORMAL_NODE);
110     CalculateGlobalNodeCount(allGlobalNodeCountBefore, normalGlobalNodeCountBefore, globalStorage);
111     EXPECT_TRUE(normalGlobalNodeCountBefore == allGlobalNodeCountBefore);
112 
113     uint64_t allGlobalNodeCountAfter = INT_VALUE_0;
114     uint64_t normalGlobalNodeCountAfter = INT_VALUE_0;
115     xRefArrayAddress = globalStorage->NewGlobalHandle<NodeKind::UNIFIED_NODE>(xRefArray.GetTaggedType());
116     CalculateGlobalNodeCount(allGlobalNodeCountAfter, normalGlobalNodeCountAfter, globalStorage);
117     EXPECT_TRUE(allGlobalNodeCountAfter == allGlobalNodeCountBefore + INT_VALUE_1);
118     EXPECT_TRUE(normalGlobalNodeCountAfter == normalGlobalNodeCountBefore);
119 
120     allGlobalNodeCountAfter = INT_VALUE_0;
121     normalGlobalNodeCountAfter = INT_VALUE_0;
122     normalArrayAddress = globalStorage->NewGlobalHandle<NodeKind::NORMAL_NODE>(normalArray.GetTaggedType());
123     CalculateGlobalNodeCount(allGlobalNodeCountAfter, normalGlobalNodeCountAfter, globalStorage);
124     EXPECT_TRUE(allGlobalNodeCountAfter == allGlobalNodeCountBefore + INT_VALUE_2);
125     EXPECT_TRUE(normalGlobalNodeCountAfter == normalGlobalNodeCountBefore + INT_VALUE_1);
126 
127     allGlobalNodeCountAfter = INT_VALUE_0;
128     normalGlobalNodeCountAfter = INT_VALUE_0;
129     globalStorage->DisposeGlobalHandle<NodeKind::UNIFIED_NODE>(xRefArrayAddress);
130     CalculateGlobalNodeCount(allGlobalNodeCountAfter, normalGlobalNodeCountAfter, globalStorage);
131     EXPECT_TRUE(allGlobalNodeCountAfter == allGlobalNodeCountBefore + INT_VALUE_1);
132     EXPECT_TRUE(normalGlobalNodeCountAfter == normalGlobalNodeCountBefore + INT_VALUE_1);
133 
134     allGlobalNodeCountAfter = INT_VALUE_0;
135     normalGlobalNodeCountAfter = INT_VALUE_0;
136     globalStorage->DisposeGlobalHandle<NodeKind::NORMAL_NODE>(normalArrayAddress);
137     CalculateGlobalNodeCount(allGlobalNodeCountAfter, normalGlobalNodeCountAfter, globalStorage);
138     EXPECT_TRUE(allGlobalNodeCountAfter == allGlobalNodeCountBefore);
139     EXPECT_TRUE(normalGlobalNodeCountAfter == normalGlobalNodeCountBefore);
140 
141     chunk->Delete(globalStorage);
142 }
143 };
144