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