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/value_object.h"
21 #include "reflective_reference.h"
22 
23 namespace art {
24 
25 // This is a holder similar to Handle<T> that is used to hold reflective references to ArtField and
26 // ArtMethod structures. A reflective reference is one that must be updated if the underlying class
27 // or instances are replaced due to structural redefinition or some other process. In general these
28 // don't need to be used. It's only when it's important that a reference to a field not become
29 // obsolete and it needs to be held over a suspend point that this should be used.
30 template <typename T>
31 class ReflectiveHandle : public ValueObject {
32  public:
33   static_assert(std::is_same_v<T, ArtField> || std::is_same_v<T, ArtMethod>,
34                 "Expected ArtField or ArtMethod");
35 
ReflectiveHandle()36   ReflectiveHandle() : reference_(nullptr) {}
37 
38   ALWAYS_INLINE ReflectiveHandle(const ReflectiveHandle<T>& handle) = default;
39   ALWAYS_INLINE ReflectiveHandle<T>& operator=(const ReflectiveHandle<T>& handle) = default;
40 
ReflectiveHandle(ReflectiveReference<T> * reference)41   ALWAYS_INLINE explicit ReflectiveHandle(ReflectiveReference<T>* reference)
42       : reference_(reference) {}
43 
REQUIRES_SHARED(Locks::mutator_lock_)44   ALWAYS_INLINE T& operator*() const REQUIRES_SHARED(Locks::mutator_lock_) {
45     return *Get();
46   }
47 
48   ALWAYS_INLINE T* operator->() const REQUIRES_SHARED(Locks::mutator_lock_) {
49     return Get();
50   }
51 
Get()52   ALWAYS_INLINE T* Get() const REQUIRES_SHARED(Locks::mutator_lock_) {
53     return reference_->Ptr();
54   }
55 
IsNull()56   ALWAYS_INLINE bool IsNull() const {
57     // It's safe to null-check it without a read barrier.
58     return reference_->IsNull();
59   }
60 
61   ALWAYS_INLINE bool operator!=(std::nullptr_t) const REQUIRES_SHARED(Locks::mutator_lock_) {
62     return !IsNull();
63   }
64 
65   ALWAYS_INLINE bool operator==(std::nullptr_t) const REQUIRES_SHARED(Locks::mutator_lock_) {
66     return IsNull();
67   }
68 
69  protected:
70   ReflectiveReference<T>* reference_;
71 
72  private:
73   friend class BaseReflectiveHandleScope;
74   template <size_t kNumFieldReferences, size_t kNumMethodReferences>
75   friend class StackReflectiveHandleScope;
76 };
77 
78 // Handles that support assignment.
79 template <typename T>
80 class MutableReflectiveHandle : public ReflectiveHandle<T> {
81  public:
MutableReflectiveHandle()82   MutableReflectiveHandle() {}
83 
84   ALWAYS_INLINE MutableReflectiveHandle(const MutableReflectiveHandle<T>& handle)
85       REQUIRES_SHARED(Locks::mutator_lock_) = default;
86 
87   ALWAYS_INLINE MutableReflectiveHandle<T>& operator=(const MutableReflectiveHandle<T>& handle)
88       REQUIRES_SHARED(Locks::mutator_lock_) = default;
89 
MutableReflectiveHandle(ReflectiveReference<T> * reference)90   ALWAYS_INLINE explicit MutableReflectiveHandle(ReflectiveReference<T>* reference)
91       REQUIRES_SHARED(Locks::mutator_lock_)
92       : ReflectiveHandle<T>(reference) {}
93 
Assign(T * reference)94   ALWAYS_INLINE T* Assign(T* reference) REQUIRES_SHARED(Locks::mutator_lock_) {
95     ReflectiveReference<T>* ref = ReflectiveHandle<T>::reference_;
96     T* old = ref->Ptr();
97     ref->Assign(reference);
98     return old;
99   }
100 
101  private:
102   friend class BaseReflectiveHandleScope;
103   template <size_t kNumFieldReferences, size_t kNumMethodReferences>
104   friend class StackReflectiveHandleScope;
105 };
106 
107 template<typename T>
108 class ReflectiveHandleWrapper : public MutableReflectiveHandle<T> {
109  public:
ReflectiveHandleWrapper(T ** obj,const MutableReflectiveHandle<T> & handle)110   ReflectiveHandleWrapper(T** obj, const MutableReflectiveHandle<T>& handle)
111      : MutableReflectiveHandle<T>(handle), obj_(obj) {
112   }
113 
114   ReflectiveHandleWrapper(const ReflectiveHandleWrapper&) = default;
115 
~ReflectiveHandleWrapper()116   ~ReflectiveHandleWrapper() {
117     *obj_ = MutableReflectiveHandle<T>::Get();
118   }
119 
120  private:
121   T** const obj_;
122 };
123 
124 }  // namespace art
125 
126 #endif  // ART_RUNTIME_REFLECTIVE_HANDLE_H_
127