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