• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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