• 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 #ifndef ECMASCRIPT_ECMA_GLOABL_STORAGE_H
17 #define ECMASCRIPT_ECMA_GLOABL_STORAGE_H
18 
19 #include "ecmascript/js_tagged_value.h"
20 
21 #include "ecmascript/mem/c_containers.h"
22 #include "ecmascript/mem/native_area_allocator.h"
23 
24 namespace panda::ecmascript {
25 class EcmaGlobalStorage {
26 public:
27     static const int32_t GLOBAL_BLOCK_SIZE = 256;
28 
EcmaGlobalStorage(NativeAreaAllocator * allocator)29     explicit EcmaGlobalStorage(NativeAreaAllocator *allocator) : allocator_(allocator)
30     {
31         ASSERT(allocator != nullptr);
32         topGlobalNodes_ = lastGlobalNodes_ = allocator_->New<NodeList>(false);
33         topWeakGlobalNodes_ = lastWeakGlobalNodes_ = allocator_->New<NodeList>(true);
34     }
35 
~EcmaGlobalStorage()36     ~EcmaGlobalStorage()
37     {
38         NodeList *next = topGlobalNodes_;
39         NodeList *current = nullptr;
40         while (next != nullptr) {
41             current = next;
42             next = current->GetNext();
43             allocator_->Delete(current);
44         }
45 
46         next = topWeakGlobalNodes_;
47         while (next != nullptr) {
48             current = next;
49             next = current->GetNext();
50             allocator_->Delete(current);
51         }
52     }
53 
54     class Node {
55     public:
GetObject()56         JSTaggedType GetObject() const
57         {
58             return obj_;
59         }
60 
SetObject(JSTaggedType obj)61         void SetObject(JSTaggedType obj)
62         {
63             obj_ = obj;
64         }
65 
GetNext()66         Node *GetNext() const
67         {
68             return next_;
69         }
70 
SetNext(Node * node)71         void SetNext(Node *node)
72         {
73             next_ = node;
74         }
75 
GetPrev()76         Node *GetPrev() const
77         {
78             return prev_;
79         }
80 
SetPrev(Node * node)81         void SetPrev(Node *node)
82         {
83             prev_ = node;
84         }
85 
GetIndex()86         int32_t GetIndex()
87         {
88             return index_;
89         }
90 
SetIndex(int32_t index)91         void SetIndex(int32_t index)
92         {
93             index_ = index;
94         }
95 
SetFree(bool free)96         void SetFree(bool free)
97         {
98             isFree_ = free;
99         }
100 
IsFree()101         bool IsFree() const
102         {
103             return isFree_;
104         }
105 
GetObjectAddress()106         uintptr_t GetObjectAddress() const
107         {
108             return reinterpret_cast<uintptr_t>(&obj_);
109         }
110 
111     private:
112         JSTaggedType obj_;
113         Node *next_ {nullptr};
114         Node *prev_ {nullptr};
115         int32_t index_ {-1};
116         bool isFree_ {false};
117     };
118 
119     class NodeList {
120     public:
NodeList(bool isWeak)121         NodeList(bool isWeak) : isWeak_(isWeak)
122         {
123             for (int i = 0; i < GLOBAL_BLOCK_SIZE; i++) {
124                 nodeList_[i].SetIndex(i);
125             }
126         }
127         ~NodeList() = default;
128 
129         inline static NodeList *NodeToNodeList(Node *node);
130 
131         inline Node *NewNode(JSTaggedType value);
132         inline Node *GetFreeNode(JSTaggedType value);
133         inline void FreeNode(Node *node);
134 
135         inline void LinkTo(NodeList *prev);
136         inline void RemoveList();
137 
IsFull()138         inline bool IsFull()
139         {
140             return index_ >= GLOBAL_BLOCK_SIZE;
141         }
142 
IsWeak()143         inline bool IsWeak()
144         {
145             return isWeak_;
146         }
147 
HasFreeNode()148         inline bool HasFreeNode()
149         {
150             return freeList_ != nullptr;
151         }
152 
HasUsagedNode()153         inline bool HasUsagedNode()
154         {
155             return !IsFull() || usedList_ != nullptr;
156         }
157 
SetNext(NodeList * next)158         inline void SetNext(NodeList *next)
159         {
160             next_ = next;
161         }
GetNext()162         inline NodeList *GetNext() const
163         {
164             return next_;
165         }
166 
SetPrev(NodeList * prev)167         inline void SetPrev(NodeList *prev)
168         {
169             prev_ = prev;
170         }
GetPrev()171         inline NodeList *GetPrev() const
172         {
173             return prev_;
174         }
175 
SetFreeNext(NodeList * next)176         inline void SetFreeNext(NodeList *next)
177         {
178             freeNext_ = next;
179         }
GetFreeNext()180         inline NodeList *GetFreeNext() const
181         {
182             return freeNext_;
183         }
184 
SetFreePrev(NodeList * prev)185         inline void SetFreePrev(NodeList *prev)
186         {
187             freePrev_ = prev;
188         }
GetFreePrev()189         inline NodeList *GetFreePrev() const
190         {
191             return freePrev_;
192         }
193 
194         template<class Callback>
IterateUsageGlobal(Callback callback)195         inline void IterateUsageGlobal(Callback callback)
196         {
197             Node *next = usedList_;
198             Node *current = nullptr;
199             while (next != nullptr) {
200                 current = next;
201                 next = current->GetNext();
202                 ASSERT(current != next);
203                 callback(current);
204             }
205         }
206 
207     private:
208         Node nodeList_[GLOBAL_BLOCK_SIZE];  // all
209         Node *freeList_ {nullptr};  // dispose node
210         Node *usedList_ {nullptr};  // usage node
211         int32_t index_ {0};
212         bool isWeak_ {false};
213         NodeList *next_ {nullptr};
214         NodeList *prev_ {nullptr};
215         NodeList *freeNext_ {nullptr};
216         NodeList *freePrev_ {nullptr};
217     };
218 
219     inline uintptr_t NewGlobalHandle(JSTaggedType value);
220     inline void DisposeGlobalHandle(uintptr_t addr);
221     inline uintptr_t SetWeak(uintptr_t addr);
222     inline uintptr_t ClearWeak(uintptr_t addr);
223     inline bool IsWeak(uintptr_t addr) const;
224 
225     template<class Callback>
IterateUsageGlobal(Callback callback)226     void IterateUsageGlobal(Callback callback)
227     {
228         NodeList *next = topGlobalNodes_;
229         NodeList *current = nullptr;
230         while (next != nullptr) {
231             current = next;
232             next = current->GetNext();
233             ASSERT(current != next);
234             current->IterateUsageGlobal(callback);
235         }
236     }
237 
238     template<class Callback>
IterateWeakUsageGlobal(Callback callback)239     void IterateWeakUsageGlobal(Callback callback)
240     {
241         NodeList *next = topWeakGlobalNodes_;
242         NodeList *current = nullptr;
243         while (next != nullptr) {
244             current = next;
245             next = current->GetNext();
246             ASSERT(current != next);
247             current->IterateUsageGlobal(callback);
248         }
249     }
250 
251 private:
252     NO_COPY_SEMANTIC(EcmaGlobalStorage);
253     NO_MOVE_SEMANTIC(EcmaGlobalStorage);
254 
255     inline uintptr_t NewGlobalHandleImplement(NodeList **storage, NodeList **freeList, bool isWeak, JSTaggedType value);
256 
257     NativeAreaAllocator *allocator_ {nullptr};
258     NodeList *topGlobalNodes_ {nullptr};
259     NodeList *lastGlobalNodes_ {nullptr};
260     NodeList *freeListNodes_ {nullptr};
261 
262     NodeList *topWeakGlobalNodes_ {nullptr};
263     NodeList *lastWeakGlobalNodes_ {nullptr};
264     NodeList *weakFreeListNodes_ {nullptr};
265 };
266 }  // namespace panda::ecmascript
267 #endif  // ECMASCRIPT_ECMA_GLOABL_STORAGE_H
268