• 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_HANDLE_H_
18 #define ART_RUNTIME_HANDLE_H_
19 
20 #include <android-base/logging.h>
21 
22 #include "base/casts.h"
23 #include "base/macros.h"
24 #include "base/mutex.h"
25 #include "base/value_object.h"
26 #include "jni.h"
27 #include "obj_ptr.h"
28 #include "stack_reference.h"
29 
30 namespace art {
31 
32 class Thread;
33 
34 template<class T> class Handle;
35 
36 // Handles are memory locations that contain GC roots. As the mirror::Object*s within a handle are
37 // GC visible then the GC may move the references within them, something that couldn't be done with
38 // a wrap pointer. Handles are generally allocated within HandleScopes. Handle is a super-class
39 // of MutableHandle and doesn't support assignment operations.
40 template<class T>
41 class Handle : public ValueObject {
42  public:
Handle()43   Handle() : reference_(nullptr) {
44   }
45 
46   ALWAYS_INLINE Handle(const Handle<T>& handle) = default;
47 
48   ALWAYS_INLINE Handle<T>& operator=(const Handle<T>& handle) = default;
49 
Handle(StackReference<T> * reference)50   ALWAYS_INLINE explicit Handle(StackReference<T>* reference) : reference_(reference) {
51   }
52 
REQUIRES_SHARED(Locks::mutator_lock_)53   ALWAYS_INLINE T& operator*() const REQUIRES_SHARED(Locks::mutator_lock_) {
54     return *Get();
55   }
56 
57   ALWAYS_INLINE T* operator->() const REQUIRES_SHARED(Locks::mutator_lock_) {
58     return Get();
59   }
60 
Get()61   ALWAYS_INLINE T* Get() const REQUIRES_SHARED(Locks::mutator_lock_) {
62     return down_cast<T*>(reference_->AsMirrorPtr());
63   }
64 
IsNull()65   ALWAYS_INLINE bool IsNull() const REQUIRES_SHARED(Locks::mutator_lock_) {
66     return Get() == nullptr;
67   }
68 
ToJObject()69   ALWAYS_INLINE jobject ToJObject() const REQUIRES_SHARED(Locks::mutator_lock_) {
70     if (UNLIKELY(reference_->AsMirrorPtr() == nullptr)) {
71       // Special case so that we work with null handles.
72       return nullptr;
73     }
74     return reinterpret_cast<jobject>(reference_);
75   }
76 
GetReference()77   ALWAYS_INLINE StackReference<mirror::Object>* GetReference() {
78     return reference_;
79   }
80 
GetReference()81   ALWAYS_INLINE const StackReference<mirror::Object>* GetReference() const {
82     return reference_;
83   }
84 
85   ALWAYS_INLINE bool operator!=(std::nullptr_t) const REQUIRES_SHARED(Locks::mutator_lock_) {
86     return !IsNull();
87   }
88 
89   ALWAYS_INLINE bool operator==(std::nullptr_t) const REQUIRES_SHARED(Locks::mutator_lock_) {
90     return IsNull();
91   }
92 
93  protected:
94   template<typename S>
Handle(StackReference<S> * reference)95   explicit Handle(StackReference<S>* reference)
96       : reference_(reference) {
97   }
98   template<typename S>
Handle(const Handle<S> & handle)99   explicit Handle(const Handle<S>& handle)
100       : reference_(handle.reference_) {
101   }
102 
103   StackReference<mirror::Object>* reference_;
104 
105  private:
106   friend class BuildGenericJniFrameVisitor;
107   template<class S> friend class Handle;
108   friend class HandleScope;
109   template<class S> friend class HandleWrapper;
110   template<size_t kNumReferences> friend class StackHandleScope;
111 };
112 
113 // Handles that support assignment.
114 template<class T>
115 class MutableHandle : public Handle<T> {
116  public:
MutableHandle()117   MutableHandle() {
118   }
119 
120   ALWAYS_INLINE MutableHandle(const MutableHandle<T>& handle)
121       REQUIRES_SHARED(Locks::mutator_lock_) = default;
122 
123   ALWAYS_INLINE MutableHandle<T>& operator=(const MutableHandle<T>& handle)
124       REQUIRES_SHARED(Locks::mutator_lock_) = default;
125 
MutableHandle(StackReference<T> * reference)126   ALWAYS_INLINE explicit MutableHandle(StackReference<T>* reference)
127       REQUIRES_SHARED(Locks::mutator_lock_)
128       : Handle<T>(reference) {
129   }
130 
Assign(T * reference)131   ALWAYS_INLINE T* Assign(T* reference) REQUIRES_SHARED(Locks::mutator_lock_) {
132     StackReference<mirror::Object>* ref = Handle<T>::GetReference();
133     T* old = down_cast<T*>(ref->AsMirrorPtr());
134     ref->Assign(reference);
135     return old;
136   }
137 
Assign(ObjPtr<T> reference)138   ALWAYS_INLINE T* Assign(ObjPtr<T> reference) REQUIRES_SHARED(Locks::mutator_lock_) {
139     StackReference<mirror::Object>* ref = Handle<T>::GetReference();
140     T* old = down_cast<T*>(ref->AsMirrorPtr());
141     ref->Assign(reference.Ptr());
142     return old;
143   }
144 
145 
146   template<typename S>
MutableHandle(const MutableHandle<S> & handle)147   explicit MutableHandle(const MutableHandle<S>& handle) REQUIRES_SHARED(Locks::mutator_lock_)
148       : Handle<T>(handle) {
149   }
150 
151   template<typename S>
MutableHandle(StackReference<S> * reference)152   explicit MutableHandle(StackReference<S>* reference) REQUIRES_SHARED(Locks::mutator_lock_)
153       : Handle<T>(reference) {
154   }
155 
156  private:
157   friend class BuildGenericJniFrameVisitor;
158   friend class HandleScope;
159   template<class S> friend class HandleWrapper;
160   template<size_t kNumReferences> friend class StackHandleScope;
161 };
162 
163 // A special case of Handle that only holds references to null. Invalid when if it goes out of
164 // scope. Example: Handle<T> h = ScopedNullHandle<T> will leave h being undefined.
165 template<class T>
166 class ScopedNullHandle : public Handle<T> {
167  public:
ScopedNullHandle()168   ScopedNullHandle() : Handle<T>(&null_ref_) {}
169 
170  private:
171   StackReference<mirror::Object> null_ref_;
172 };
173 
174 }  // namespace art
175 
176 #endif  // ART_RUNTIME_HANDLE_H_
177