1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_REFLECTIVE_HANDLE_H_ 18 #define ART_RUNTIME_REFLECTIVE_HANDLE_H_ 19 20 #include "base/macros.h" 21 #include "base/value_object.h" 22 #include "reflective_reference.h" 23 24 namespace art HIDDEN { 25 26 // This is a holder similar to Handle<T> that is used to hold reflective references to ArtField and 27 // ArtMethod structures. A reflective reference is one that must be updated if the underlying class 28 // or instances are replaced due to structural redefinition or some other process. In general these 29 // don't need to be used. It's only when it's important that a reference to a field not become 30 // obsolete and it needs to be held over a suspend point that this should be used. 31 template <typename T> 32 class ReflectiveHandle : public ValueObject { 33 public: 34 static_assert(std::is_same_v<T, ArtField> || std::is_same_v<T, ArtMethod>, 35 "Expected ArtField or ArtMethod"); 36 ReflectiveHandle()37 ReflectiveHandle() : reference_(nullptr) {} 38 39 ALWAYS_INLINE ReflectiveHandle(const ReflectiveHandle<T>& handle) = default; 40 ALWAYS_INLINE ReflectiveHandle<T>& operator=(const ReflectiveHandle<T>& handle) = default; 41 ReflectiveHandle(ReflectiveReference<T> * reference)42 ALWAYS_INLINE explicit ReflectiveHandle(ReflectiveReference<T>* reference) 43 : reference_(reference) {} 44 REQUIRES_SHARED(Locks::mutator_lock_)45 ALWAYS_INLINE T& operator*() const REQUIRES_SHARED(Locks::mutator_lock_) { 46 return *Get(); 47 } 48 49 ALWAYS_INLINE T* operator->() const REQUIRES_SHARED(Locks::mutator_lock_) { 50 return Get(); 51 } 52 Get()53 ALWAYS_INLINE T* Get() const REQUIRES_SHARED(Locks::mutator_lock_) { 54 return reference_->Ptr(); 55 } 56 IsNull()57 ALWAYS_INLINE bool IsNull() const { 58 // It's safe to null-check it without a read barrier. 59 return reference_->IsNull(); 60 } 61 62 ALWAYS_INLINE bool operator!=(std::nullptr_t) const REQUIRES_SHARED(Locks::mutator_lock_) { 63 return !IsNull(); 64 } 65 66 ALWAYS_INLINE bool operator==(std::nullptr_t) const REQUIRES_SHARED(Locks::mutator_lock_) { 67 return IsNull(); 68 } 69 70 protected: 71 ReflectiveReference<T>* reference_; 72 73 private: 74 friend class BaseReflectiveHandleScope; 75 template <size_t kNumFieldReferences, size_t kNumMethodReferences> 76 friend class StackReflectiveHandleScope; 77 }; 78 79 // Handles that support assignment. 80 template <typename T> 81 class MutableReflectiveHandle : public ReflectiveHandle<T> { 82 public: MutableReflectiveHandle()83 MutableReflectiveHandle() {} 84 85 ALWAYS_INLINE MutableReflectiveHandle(const MutableReflectiveHandle<T>& handle) = default; 86 87 ALWAYS_INLINE MutableReflectiveHandle<T>& operator=(const MutableReflectiveHandle<T>& handle) 88 = default; 89 MutableReflectiveHandle(ReflectiveReference<T> * reference)90 ALWAYS_INLINE explicit MutableReflectiveHandle(ReflectiveReference<T>* reference) 91 : ReflectiveHandle<T>(reference) {} 92 Assign(T * reference)93 ALWAYS_INLINE T* Assign(T* reference) REQUIRES_SHARED(Locks::mutator_lock_) { 94 ReflectiveReference<T>* ref = ReflectiveHandle<T>::reference_; 95 T* old = ref->Ptr(); 96 ref->Assign(reference); 97 return old; 98 } 99 100 private: 101 friend class BaseReflectiveHandleScope; 102 template <size_t kNumFieldReferences, size_t kNumMethodReferences> 103 friend class StackReflectiveHandleScope; 104 }; 105 106 template<typename T> 107 class ReflectiveHandleWrapper : public MutableReflectiveHandle<T> { 108 public: ReflectiveHandleWrapper(T ** obj,const MutableReflectiveHandle<T> & handle)109 ReflectiveHandleWrapper(T** obj, const MutableReflectiveHandle<T>& handle) 110 : MutableReflectiveHandle<T>(handle), obj_(obj) { 111 } 112 113 ReflectiveHandleWrapper(const ReflectiveHandleWrapper&) = default; 114 ~ReflectiveHandleWrapper()115 ~ReflectiveHandleWrapper() { 116 *obj_ = MutableReflectiveHandle<T>::Get(); 117 } 118 119 private: 120 T** const obj_; 121 }; 122 123 } // namespace art 124 125 #endif // ART_RUNTIME_REFLECTIVE_HANDLE_H_ 126