Home | History | Annotate | Download | only in runtime
      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 
     26 namespace art {
     27 
     28 class Thread;
     29 
     30 template<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.
     36 template<class T>
     37 class 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.
    104 template<class T>
    105 class 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.
    151 template<class T>
    152 class 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