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