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