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