148 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright (C) 2014 The Android Open Source Project
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *      http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| #ifndef ART_RUNTIME_MIRROR_REFERENCE_H_
 | |
| #define ART_RUNTIME_MIRROR_REFERENCE_H_
 | |
| 
 | |
| #include "base/enums.h"
 | |
| #include "base/locks.h"
 | |
| #include "base/macros.h"
 | |
| #include "obj_ptr.h"
 | |
| #include "object.h"
 | |
| #include "read_barrier_option.h"
 | |
| 
 | |
| namespace art {
 | |
| 
 | |
| namespace gc {
 | |
| 
 | |
| class ReferenceProcessor;
 | |
| class ReferenceQueue;
 | |
| 
 | |
| }  // namespace gc
 | |
| 
 | |
| struct ReferenceOffsets;
 | |
| struct FinalizerReferenceOffsets;
 | |
| 
 | |
| namespace mirror {
 | |
| 
 | |
| // C++ mirror of java.lang.ref.Reference
 | |
| class MANAGED Reference : public Object {
 | |
|  public:
 | |
|   MIRROR_CLASS("Ljava/lang/ref/Reference;");
 | |
| 
 | |
|   // Size of java.lang.ref.Reference.class.
 | |
|   static uint32_t ClassSize(PointerSize pointer_size);
 | |
| 
 | |
|   // Size of an instance of java.lang.ref.Reference.
 | |
|   static constexpr uint32_t InstanceSize() {
 | |
|     return sizeof(Reference);
 | |
|   }
 | |
| 
 | |
|   static MemberOffset PendingNextOffset() {
 | |
|     return OFFSET_OF_OBJECT_MEMBER(Reference, pending_next_);
 | |
|   }
 | |
|   static MemberOffset QueueOffset() {
 | |
|     return OFFSET_OF_OBJECT_MEMBER(Reference, queue_);
 | |
|   }
 | |
|   static MemberOffset QueueNextOffset() {
 | |
|     return OFFSET_OF_OBJECT_MEMBER(Reference, queue_next_);
 | |
|   }
 | |
|   static MemberOffset ReferentOffset() {
 | |
|     return OFFSET_OF_OBJECT_MEMBER(Reference, referent_);
 | |
|   }
 | |
|   template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
 | |
|   Object* GetReferent() REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|     return GetFieldObjectVolatile<Object, kDefaultVerifyFlags, kReadBarrierOption>(
 | |
|         ReferentOffset());
 | |
|   }
 | |
|   template<bool kTransactionActive>
 | |
|   void SetReferent(ObjPtr<Object> referent) REQUIRES_SHARED(Locks::mutator_lock_);
 | |
|   template<bool kTransactionActive>
 | |
|   void ClearReferent() REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|     SetFieldObjectVolatile<kTransactionActive>(ReferentOffset(), nullptr);
 | |
|   }
 | |
| 
 | |
|   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
 | |
|   Reference* GetPendingNext() REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|     return GetFieldObject<Reference, kDefaultVerifyFlags, kReadBarrierOption>(PendingNextOffset());
 | |
|   }
 | |
| 
 | |
|   void SetPendingNext(ObjPtr<Reference> pending_next) REQUIRES_SHARED(Locks::mutator_lock_);
 | |
| 
 | |
|   // Returns true if the reference's pendingNext is null, indicating it is
 | |
|   // okay to process this reference.
 | |
|   //
 | |
|   // If pendingNext is not null, then one of the following cases holds:
 | |
|   // 1. The reference has already been enqueued to a java ReferenceQueue. In
 | |
|   // this case the referent should not be considered for reference processing
 | |
|   // ever again.
 | |
|   // 2. The reference is currently part of a list of references that may
 | |
|   // shortly be enqueued on a java ReferenceQueue. In this case the reference
 | |
|   // should not be processed again until and unless the reference has been
 | |
|   // removed from the list after having determined the reference is not ready
 | |
|   // to be enqueued on a java ReferenceQueue.
 | |
|   bool IsUnprocessed() REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|     return GetPendingNext<kWithoutReadBarrier>() == nullptr;
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   // Note: This avoids a read barrier, it should only be used by the GC.
 | |
|   HeapReference<Object>* GetReferentReferenceAddr() REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|     return GetFieldObjectReferenceAddr<kDefaultVerifyFlags>(ReferentOffset());
 | |
|   }
 | |
| 
 | |
|   // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
 | |
|   HeapReference<Reference> pending_next_;
 | |
|   HeapReference<Object> queue_;
 | |
|   HeapReference<Reference> queue_next_;
 | |
|   HeapReference<Object> referent_;  // Note this is Java volatile:
 | |
| 
 | |
|   friend struct art::ReferenceOffsets;  // for verifying offset information
 | |
|   friend class gc::ReferenceProcessor;
 | |
|   friend class gc::ReferenceQueue;
 | |
|   DISALLOW_IMPLICIT_CONSTRUCTORS(Reference);
 | |
| };
 | |
| 
 | |
| // C++ mirror of java.lang.ref.FinalizerReference
 | |
| class MANAGED FinalizerReference : public Reference {
 | |
|  public:
 | |
|   MIRROR_CLASS("Ljava/lang/ref/FinalizerReference;");
 | |
| 
 | |
|   static MemberOffset ZombieOffset() {
 | |
|     return OFFSET_OF_OBJECT_MEMBER(FinalizerReference, zombie_);
 | |
|   }
 | |
| 
 | |
|   template<bool kTransactionActive>
 | |
|   void SetZombie(ObjPtr<Object> zombie) REQUIRES_SHARED(Locks::mutator_lock_);
 | |
| 
 | |
|   Object* GetZombie() REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|     return GetFieldObjectVolatile<Object>(ZombieOffset());
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   HeapReference<FinalizerReference> next_;
 | |
|   HeapReference<FinalizerReference> prev_;
 | |
|   HeapReference<Object> zombie_;
 | |
| 
 | |
|   friend struct art::FinalizerReferenceOffsets;  // for verifying offset information
 | |
|   DISALLOW_IMPLICIT_CONSTRUCTORS(FinalizerReference);
 | |
| };
 | |
| 
 | |
| }  // namespace mirror
 | |
| }  // namespace art
 | |
| 
 | |
| #endif  // ART_RUNTIME_MIRROR_REFERENCE_H_
 |