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