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