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 #ifndef PANDA_RUNTIME_MEM_REFERENCE_H 16 #define PANDA_RUNTIME_MEM_REFERENCE_H 17 18 #include "libpandabase/macros.h" 19 #include "libpandabase/mem/mem.h" 20 21 namespace ark::mem { 22 class ReferenceStorage; 23 class RefBlock; 24 namespace test { 25 class ReferenceStorageTest; 26 } // namespace test 27 } // namespace ark::mem 28 29 namespace ark::mem { 30 31 class GlobalObjectStorage; 32 33 class Reference { 34 public: 35 enum class ObjectType : uint8_t { 36 /// Used for objects on stack (arguments for methods) 37 STACK = 0, 38 /** 39 * Local references which can be used inside Frame. If Frame was removed all references inside this Frame can't 40 * be used anymore 41 */ 42 LOCAL = 1, 43 /// Global references which can be used without Frames 44 GLOBAL = 2, 45 /** 46 * Weak references which work as Global references, but will be nullified when GC clears the object when the 47 * object becomes unreachable (no guarantees when it will happen) 48 */ 49 WEAK = 3, 50 /// Global references which can be used without Frames. Addresses of references aren't changed 51 GLOBAL_FIXED = LOCAL, 52 ENUM_SIZE = 4 53 }; 54 55 DEFAULT_COPY_SEMANTIC(Reference); 56 DEFAULT_MOVE_SEMANTIC(Reference); 57 ~Reference() = delete; 58 Reference() = delete; 59 IsStack()60 bool IsStack() const 61 { 62 return GetType() == ObjectType::STACK; 63 } 64 IsLocal()65 bool IsLocal() const 66 { 67 ObjectType type = GetType(); 68 return type == ObjectType::STACK || type == ObjectType::LOCAL; 69 } 70 IsGlobal()71 bool IsGlobal() const 72 { 73 return GetType() == ObjectType::GLOBAL; 74 } 75 IsGlobalFixed()76 bool IsGlobalFixed() const 77 { 78 return GetType() == ObjectType::GLOBAL_FIXED; 79 } 80 IsWeak()81 bool IsWeak() const 82 { 83 return GetType() == ObjectType::WEAK; 84 } 85 86 private: 87 static constexpr auto MASK_TYPE = 3U; 88 static constexpr auto MASK_WITHOUT_TYPE = sizeof(uintptr_t) == sizeof(uint64_t) 89 ? std::numeric_limits<uint64_t>::max() - MASK_TYPE 90 : std::numeric_limits<uint32_t>::max() - MASK_TYPE; 91 CreateWithoutType(uintptr_t addr)92 static Reference *CreateWithoutType(uintptr_t addr) 93 { 94 ASSERT((addr & MASK_TYPE) == 0); 95 return reinterpret_cast<Reference *>(addr); 96 } 97 Create(uintptr_t addr,ObjectType type)98 static Reference *Create(uintptr_t addr, ObjectType type) 99 { 100 ASSERT((addr & MASK_TYPE) == 0); 101 return SetType(addr, type); 102 } 103 GetType(const Reference * ref)104 static ObjectType GetType(const Reference *ref) 105 { 106 auto addr = ToUintPtr(ref); 107 return static_cast<ObjectType>(addr & MASK_TYPE); 108 } 109 SetType(Reference * ref,ObjectType type)110 static Reference *SetType(Reference *ref, ObjectType type) 111 { 112 auto addr = ToUintPtr(ref); 113 return SetType(addr, type); 114 } 115 SetType(uintptr_t addr,ObjectType type)116 static Reference *SetType(uintptr_t addr, ObjectType type) 117 { 118 ASSERT((addr & MASK_TYPE) == 0); 119 return reinterpret_cast<Reference *>(addr | static_cast<uintptr_t>(type)); 120 } 121 GetType()122 ObjectType GetType() const 123 { 124 return Reference::GetType(this); 125 } 126 GetRefWithoutType(const Reference * ref)127 static Reference *GetRefWithoutType(const Reference *ref) 128 { 129 auto addr = ToUintPtr(ref); 130 return reinterpret_cast<Reference *>(addr & MASK_WITHOUT_TYPE); 131 } 132 133 friend class ark::mem::ReferenceStorage; 134 friend class ark::mem::GlobalObjectStorage; 135 friend class ark::mem::RefBlock; 136 friend class ark::mem::test::ReferenceStorageTest; 137 }; 138 } // namespace ark::mem 139 #endif // PANDA_RUNTIME_MEM_REFERENCE_H 140