• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2025 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 PANDA_RUNTIME_HANDLE_STORAGE_INL_H
17 #define PANDA_RUNTIME_HANDLE_STORAGE_INL_H
18 
19 #include "runtime/handle_storage.h"
20 #include "runtime/mem/object_helpers.h"
21 
22 namespace ark {
23 template <typename T>
GetNodeAddress(uint32_t index)24 inline uintptr_t HandleStorage<T>::GetNodeAddress(uint32_t index) const
25 {
26     uint32_t id = index >> NODE_BLOCK_SIZE_LOG2;
27     uint32_t offset = index & NODE_BLOCK_SIZE_MASK;
28     auto node = nodes_[id];
29     auto location = &(*node)[offset];
30     return reinterpret_cast<uintptr_t>(location);
31 }
32 
33 template <typename T>
34 // CC-OFFNXT(G.FUD.06) solid logic
NewHandle(T value)35 inline uintptr_t HandleStorage<T>::NewHandle(T value)
36 {
37     uint32_t nid = lastIndex_ >> NODE_BLOCK_SIZE_LOG2;
38     uint32_t offset = lastIndex_ & NODE_BLOCK_SIZE_MASK;
39     if (nodes_.size() <= nid) {
40         auto n = allocator_->New<std::array<T, NODE_BLOCK_SIZE>>();
41         nodes_.push_back(n);
42     }
43     auto node = nodes_[nid];
44     auto loc = &(*node)[offset];
45     *loc = value;
46     lastIndex_++;
47     return reinterpret_cast<uintptr_t>(loc);
48 }
49 
50 template <typename T>
FreeExtraNodes(uint32_t nid)51 inline void HandleStorage<T>::FreeExtraNodes(uint32_t nid)
52 {
53     for (size_t i = nid; i < nodes_.size(); ++i) {
54         allocator_->Delete(nodes_[i]);
55     }
56     if (nid < nodes_.size()) {
57         nodes_.erase(nodes_.begin() + nid, nodes_.end());
58     }
59 }
60 
61 template <typename T>
FreeHandles(uint32_t beginIdx)62 inline void HandleStorage<T>::FreeHandles(uint32_t beginIdx)
63 {
64     lastIndex_ = beginIdx;
65 #ifndef NDEBUG
66     ZapFreedHandles();
67 #endif
68     uint32_t nid = lastIndex_ >> NODE_BLOCK_SIZE_LOG2;
69     // reserve at least one block for perf.
70     nid++;
71     FreeExtraNodes(nid);
72 }
73 
74 template <typename T>
ZapFreedHandlesForNode(std::array<T,NODE_BLOCK_SIZE> * node,uint32_t start)75 void HandleStorage<T>::ZapFreedHandlesForNode(std::array<T, NODE_BLOCK_SIZE> *node, uint32_t start)
76 {
77     for (uint32_t j = start; j < NODE_BLOCK_SIZE; ++j) {
78         node->at(j) = reinterpret_cast<T>(static_cast<uint64_t>(0));
79     }
80 }
81 
82 template <typename T>
ZapFreedHandles()83 void HandleStorage<T>::ZapFreedHandles()
84 {
85     uint32_t nid = lastIndex_ >> NODE_BLOCK_SIZE_LOG2;
86     uint32_t offset = lastIndex_ & NODE_BLOCK_SIZE_MASK;
87     for (size_t i = nid; i < nodes_.size(); ++i) {
88         auto node = nodes_.at(i);
89         if (i != nid) {
90             ZapFreedHandlesForNode(node);
91         } else {
92             ZapFreedHandlesForNode(node, offset);
93         }
94     }
95 }
96 
97 template <>
UpdateHeapObjectForNode(std::array<coretypes::TaggedType,NODE_BLOCK_SIZE> * node,uint32_t size,const GCRootUpdater & gcRootUpdater)98 inline void HandleStorage<coretypes::TaggedType>::UpdateHeapObjectForNode(
99     std::array<coretypes::TaggedType, NODE_BLOCK_SIZE> *node, uint32_t size, const GCRootUpdater &gcRootUpdater)
100 {
101     for (uint32_t j = 0; j < size; ++j) {
102         coretypes::TaggedValue obj(node->at(j));
103         if (!obj.IsHeapObject()) {
104             continue;
105         }
106         ObjectHeader *objH = obj.GetHeapObject();
107         if (gcRootUpdater(&objH)) {
108             (*node)[j] = coretypes::TaggedValue(objH).GetRawData();
109         }
110     }
111 }
112 
113 template <>
114 // CC-OFFNXT(G.FUD.06) solid logic
UpdateHeapObject(const GCRootUpdater & gcRootUpdater)115 inline void HandleStorage<coretypes::TaggedType>::UpdateHeapObject(const GCRootUpdater &gcRootUpdater)
116 {
117     if (lastIndex_ == 0) {
118         return;
119     }
120     uint32_t nid = lastIndex_ >> NODE_BLOCK_SIZE_LOG2;
121     uint32_t offset = lastIndex_ & NODE_BLOCK_SIZE_MASK;
122     for (uint32_t i = 0; i <= nid; ++i) {
123         auto node = nodes_.at(i);
124         uint32_t count = (i != nid) ? NODE_BLOCK_SIZE : offset;
125         UpdateHeapObjectForNode(node, count, gcRootUpdater);
126     }
127 }
128 
129 template <>
VisitGCRootsForNode(std::array<coretypes::TaggedType,NODE_BLOCK_SIZE> * node,uint32_t size,const ObjectVisitor & cb)130 inline void HandleStorage<coretypes::TaggedType>::VisitGCRootsForNode(
131     std::array<coretypes::TaggedType, NODE_BLOCK_SIZE> *node, uint32_t size, const ObjectVisitor &cb)
132 {
133     for (uint32_t j = 0; j < size; ++j) {
134         coretypes::TaggedValue obj(node->at(j));
135         if (obj.IsHeapObject()) {
136             cb(obj.GetHeapObject());
137         }
138     }
139 }
140 
141 template <>
142 // CC-OFFNXT(G.FUD.06) solid logic
VisitGCRoots(const ObjectVisitor & cb)143 inline void HandleStorage<coretypes::TaggedType>::VisitGCRoots([[maybe_unused]] const ObjectVisitor &cb)
144 {
145     if (lastIndex_ == 0) {
146         return;
147     }
148     uint32_t nid = lastIndex_ >> NODE_BLOCK_SIZE_LOG2;
149     uint32_t offset = lastIndex_ & NODE_BLOCK_SIZE_MASK;
150     if (offset == 0) {
151         nid -= 1;
152         offset = NODE_BLOCK_SIZE;
153     }
154     for (uint32_t i = 0; i <= nid; ++i) {
155         auto node = nodes_.at(i);
156         uint32_t count = (i != nid) ? NODE_BLOCK_SIZE : offset;
157         VisitGCRootsForNode(node, count, cb);
158     }
159 }
160 
161 template <>
UpdateHeapObjectForNode(std::array<ObjectHeader *,NODE_BLOCK_SIZE> * node,uint32_t size,const GCRootUpdater & gcRootUpdater)162 inline void HandleStorage<ObjectHeader *>::UpdateHeapObjectForNode(std::array<ObjectHeader *, NODE_BLOCK_SIZE> *node,
163                                                                    uint32_t size, const GCRootUpdater &gcRootUpdater)
164 {
165     for (uint32_t j = 0; j < size; ++j) {
166         gcRootUpdater(reinterpret_cast<ObjectHeader **>(&(*node)[j]));
167     }
168 }
169 
170 template <>
171 // CC-OFFNXT(G.FUD.06) solid logic
UpdateHeapObject(const GCRootUpdater & gcRootUpdater)172 inline void HandleStorage<ObjectHeader *>::UpdateHeapObject(const GCRootUpdater &gcRootUpdater)
173 {
174     if (lastIndex_ == 0) {
175         return;
176     }
177     uint32_t nid = lastIndex_ >> NODE_BLOCK_SIZE_LOG2;
178     uint32_t offset = lastIndex_ & NODE_BLOCK_SIZE_MASK;
179     if (offset == 0) {
180         nid -= 1;
181         offset = NODE_BLOCK_SIZE;
182     }
183     for (uint32_t i = 0; i <= nid; ++i) {
184         auto node = nodes_.at(i);
185         uint32_t count = (i != nid) ? NODE_BLOCK_SIZE : offset;
186         UpdateHeapObjectForNode(node, count, gcRootUpdater);
187     }
188 }
189 
190 template <>
VisitGCRootsForNode(std::array<ObjectHeader *,NODE_BLOCK_SIZE> * node,uint32_t size,const ObjectVisitor & cb)191 inline void HandleStorage<ObjectHeader *>::VisitGCRootsForNode(std::array<ObjectHeader *, NODE_BLOCK_SIZE> *node,
192                                                                uint32_t size, const ObjectVisitor &cb)
193 {
194     for (uint32_t j = 0; j < size; ++j) {
195         auto obj = reinterpret_cast<ObjectHeader *>(node->at(j));
196         cb(obj);
197     }
198 }
199 
200 template <>
201 // CC-OFFNXT(G.FUD.06) solid logic
VisitGCRoots(const ObjectVisitor & cb)202 inline void HandleStorage<ObjectHeader *>::VisitGCRoots([[maybe_unused]] const ObjectVisitor &cb)
203 {
204     if (lastIndex_ == 0) {
205         return;
206     }
207     uint32_t nid = lastIndex_ >> NODE_BLOCK_SIZE_LOG2;
208     uint32_t offset = lastIndex_ & NODE_BLOCK_SIZE_MASK;
209     for (uint32_t i = 0; i <= nid; ++i) {
210         auto node = nodes_.at(i);
211         uint32_t count = (i != nid) ? NODE_BLOCK_SIZE : offset;
212         VisitGCRootsForNode(node, count, cb);
213     }
214 }
215 
216 template class HandleStorage<coretypes::TaggedType>;
217 }  // namespace ark
218 
219 #endif  // PANDA_RUNTIME_HANDLE_STORAGE_INL_H
220