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