xref: /aosp_15_r20/art/runtime/handle.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_HANDLE_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_HANDLE_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h>
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include "base/casts.h"
23*795d594fSAndroid Build Coastguard Worker #include "base/locks.h"
24*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/value_object.h"
26*795d594fSAndroid Build Coastguard Worker #include "jni.h"
27*795d594fSAndroid Build Coastguard Worker #include "obj_ptr.h"
28*795d594fSAndroid Build Coastguard Worker #include "stack_reference.h"
29*795d594fSAndroid Build Coastguard Worker 
30*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker class Thread;
33*795d594fSAndroid Build Coastguard Worker 
34*795d594fSAndroid Build Coastguard Worker template<class T> class Handle;
35*795d594fSAndroid Build Coastguard Worker template<typename T> class IterationRange;
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker namespace mirror {
38*795d594fSAndroid Build Coastguard Worker template<typename T> class ObjectArray;
39*795d594fSAndroid Build Coastguard Worker template<typename T, typename C> class ArrayIter;
40*795d594fSAndroid Build Coastguard Worker template<typename T> using HandleArrayIter = ArrayIter<T, Handle<ObjectArray<T>>>;
41*795d594fSAndroid Build Coastguard Worker template<typename T> using ConstHandleArrayIter = ArrayIter<T, const Handle<ObjectArray<T>>>;
42*795d594fSAndroid Build Coastguard Worker }  // namespace mirror
43*795d594fSAndroid Build Coastguard Worker 
44*795d594fSAndroid Build Coastguard Worker // Handles are memory locations that contain GC roots. As the mirror::Object*s within a handle are
45*795d594fSAndroid Build Coastguard Worker // GC visible then the GC may move the references within them, something that couldn't be done with
46*795d594fSAndroid Build Coastguard Worker // a wrap pointer. Handles are generally allocated within HandleScopes. Handle is a super-class
47*795d594fSAndroid Build Coastguard Worker // of MutableHandle and doesn't support assignment operations.
48*795d594fSAndroid Build Coastguard Worker template<class T>
49*795d594fSAndroid Build Coastguard Worker class Handle : public ValueObject {
50*795d594fSAndroid Build Coastguard Worker  public:
Handle()51*795d594fSAndroid Build Coastguard Worker   constexpr Handle() : reference_(nullptr) {
52*795d594fSAndroid Build Coastguard Worker   }
53*795d594fSAndroid Build Coastguard Worker 
54*795d594fSAndroid Build Coastguard Worker   constexpr ALWAYS_INLINE Handle(const Handle<T>& handle) = default;
55*795d594fSAndroid Build Coastguard Worker 
56*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE Handle<T>& operator=(const Handle<T>& handle) = default;
57*795d594fSAndroid Build Coastguard Worker 
58*795d594fSAndroid Build Coastguard Worker   template <typename Type,
59*795d594fSAndroid Build Coastguard Worker             typename = typename std::enable_if_t<std::is_base_of_v<T, Type>>>
Handle(const Handle<Type> & other)60*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE Handle(const Handle<Type>& other) : reference_(other.reference_) {
61*795d594fSAndroid Build Coastguard Worker   }
62*795d594fSAndroid Build Coastguard Worker 
Handle(StackReference<T> * reference)63*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE explicit Handle(StackReference<T>* reference) : reference_(reference) {
64*795d594fSAndroid Build Coastguard Worker   }
65*795d594fSAndroid Build Coastguard Worker 
REQUIRES_SHARED(Locks::mutator_lock_)66*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE T& operator*() const REQUIRES_SHARED(Locks::mutator_lock_) {
67*795d594fSAndroid Build Coastguard Worker     return *Get();
68*795d594fSAndroid Build Coastguard Worker   }
69*795d594fSAndroid Build Coastguard Worker 
70*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE T* operator->() const REQUIRES_SHARED(Locks::mutator_lock_) {
71*795d594fSAndroid Build Coastguard Worker     return Get();
72*795d594fSAndroid Build Coastguard Worker   }
73*795d594fSAndroid Build Coastguard Worker 
Get()74*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE T* Get() const REQUIRES_SHARED(Locks::mutator_lock_) {
75*795d594fSAndroid Build Coastguard Worker     return down_cast<T*>(reference_->AsMirrorPtr());
76*795d594fSAndroid Build Coastguard Worker   }
77*795d594fSAndroid Build Coastguard Worker 
78*795d594fSAndroid Build Coastguard Worker   template <typename Type,
79*795d594fSAndroid Build Coastguard Worker             typename = typename std::enable_if_t<std::is_same_v<mirror::ObjectArray<Type>, T>>>
ConstIterate()80*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE IterationRange<mirror::ConstHandleArrayIter<Type>> ConstIterate() const
81*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
82*795d594fSAndroid Build Coastguard Worker     return T::ConstIterate(*this);
83*795d594fSAndroid Build Coastguard Worker   }
84*795d594fSAndroid Build Coastguard Worker   template <typename Type,
85*795d594fSAndroid Build Coastguard Worker             typename = typename std::enable_if_t<std::is_same_v<mirror::ObjectArray<Type>, T>>>
Iterate()86*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE IterationRange<mirror::HandleArrayIter<Type>> Iterate()
87*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
88*795d594fSAndroid Build Coastguard Worker     return T::Iterate(*this);
89*795d594fSAndroid Build Coastguard Worker   }
90*795d594fSAndroid Build Coastguard Worker 
IsNull()91*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE bool IsNull() const {
92*795d594fSAndroid Build Coastguard Worker     // It's safe to null-check it without a read barrier.
93*795d594fSAndroid Build Coastguard Worker     return reference_->IsNull();
94*795d594fSAndroid Build Coastguard Worker   }
95*795d594fSAndroid Build Coastguard Worker 
GetReference()96*795d594fSAndroid Build Coastguard Worker   constexpr ALWAYS_INLINE StackReference<mirror::Object>* GetReference() {
97*795d594fSAndroid Build Coastguard Worker     return reference_;
98*795d594fSAndroid Build Coastguard Worker   }
99*795d594fSAndroid Build Coastguard Worker 
GetReference()100*795d594fSAndroid Build Coastguard Worker   constexpr ALWAYS_INLINE const StackReference<mirror::Object>* GetReference() const {
101*795d594fSAndroid Build Coastguard Worker     return reference_;
102*795d594fSAndroid Build Coastguard Worker   }
103*795d594fSAndroid Build Coastguard Worker 
104*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE bool operator!=(std::nullptr_t) const {
105*795d594fSAndroid Build Coastguard Worker     return !IsNull();
106*795d594fSAndroid Build Coastguard Worker   }
107*795d594fSAndroid Build Coastguard Worker 
108*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE bool operator==(std::nullptr_t) const {
109*795d594fSAndroid Build Coastguard Worker     return IsNull();
110*795d594fSAndroid Build Coastguard Worker   }
111*795d594fSAndroid Build Coastguard Worker 
112*795d594fSAndroid Build Coastguard Worker   mirror::Object* ObjectFromGdb() REQUIRES_SHARED(Locks::mutator_lock_);
113*795d594fSAndroid Build Coastguard Worker   T* GetFromGdb() REQUIRES_SHARED(Locks::mutator_lock_);
114*795d594fSAndroid Build Coastguard Worker 
115*795d594fSAndroid Build Coastguard Worker  protected:
116*795d594fSAndroid Build Coastguard Worker   template<typename S>
Handle(StackReference<S> * reference)117*795d594fSAndroid Build Coastguard Worker   explicit Handle(StackReference<S>* reference)
118*795d594fSAndroid Build Coastguard Worker       : reference_(reference) {
119*795d594fSAndroid Build Coastguard Worker   }
120*795d594fSAndroid Build Coastguard Worker   template<typename S>
Handle(const Handle<S> & handle)121*795d594fSAndroid Build Coastguard Worker   explicit Handle(const Handle<S>& handle)
122*795d594fSAndroid Build Coastguard Worker       : reference_(handle.reference_) {
123*795d594fSAndroid Build Coastguard Worker   }
124*795d594fSAndroid Build Coastguard Worker 
125*795d594fSAndroid Build Coastguard Worker   StackReference<mirror::Object>* reference_;
126*795d594fSAndroid Build Coastguard Worker 
127*795d594fSAndroid Build Coastguard Worker  private:
128*795d594fSAndroid Build Coastguard Worker   friend class BuildGenericJniFrameVisitor;
129*795d594fSAndroid Build Coastguard Worker   template<class S> friend class Handle;
130*795d594fSAndroid Build Coastguard Worker   friend class HandleScope;
131*795d594fSAndroid Build Coastguard Worker   template<class S> friend class HandleWrapper;
132*795d594fSAndroid Build Coastguard Worker   template<size_t kNumReferences> friend class StackHandleScope;
133*795d594fSAndroid Build Coastguard Worker };
134*795d594fSAndroid Build Coastguard Worker 
135*795d594fSAndroid Build Coastguard Worker // Handles that support assignment.
136*795d594fSAndroid Build Coastguard Worker template<class T>
137*795d594fSAndroid Build Coastguard Worker class MutableHandle : public Handle<T> {
138*795d594fSAndroid Build Coastguard Worker  public:
MutableHandle()139*795d594fSAndroid Build Coastguard Worker   MutableHandle() {
140*795d594fSAndroid Build Coastguard Worker   }
141*795d594fSAndroid Build Coastguard Worker 
142*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE MutableHandle(const MutableHandle<T>& handle)
143*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) = default;
144*795d594fSAndroid Build Coastguard Worker 
145*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE MutableHandle<T>& operator=(const MutableHandle<T>& handle)
146*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) = default;
147*795d594fSAndroid Build Coastguard Worker 
MutableHandle(StackReference<T> * reference)148*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE explicit MutableHandle(StackReference<T>* reference)
149*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_)
150*795d594fSAndroid Build Coastguard Worker       : Handle<T>(reference) {
151*795d594fSAndroid Build Coastguard Worker   }
152*795d594fSAndroid Build Coastguard Worker 
Assign(T * reference)153*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE T* Assign(T* reference) REQUIRES_SHARED(Locks::mutator_lock_) {
154*795d594fSAndroid Build Coastguard Worker     StackReference<mirror::Object>* ref = Handle<T>::GetReference();
155*795d594fSAndroid Build Coastguard Worker     T* old = down_cast<T*>(ref->AsMirrorPtr());
156*795d594fSAndroid Build Coastguard Worker     ref->Assign(reference);
157*795d594fSAndroid Build Coastguard Worker     return old;
158*795d594fSAndroid Build Coastguard Worker   }
159*795d594fSAndroid Build Coastguard Worker 
Assign(ObjPtr<T> reference)160*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE T* Assign(ObjPtr<T> reference) REQUIRES_SHARED(Locks::mutator_lock_) {
161*795d594fSAndroid Build Coastguard Worker     StackReference<mirror::Object>* ref = Handle<T>::GetReference();
162*795d594fSAndroid Build Coastguard Worker     T* old = down_cast<T*>(ref->AsMirrorPtr());
163*795d594fSAndroid Build Coastguard Worker     ref->Assign(reference.Ptr());
164*795d594fSAndroid Build Coastguard Worker     return old;
165*795d594fSAndroid Build Coastguard Worker   }
166*795d594fSAndroid Build Coastguard Worker 
167*795d594fSAndroid Build Coastguard Worker 
168*795d594fSAndroid Build Coastguard Worker   template<typename S>
MutableHandle(const MutableHandle<S> & handle)169*795d594fSAndroid Build Coastguard Worker   explicit MutableHandle(const MutableHandle<S>& handle) REQUIRES_SHARED(Locks::mutator_lock_)
170*795d594fSAndroid Build Coastguard Worker       : Handle<T>(handle) {
171*795d594fSAndroid Build Coastguard Worker   }
172*795d594fSAndroid Build Coastguard Worker 
173*795d594fSAndroid Build Coastguard Worker   template<typename S>
MutableHandle(StackReference<S> * reference)174*795d594fSAndroid Build Coastguard Worker   explicit MutableHandle(StackReference<S>* reference) REQUIRES_SHARED(Locks::mutator_lock_)
175*795d594fSAndroid Build Coastguard Worker       : Handle<T>(reference) {
176*795d594fSAndroid Build Coastguard Worker   }
177*795d594fSAndroid Build Coastguard Worker 
178*795d594fSAndroid Build Coastguard Worker  private:
179*795d594fSAndroid Build Coastguard Worker   friend class BuildGenericJniFrameVisitor;
180*795d594fSAndroid Build Coastguard Worker   friend class HandleScope;
181*795d594fSAndroid Build Coastguard Worker   template<class S> friend class HandleWrapper;
182*795d594fSAndroid Build Coastguard Worker   template<size_t kNumReferences> friend class StackHandleScope;
183*795d594fSAndroid Build Coastguard Worker };
184*795d594fSAndroid Build Coastguard Worker 
185*795d594fSAndroid Build Coastguard Worker // A special case of Handle that only holds references to null. Invalid when if it goes out of
186*795d594fSAndroid Build Coastguard Worker // scope. Example: Handle<T> h = ScopedNullHandle<T> will leave h being undefined.
187*795d594fSAndroid Build Coastguard Worker template<class T>
188*795d594fSAndroid Build Coastguard Worker class ScopedNullHandle : public Handle<T> {
189*795d594fSAndroid Build Coastguard Worker  public:
ScopedNullHandle()190*795d594fSAndroid Build Coastguard Worker   ScopedNullHandle() : Handle<T>(&null_ref_) {}
191*795d594fSAndroid Build Coastguard Worker 
192*795d594fSAndroid Build Coastguard Worker  private:
193*795d594fSAndroid Build Coastguard Worker   StackReference<mirror::Object> null_ref_;
194*795d594fSAndroid Build Coastguard Worker };
195*795d594fSAndroid Build Coastguard Worker 
196*795d594fSAndroid Build Coastguard Worker }  // namespace art
197*795d594fSAndroid Build Coastguard Worker 
198*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_HANDLE_H_
199