• 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_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.
InstanceSize()50   static constexpr uint32_t InstanceSize() {
51     return sizeof(Reference);
52   }
53 
PendingNextOffset()54   static MemberOffset PendingNextOffset() {
55     return OFFSET_OF_OBJECT_MEMBER(Reference, pending_next_);
56   }
QueueOffset()57   static MemberOffset QueueOffset() {
58     return OFFSET_OF_OBJECT_MEMBER(Reference, queue_);
59   }
QueueNextOffset()60   static MemberOffset QueueNextOffset() {
61     return OFFSET_OF_OBJECT_MEMBER(Reference, queue_next_);
62   }
ReferentOffset()63   static MemberOffset ReferentOffset() {
64     return OFFSET_OF_OBJECT_MEMBER(Reference, referent_);
65   }
66   template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
GetReferent()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>
ClearReferent()74   void ClearReferent() REQUIRES_SHARED(Locks::mutator_lock_) {
75     SetFieldObjectVolatile<kTransactionActive>(ReferentOffset(), nullptr);
76   }
77 
78   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
GetPendingNext()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.
IsUnprocessed()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.
GetReferentReferenceAddr()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:
ZombieOffset()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 
GetZombie()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