blob: 15e0145bafae11e3d0b771beec67c932f78f0313 [file] [log] [blame]
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -07001/*
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
Christopher Ferrisd4415e82014-07-11 06:44:39 +000020#include "class.h"
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -070021#include "object.h"
Christopher Ferrisd4415e82014-07-11 06:44:39 +000022#include "object_callbacks.h"
23#include "thread.h"
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -070024
25namespace art {
26
Mathieu Chartier308351a2014-06-15 12:39:02 -070027namespace gc {
28
29class ReferenceProcessor;
30class ReferenceQueue;
31
32} // namespace gc
33
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -070034struct ReferenceOffsets;
Christopher Ferrisd4415e82014-07-11 06:44:39 +000035struct ReferenceClassOffsets;
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -070036struct FinalizerReferenceOffsets;
37
38namespace mirror {
Christopher Ferrisd4415e82014-07-11 06:44:39 +000039class ReferenceClass;
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -070040
41// C++ mirror of java.lang.ref.Reference
42class MANAGED Reference : public Object {
43 public:
44 static MemberOffset PendingNextOffset() {
45 return OFFSET_OF_OBJECT_MEMBER(Reference, pending_next_);
46 }
47 static MemberOffset QueueOffset() {
48 return OFFSET_OF_OBJECT_MEMBER(Reference, queue_);
49 }
50 static MemberOffset QueueNextOffset() {
51 return OFFSET_OF_OBJECT_MEMBER(Reference, queue_next_);
52 }
53 static MemberOffset ReferentOffset() {
54 return OFFSET_OF_OBJECT_MEMBER(Reference, referent_);
55 }
Hiroshi Yamauchibfff21a2014-05-09 12:21:15 -070056 template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -070057 Object* GetReferent() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Hiroshi Yamauchibfff21a2014-05-09 12:21:15 -070058 return GetFieldObjectVolatile<Object, kDefaultVerifyFlags, kReadBarrierOption>(
59 ReferentOffset());
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -070060 }
61 template<bool kTransactionActive>
62 void SetReferent(Object* referent) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070063 SetFieldObjectVolatile<kTransactionActive>(ReferentOffset(), referent);
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -070064 }
65 template<bool kTransactionActive>
66 void ClearReferent() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070067 SetFieldObjectVolatile<kTransactionActive>(ReferentOffset(), nullptr);
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -070068 }
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -070069 // Volatile read/write is not necessary since the java pending next is only accessed from
70 // the java threads for cleared references. Once these cleared references have a null referent,
71 // we never end up reading their pending next from the GC again.
72 Reference* GetPendingNext() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070073 return GetFieldObject<Reference>(PendingNextOffset());
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -070074 }
75 template<bool kTransactionActive>
76 void SetPendingNext(Reference* pending_next) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070077 SetFieldObject<kTransactionActive>(PendingNextOffset(), pending_next);
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -070078 }
79
80 bool IsEnqueued() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
81 // Since the references are stored as cyclic lists it means that once enqueued, the pending
82 // next is always non-null.
83 return GetPendingNext() != nullptr;
84 }
85
86 bool IsEnqueuable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
87
Christopher Ferrisd4415e82014-07-11 06:44:39 +000088 static ReferenceClass* GetJavaLangRefReference() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
89 CHECK(java_lang_ref_Reference_ != nullptr);
90 return ReadBarrier::BarrierForRoot<mirror::ReferenceClass, kWithReadBarrier>(
91 &java_lang_ref_Reference_);
92 }
93 static void SetClass(ReferenceClass* klass);
94 static void ResetClass(void);
95 static void VisitRoots(RootCallback* callback, void* arg);
96
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -070097 private:
Mathieu Chartier308351a2014-06-15 12:39:02 -070098 // Note: This avoids a read barrier, it should only be used by the GC.
99 HeapReference<Object>* GetReferentReferenceAddr() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
100 return GetFieldObjectReferenceAddr<kDefaultVerifyFlags>(ReferentOffset());
101 }
102
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -0700103 // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
104 HeapReference<Reference> pending_next_; // Note this is Java volatile:
105 HeapReference<Object> queue_; // Note this is Java volatile:
106 HeapReference<Reference> queue_next_; // Note this is Java volatile:
107 HeapReference<Object> referent_; // Note this is Java volatile:
108
Christopher Ferrisd4415e82014-07-11 06:44:39 +0000109 static ReferenceClass* java_lang_ref_Reference_;
110
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -0700111 friend struct art::ReferenceOffsets; // for verifying offset information
Mathieu Chartier308351a2014-06-15 12:39:02 -0700112 friend class gc::ReferenceProcessor;
113 friend class gc::ReferenceQueue;
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -0700114 DISALLOW_IMPLICIT_CONSTRUCTORS(Reference);
115};
116
Christopher Ferrisd4415e82014-07-11 06:44:39 +0000117// Tightly coupled with the ReferenceProcessor to provide switch for slow/fast path. Consistency
118// is maintained by ReferenceProcessor.
119class MANAGED ReferenceClass : public Class {
120 public:
121 static MemberOffset DisableIntrinsicOffset() {
122 return OFFSET_OF_OBJECT_MEMBER(ReferenceClass, disable_intrinsic_);
123 }
124 static MemberOffset SlowPathEnabledOffset() {
125 return OFFSET_OF_OBJECT_MEMBER(ReferenceClass, slow_path_enabled_);
126 }
127
128 void Init() {
129 disable_intrinsic_ = false;
130 slow_path_enabled_ = false;
131 }
132
133 bool GetSlowPathEnabled() const {
134 return slow_path_enabled_;
135 }
136 void SetSlowPathEnabled(bool enabled) {
137 slow_path_enabled_ = enabled;
138 }
139
140 private:
141 int32_t disable_intrinsic_;
142 int32_t slow_path_enabled_;
143 // allows runtime to safely enable/disable intrinsics fast path for benchmarking
144
145 friend struct art::ReferenceClassOffsets; // for verifying offset information
146 DISALLOW_IMPLICIT_CONSTRUCTORS(ReferenceClass);
147};
148
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -0700149// C++ mirror of java.lang.ref.FinalizerReference
150class MANAGED FinalizerReference : public Reference {
151 public:
152 static MemberOffset ZombieOffset() {
153 return OFFSET_OF_OBJECT_MEMBER(FinalizerReference, zombie_);
154 }
155
156 template<bool kTransactionActive>
157 void SetZombie(Object* zombie) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700158 return SetFieldObjectVolatile<kTransactionActive>(ZombieOffset(), zombie);
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -0700159 }
160 Object* GetZombie() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700161 return GetFieldObjectVolatile<Object>(ZombieOffset());
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -0700162 }
163
164 private:
165 HeapReference<FinalizerReference> next_;
166 HeapReference<FinalizerReference> prev_;
167 HeapReference<Object> zombie_;
168
169 friend struct art::FinalizerReferenceOffsets; // for verifying offset information
170 DISALLOW_IMPLICIT_CONSTRUCTORS(FinalizerReference);
171};
172
173} // namespace mirror
174} // namespace art
175
176#endif // ART_RUNTIME_MIRROR_REFERENCE_H_