Home | History | Annotate | Download | only in mirror
      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_MIRROR_REFERENCE_H_
     18 #define ART_RUNTIME_MIRROR_REFERENCE_H_
     19 
     20 #include "class.h"
     21 #include "gc_root.h"
     22 #include "object.h"
     23 #include "object_callbacks.h"
     24 #include "read_barrier_option.h"
     25 #include "runtime.h"
     26 #include "thread.h"
     27 
     28 namespace art {
     29 
     30 namespace gc {
     31 
     32 class ReferenceProcessor;
     33 class ReferenceQueue;
     34 
     35 }  // namespace gc
     36 
     37 struct ReferenceOffsets;
     38 struct FinalizerReferenceOffsets;
     39 
     40 namespace mirror {
     41 
     42 // C++ mirror of java.lang.ref.Reference
     43 class MANAGED Reference : public Object {
     44  public:
     45   // Size of java.lang.ref.Reference.class.
     46   static uint32_t ClassSize(size_t pointer_size);
     47 
     48   // Size of an instance of java.lang.ref.Reference.
     49   static constexpr uint32_t InstanceSize() {
     50     return sizeof(Reference);
     51   }
     52 
     53   static MemberOffset PendingNextOffset() {
     54     return OFFSET_OF_OBJECT_MEMBER(Reference, pending_next_);
     55   }
     56   static MemberOffset QueueOffset() {
     57     return OFFSET_OF_OBJECT_MEMBER(Reference, queue_);
     58   }
     59   static MemberOffset QueueNextOffset() {
     60     return OFFSET_OF_OBJECT_MEMBER(Reference, queue_next_);
     61   }
     62   static MemberOffset ReferentOffset() {
     63     return OFFSET_OF_OBJECT_MEMBER(Reference, referent_);
     64   }
     65   template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
     66   Object* GetReferent() SHARED_REQUIRES(Locks::mutator_lock_) {
     67     return GetFieldObjectVolatile<Object, kDefaultVerifyFlags, kReadBarrierOption>(
     68         ReferentOffset());
     69   }
     70   template<bool kTransactionActive>
     71   void SetReferent(Object* referent) SHARED_REQUIRES(Locks::mutator_lock_) {
     72     SetFieldObjectVolatile<kTransactionActive>(ReferentOffset(), referent);
     73   }
     74   template<bool kTransactionActive>
     75   void ClearReferent() SHARED_REQUIRES(Locks::mutator_lock_) {
     76     SetFieldObjectVolatile<kTransactionActive>(ReferentOffset(), nullptr);
     77   }
     78 
     79   Reference* GetPendingNext() SHARED_REQUIRES(Locks::mutator_lock_) {
     80     return GetFieldObject<Reference>(PendingNextOffset());
     81   }
     82 
     83   void SetPendingNext(Reference* pending_next)
     84       SHARED_REQUIRES(Locks::mutator_lock_) {
     85     if (Runtime::Current()->IsActiveTransaction()) {
     86       SetFieldObject<true>(PendingNextOffset(), pending_next);
     87     } else {
     88       SetFieldObject<false>(PendingNextOffset(), pending_next);
     89     }
     90   }
     91 
     92   // Returns true if the reference's pendingNext is null, indicating it is
     93   // okay to process this reference.
     94   //
     95   // If pendingNext is not null, then one of the following cases holds:
     96   // 1. The reference has already been enqueued to a java ReferenceQueue. In
     97   // this case the referent should not be considered for reference processing
     98   // ever again.
     99   // 2. The reference is currently part of a list of references that may
    100   // shortly be enqueued on a java ReferenceQueue. In this case the reference
    101   // should not be processed again until and unless the reference has been
    102   // removed from the list after having determined the reference is not ready
    103   // to be enqueued on a java ReferenceQueue.
    104   bool IsUnprocessed() SHARED_REQUIRES(Locks::mutator_lock_) {
    105     return GetPendingNext() == nullptr;
    106   }
    107 
    108   template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
    109   static Class* GetJavaLangRefReference() SHARED_REQUIRES(Locks::mutator_lock_) {
    110     DCHECK(!java_lang_ref_Reference_.IsNull());
    111     return java_lang_ref_Reference_.Read<kReadBarrierOption>();
    112   }
    113   static void SetClass(Class* klass);
    114   static void ResetClass();
    115   static void VisitRoots(RootVisitor* visitor) SHARED_REQUIRES(Locks::mutator_lock_);
    116 
    117  private:
    118   // Note: This avoids a read barrier, it should only be used by the GC.
    119   HeapReference<Object>* GetReferentReferenceAddr() SHARED_REQUIRES(Locks::mutator_lock_) {
    120     return GetFieldObjectReferenceAddr<kDefaultVerifyFlags>(ReferentOffset());
    121   }
    122 
    123   // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
    124   HeapReference<Reference> pending_next_;
    125   HeapReference<Object> queue_;
    126   HeapReference<Reference> queue_next_;
    127   HeapReference<Object> referent_;  // Note this is Java volatile:
    128 
    129   static GcRoot<Class> java_lang_ref_Reference_;
    130 
    131   friend struct art::ReferenceOffsets;  // for verifying offset information
    132   friend class gc::ReferenceProcessor;
    133   friend class gc::ReferenceQueue;
    134   DISALLOW_IMPLICIT_CONSTRUCTORS(Reference);
    135 };
    136 
    137 // C++ mirror of java.lang.ref.FinalizerReference
    138 class MANAGED FinalizerReference : public Reference {
    139  public:
    140   static MemberOffset ZombieOffset() {
    141     return OFFSET_OF_OBJECT_MEMBER(FinalizerReference, zombie_);
    142   }
    143 
    144   template<bool kTransactionActive>
    145   void SetZombie(Object* zombie) SHARED_REQUIRES(Locks::mutator_lock_) {
    146     return SetFieldObjectVolatile<kTransactionActive>(ZombieOffset(), zombie);
    147   }
    148   Object* GetZombie() SHARED_REQUIRES(Locks::mutator_lock_) {
    149     return GetFieldObjectVolatile<Object>(ZombieOffset());
    150   }
    151 
    152  private:
    153   HeapReference<FinalizerReference> next_;
    154   HeapReference<FinalizerReference> prev_;
    155   HeapReference<Object> zombie_;
    156 
    157   friend struct art::FinalizerReferenceOffsets;  // for verifying offset information
    158   DISALLOW_IMPLICIT_CONSTRUCTORS(FinalizerReference);
    159 };
    160 
    161 }  // namespace mirror
    162 }  // namespace art
    163 
    164 #endif  // ART_RUNTIME_MIRROR_REFERENCE_H_
    165