18fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier/*
28fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier * Copyright (C) 2014 The Android Open Source Project
38fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier *
48fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier * Licensed under the Apache License, Version 2.0 (the "License");
58fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier * you may not use this file except in compliance with the License.
68fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier * You may obtain a copy of the License at
78fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier *
88fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier *      http://www.apache.org/licenses/LICENSE-2.0
98fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier *
108fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier * Unless required by applicable law or agreed to in writing, software
118fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier * distributed under the License is distributed on an "AS IS" BASIS,
128fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier * See the License for the specific language governing permissions and
148fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier * limitations under the License.
158fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier */
168fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
178fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier#ifndef ART_RUNTIME_MIRROR_REFERENCE_H_
188fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier#define ART_RUNTIME_MIRROR_REFERENCE_H_
198fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
204ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih#include "class.h"
2194f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi#include "gc_root.h"
228fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier#include "object.h"
234ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih#include "object_callbacks.h"
2494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi#include "read_barrier_option.h"
254ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih#include "thread.h"
268fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
278fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartiernamespace art {
288fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
29308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartiernamespace gc {
30308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier
31308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartierclass ReferenceProcessor;
32308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartierclass ReferenceQueue;
33308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier
34308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier}  // namespace gc
35308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier
368fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierstruct ReferenceOffsets;
378fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierstruct FinalizerReferenceOffsets;
388fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
398fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartiernamespace mirror {
408fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
418fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier// C++ mirror of java.lang.ref.Reference
428fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierclass MANAGED Reference : public Object {
438fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier public:
444ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  // Size of java.lang.ref.Reference.class.
454ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  static uint32_t ClassSize();
464ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih
474ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  // Size of an instance of java.lang.ref.Reference.
484ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  static constexpr uint32_t InstanceSize() {
494ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih    return sizeof(Reference);
504ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  }
514ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih
528fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  static MemberOffset PendingNextOffset() {
538fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier    return OFFSET_OF_OBJECT_MEMBER(Reference, pending_next_);
548fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  }
558fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  static MemberOffset QueueOffset() {
568fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier    return OFFSET_OF_OBJECT_MEMBER(Reference, queue_);
578fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  }
588fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  static MemberOffset QueueNextOffset() {
598fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier    return OFFSET_OF_OBJECT_MEMBER(Reference, queue_next_);
608fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  }
618fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  static MemberOffset ReferentOffset() {
628fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier    return OFFSET_OF_OBJECT_MEMBER(Reference, referent_);
638fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  }
64bfff21aaa05d4fce39481cf7899f7639eb7fd66dHiroshi Yamauchi  template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
658fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  Object* GetReferent() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
66bfff21aaa05d4fce39481cf7899f7639eb7fd66dHiroshi Yamauchi    return GetFieldObjectVolatile<Object, kDefaultVerifyFlags, kReadBarrierOption>(
67bfff21aaa05d4fce39481cf7899f7639eb7fd66dHiroshi Yamauchi        ReferentOffset());
688fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  }
698fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  template<bool kTransactionActive>
708fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  void SetReferent(Object* referent) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
71b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    SetFieldObjectVolatile<kTransactionActive>(ReferentOffset(), referent);
728fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  }
738fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  template<bool kTransactionActive>
748fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  void ClearReferent() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
75b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    SetFieldObjectVolatile<kTransactionActive>(ReferentOffset(), nullptr);
768fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  }
778fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  // Volatile read/write is not necessary since the java pending next is only accessed from
788fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  // the java threads for cleared references. Once these cleared references have a null referent,
798fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  // we never end up reading their pending next from the GC again.
808fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  Reference* GetPendingNext() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
81b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    return GetFieldObject<Reference>(PendingNextOffset());
828fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  }
838fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  template<bool kTransactionActive>
848fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  void SetPendingNext(Reference* pending_next) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
85b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    SetFieldObject<kTransactionActive>(PendingNextOffset(), pending_next);
868fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  }
878fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
888fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  bool IsEnqueued() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
898fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier    // Since the references are stored as cyclic lists it means that once enqueued, the pending
908fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier    // next is always non-null.
918fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier    return GetPendingNext() != nullptr;
928fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  }
938fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
948fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  bool IsEnqueuable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
958fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
964ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
974ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  static Class* GetJavaLangRefReference() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
9894f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi    DCHECK(!java_lang_ref_Reference_.IsNull());
9994f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi    return java_lang_ref_Reference_.Read<kReadBarrierOption>();
1004ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  }
1014ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  static void SetClass(Class* klass);
1024ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  static void ResetClass(void);
1034ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  static void VisitRoots(RootCallback* callback, void* arg);
1044ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih
1058fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier private:
106308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier  // Note: This avoids a read barrier, it should only be used by the GC.
107308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier  HeapReference<Object>* GetReferentReferenceAddr() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
108308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier    return GetFieldObjectReferenceAddr<kDefaultVerifyFlags>(ReferentOffset());
109308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier  }
110308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier
1118fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
1128fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  HeapReference<Reference> pending_next_;  // Note this is Java volatile:
1138fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  HeapReference<Object> queue_;  // Note this is Java volatile:
1148fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  HeapReference<Reference> queue_next_;  // Note this is Java volatile:
1158fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  HeapReference<Object> referent_;  // Note this is Java volatile:
1168fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
11794f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi  static GcRoot<Class> java_lang_ref_Reference_;
1184ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih
1198fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  friend struct art::ReferenceOffsets;  // for verifying offset information
120308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier  friend class gc::ReferenceProcessor;
121308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier  friend class gc::ReferenceQueue;
1228fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  DISALLOW_IMPLICIT_CONSTRUCTORS(Reference);
1238fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier};
1248fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
1258fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier// C++ mirror of java.lang.ref.FinalizerReference
1268fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierclass MANAGED FinalizerReference : public Reference {
1278fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier public:
1288fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  static MemberOffset ZombieOffset() {
1298fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier    return OFFSET_OF_OBJECT_MEMBER(FinalizerReference, zombie_);
1308fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  }
1318fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
1328fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  template<bool kTransactionActive>
1338fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  void SetZombie(Object* zombie) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
134b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    return SetFieldObjectVolatile<kTransactionActive>(ZombieOffset(), zombie);
1358fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  }
1368fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  Object* GetZombie() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
137b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    return GetFieldObjectVolatile<Object>(ZombieOffset());
1388fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  }
1398fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
1408fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier private:
1418fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  HeapReference<FinalizerReference> next_;
1428fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  HeapReference<FinalizerReference> prev_;
1438fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  HeapReference<Object> zombie_;
1448fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
1458fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  friend struct art::FinalizerReferenceOffsets;  // for verifying offset information
1468fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  DISALLOW_IMPLICIT_CONSTRUCTORS(FinalizerReference);
1478fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier};
1488fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
1498fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier}  // namespace mirror
1508fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier}  // namespace art
1518fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
1528fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier#endif  // ART_RUNTIME_MIRROR_REFERENCE_H_
153