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 PANDA_RUNTIME_MEM_REFSTORAGE_REFERENCE_H_ 17 #define PANDA_RUNTIME_MEM_REFSTORAGE_REFERENCE_H_ 18 19 #include "libpandabase/macros.h" 20 #include "libpandabase/mem/mem.h" 21 22 namespace panda::mem { 23 class ReferenceStorage; 24 class RefBlock; 25 namespace test { 26 class ReferenceStorageTest; 27 } // namespace test 28 } // namespace panda::mem 29 30 namespace panda::mem { 31 32 class GlobalObjectStorage; 33 34 class Reference { 35 public: 36 enum class ObjectType : uint8_t { 37 /** 38 * Used for objects on stack (arguments for methods) 39 */ 40 STACK = 0, 41 /** 42 * Local references which were created by NewLocalRef JNI method 43 */ 44 LOCAL = 1, 45 /** 46 * Local references which were created by NewGlobalRef JNI method 47 */ 48 GLOBAL = 2, 49 /** 50 * Local references which were created by NewWeakGlobalRef JNI method 51 */ 52 WEAK = 3, 53 ENUM_SIZE 54 }; 55 56 DEFAULT_COPY_SEMANTIC(Reference); 57 DEFAULT_MOVE_SEMANTIC(Reference); 58 ~Reference() = delete; 59 Reference() = delete; 60 IsStack()61 bool IsStack() const 62 { 63 return GetType() == ObjectType::STACK; 64 } 65 IsLocal()66 bool IsLocal() const 67 { 68 ObjectType type = GetType(); 69 return type == ObjectType::STACK || type == ObjectType::LOCAL; 70 } 71 IsGlobal()72 bool IsGlobal() const 73 { 74 return GetType() == ObjectType::GLOBAL; 75 } 76 IsWeak()77 bool IsWeak() const 78 { 79 return GetType() == ObjectType::WEAK; 80 } 81 82 private: 83 static constexpr auto MASK_TYPE = 3U; 84 static constexpr auto MASK_WITHOUT_TYPE = sizeof(uintptr_t) == sizeof(uint64_t) 85 ? std::numeric_limits<uint64_t>::max() - MASK_TYPE 86 : std::numeric_limits<uint32_t>::max() - MASK_TYPE; 87 CreateWithoutType(uintptr_t addr)88 static Reference *CreateWithoutType(uintptr_t addr) 89 { 90 ASSERT((addr & MASK_TYPE) == 0); 91 return reinterpret_cast<Reference *>(addr); 92 } 93 Create(uintptr_t addr,ObjectType type)94 static Reference *Create(uintptr_t addr, ObjectType type) 95 { 96 ASSERT((addr & MASK_TYPE) == 0); 97 return SetType(addr, type); 98 } 99 GetType(const Reference * ref)100 static ObjectType GetType(const Reference *ref) 101 { 102 auto addr = ToUintPtr(ref); 103 return static_cast<ObjectType>(addr & MASK_TYPE); 104 } 105 SetType(Reference * ref,ObjectType type)106 static Reference *SetType(Reference *ref, ObjectType type) 107 { 108 auto addr = ToUintPtr(ref); 109 return SetType(addr, type); 110 } 111 SetType(uintptr_t addr,ObjectType type)112 static Reference *SetType(uintptr_t addr, ObjectType type) 113 { 114 ASSERT((addr & MASK_TYPE) == 0); 115 return reinterpret_cast<Reference *>(addr | static_cast<uintptr_t>(type)); 116 } 117 GetType()118 ObjectType GetType() const 119 { 120 return Reference::GetType(this); 121 } 122 GetRefWithoutType(const Reference * ref)123 static Reference *GetRefWithoutType(const Reference *ref) 124 { 125 auto addr = ToUintPtr(ref); 126 return reinterpret_cast<Reference *>(addr & MASK_WITHOUT_TYPE); 127 } 128 129 friend class panda::mem::ReferenceStorage; 130 friend class panda::mem::GlobalObjectStorage; 131 friend class panda::mem::RefBlock; 132 friend class panda::mem::test::ReferenceStorageTest; 133 }; 134 } // namespace panda::mem 135 136 #endif // PANDA_RUNTIME_MEM_REFSTORAGE_REFERENCE_H_ 137