• 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