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_OBJECT_REFERENCE_H_ 18 #define ART_RUNTIME_MIRROR_OBJECT_REFERENCE_H_ 19 20 #include "base/mutex.h" // For Locks::mutator_lock_. 21 #include "globals.h" 22 #include "obj_ptr.h" 23 24 namespace art { 25 namespace mirror { 26 27 class Object; 28 29 // Classes shared with the managed side of the world need to be packed so that they don't have 30 // extra platform specific padding. 31 #define MANAGED PACKED(4) 32 33 // Value type representing a reference to a mirror::Object of type MirrorType. 34 template<bool kPoisonReferences, class MirrorType> 35 class MANAGED ObjectReference { 36 public: AsMirrorPtr()37 MirrorType* AsMirrorPtr() const REQUIRES_SHARED(Locks::mutator_lock_) { 38 return UnCompress(); 39 } 40 Assign(MirrorType * other)41 void Assign(MirrorType* other) REQUIRES_SHARED(Locks::mutator_lock_) { 42 reference_ = Compress(other); 43 } 44 45 void Assign(ObjPtr<MirrorType> ptr) 46 REQUIRES_SHARED(Locks::mutator_lock_); 47 Clear()48 void Clear() { 49 reference_ = 0; 50 DCHECK(IsNull()); 51 } 52 IsNull()53 bool IsNull() const { 54 return reference_ == 0; 55 } 56 AsVRegValue()57 uint32_t AsVRegValue() const { 58 return reference_; 59 } 60 61 protected: ObjectReference(MirrorType * mirror_ptr)62 explicit ObjectReference(MirrorType* mirror_ptr) 63 REQUIRES_SHARED(Locks::mutator_lock_) 64 : reference_(Compress(mirror_ptr)) { 65 } 66 67 // Compress reference to its bit representation. Compress(MirrorType * mirror_ptr)68 static uint32_t Compress(MirrorType* mirror_ptr) REQUIRES_SHARED(Locks::mutator_lock_) { 69 uintptr_t as_bits = reinterpret_cast<uintptr_t>(mirror_ptr); 70 return static_cast<uint32_t>(kPoisonReferences ? -as_bits : as_bits); 71 } 72 73 // Uncompress an encoded reference from its bit representation. UnCompress()74 MirrorType* UnCompress() const REQUIRES_SHARED(Locks::mutator_lock_) { 75 uintptr_t as_bits = kPoisonReferences ? -reference_ : reference_; 76 return reinterpret_cast<MirrorType*>(as_bits); 77 } 78 79 friend class Object; 80 81 // The encoded reference to a mirror::Object. 82 uint32_t reference_; 83 }; 84 85 // References between objects within the managed heap. 86 template<class MirrorType> 87 class MANAGED HeapReference : public ObjectReference<kPoisonHeapReferences, MirrorType> { 88 public: FromMirrorPtr(MirrorType * mirror_ptr)89 static HeapReference<MirrorType> FromMirrorPtr(MirrorType* mirror_ptr) 90 REQUIRES_SHARED(Locks::mutator_lock_) { 91 return HeapReference<MirrorType>(mirror_ptr); 92 } 93 94 static HeapReference<MirrorType> FromObjPtr(ObjPtr<MirrorType> ptr) 95 REQUIRES_SHARED(Locks::mutator_lock_); 96 97 bool CasWeakRelaxed(MirrorType* old_ptr, MirrorType* new_ptr) 98 REQUIRES_SHARED(Locks::mutator_lock_); 99 100 private: HeapReference(MirrorType * mirror_ptr)101 explicit HeapReference(MirrorType* mirror_ptr) REQUIRES_SHARED(Locks::mutator_lock_) 102 : ObjectReference<kPoisonHeapReferences, MirrorType>(mirror_ptr) {} 103 }; 104 105 static_assert(sizeof(mirror::HeapReference<mirror::Object>) == kHeapReferenceSize, 106 "heap reference size does not match"); 107 108 // Standard compressed reference used in the runtime. Used for StackReference and GC roots. 109 template<class MirrorType> 110 class MANAGED CompressedReference : public mirror::ObjectReference<false, MirrorType> { 111 public: REQUIRES_SHARED(Locks::mutator_lock_)112 CompressedReference<MirrorType>() REQUIRES_SHARED(Locks::mutator_lock_) 113 : mirror::ObjectReference<false, MirrorType>(nullptr) {} 114 FromMirrorPtr(MirrorType * p)115 static CompressedReference<MirrorType> FromMirrorPtr(MirrorType* p) 116 REQUIRES_SHARED(Locks::mutator_lock_) { 117 return CompressedReference<MirrorType>(p); 118 } 119 120 private: CompressedReference(MirrorType * p)121 explicit CompressedReference(MirrorType* p) REQUIRES_SHARED(Locks::mutator_lock_) 122 : mirror::ObjectReference<false, MirrorType>(p) {} 123 }; 124 125 } // namespace mirror 126 } // namespace art 127 128 #endif // ART_RUNTIME_MIRROR_OBJECT_REFERENCE_H_ 129