1 /** 2 * Copyright (c) 2021-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 #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)24inline 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)35inline 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> FreeHandles(uint32_t beginIdx)51inline void HandleStorage<T>::FreeHandles(uint32_t beginIdx) 52 { 53 lastIndex_ = beginIdx; 54 #ifndef NDEBUG 55 ZapFreedHandles(); 56 #endif 57 uint32_t nid = lastIndex_ >> NODE_BLOCK_SIZE_LOG2; 58 // reserve at least one block for perf. 59 nid++; 60 for (size_t i = nid; i < nodes_.size(); ++i) { 61 allocator_->Delete(nodes_[i]); 62 } 63 if (nid < nodes_.size()) { 64 nodes_.erase(nodes_.begin() + nid, nodes_.end()); 65 } 66 } 67 68 template <typename T> ZapFreedHandles()69void HandleStorage<T>::ZapFreedHandles() 70 { 71 uint32_t nid = lastIndex_ >> NODE_BLOCK_SIZE_LOG2; 72 uint32_t offset = lastIndex_ & NODE_BLOCK_SIZE_MASK; 73 for (size_t i = nid; i < nodes_.size(); ++i) { 74 auto node = nodes_.at(i); 75 if (i != nid) { 76 node->fill(reinterpret_cast<T>(static_cast<uint64_t>(0))); 77 } else { 78 for (uint32_t j = offset; j < NODE_BLOCK_SIZE; ++j) { 79 node->at(j) = reinterpret_cast<T>(static_cast<uint64_t>(0)); 80 } 81 } 82 } 83 } 84 85 template <> 86 // CC-OFFNXT(G.FUD.06) solid logic UpdateHeapObject()87inline void HandleStorage<coretypes::TaggedType>::UpdateHeapObject() 88 { 89 if (lastIndex_ == 0) { 90 return; 91 } 92 uint32_t nid = lastIndex_ >> NODE_BLOCK_SIZE_LOG2; 93 uint32_t offset = lastIndex_ & NODE_BLOCK_SIZE_MASK; 94 for (uint32_t i = 0; i <= nid; ++i) { 95 auto node = nodes_.at(i); 96 uint32_t count = (i != nid) ? NODE_BLOCK_SIZE : offset; 97 for (uint32_t j = 0; j < count; ++j) { 98 coretypes::TaggedValue obj(node->at(j)); 99 if (obj.IsHeapObject() && obj.GetHeapObject()->IsForwarded()) { 100 (*node)[j] = coretypes::TaggedValue(ark::mem::GetForwardAddress(obj.GetHeapObject())).GetRawData(); 101 } 102 } 103 } 104 } 105 106 template <> 107 // CC-OFFNXT(G.FUD.06) solid logic VisitGCRoots(const ObjectVisitor & cb)108inline void HandleStorage<coretypes::TaggedType>::VisitGCRoots([[maybe_unused]] const ObjectVisitor &cb) 109 { 110 if (lastIndex_ == 0) { 111 return; 112 } 113 uint32_t nid = lastIndex_ >> NODE_BLOCK_SIZE_LOG2; 114 uint32_t offset = lastIndex_ & NODE_BLOCK_SIZE_MASK; 115 if (offset == 0) { 116 nid -= 1; 117 offset = NODE_BLOCK_SIZE; 118 } 119 for (uint32_t i = 0; i <= nid; ++i) { 120 auto node = nodes_.at(i); 121 uint32_t count = (i != nid) ? NODE_BLOCK_SIZE : offset; 122 for (uint32_t j = 0; j < count; ++j) { 123 coretypes::TaggedValue obj(node->at(j)); 124 if (obj.IsHeapObject()) { 125 cb(obj.GetHeapObject()); 126 } 127 } 128 } 129 } 130 131 template <> 132 // CC-OFFNXT(G.FUD.06) solid logic UpdateHeapObject()133inline void HandleStorage<ObjectHeader *>::UpdateHeapObject() 134 { 135 if (lastIndex_ == 0) { 136 return; 137 } 138 uint32_t nid = lastIndex_ >> NODE_BLOCK_SIZE_LOG2; 139 uint32_t offset = lastIndex_ & NODE_BLOCK_SIZE_MASK; 140 if (offset == 0) { 141 nid -= 1; 142 offset = NODE_BLOCK_SIZE; 143 } 144 for (uint32_t i = 0; i <= nid; ++i) { 145 auto node = nodes_.at(i); 146 uint32_t count = (i != nid) ? NODE_BLOCK_SIZE : offset; 147 for (uint32_t j = 0; j < count; ++j) { 148 auto *obj = reinterpret_cast<ObjectHeader *>(node->at(j)); 149 if (obj->IsForwarded()) { 150 (*node)[j] = ::ark::mem::GetForwardAddress(obj); 151 } 152 } 153 } 154 } 155 156 template <> 157 // CC-OFFNXT(G.FUD.06) solid logic VisitGCRoots(const ObjectVisitor & cb)158inline void HandleStorage<ObjectHeader *>::VisitGCRoots([[maybe_unused]] const ObjectVisitor &cb) 159 { 160 if (lastIndex_ == 0) { 161 return; 162 } 163 uint32_t nid = lastIndex_ >> NODE_BLOCK_SIZE_LOG2; 164 uint32_t offset = lastIndex_ & NODE_BLOCK_SIZE_MASK; 165 for (uint32_t i = 0; i <= nid; ++i) { 166 auto node = nodes_.at(i); 167 uint32_t count = (i != nid) ? NODE_BLOCK_SIZE : offset; 168 for (uint32_t j = 0; j < count; ++j) { 169 auto obj = reinterpret_cast<ObjectHeader *>(node->at(j)); 170 cb(obj); 171 } 172 } 173 } 174 175 template class HandleStorage<coretypes::TaggedType>; 176 } // namespace ark 177 178 #endif // PANDA_RUNTIME_HANDLE_STORAGE_INL_H 179