1 /*
2 * Copyright (C) 2011 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_INL_H_
18 #define ART_RUNTIME_MIRROR_OBJECT_INL_H_
19
20 #include "object.h"
21
22 #include "art_field.h"
23 #include "art_method.h"
24 #include "atomic.h"
25 #include "array-inl.h"
26 #include "class.h"
27 #include "monitor.h"
28 #include "runtime.h"
29 #include "throwable.h"
30
31 namespace art {
32 namespace mirror {
33
GetClass()34 inline Class* Object::GetClass() const {
35 return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Object, klass_), false);
36 }
37
SetClass(Class * new_klass)38 inline void Object::SetClass(Class* new_klass) {
39 // new_klass may be NULL prior to class linker initialization
40 // We don't mark the card since the class is guaranteed to be referenced from another location.
41 // Proxy classes are held live by the class loader, and other classes are roots of the class
42 // linker.
43 SetFieldPtr(OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass, false, false);
44 }
45
GetThinLockId()46 inline uint32_t Object::GetThinLockId() {
47 return Monitor::GetThinLockId(monitor_);
48 }
49
MonitorEnter(Thread * self)50 inline void Object::MonitorEnter(Thread* self) {
51 Monitor::MonitorEnter(self, this);
52 }
53
MonitorExit(Thread * self)54 inline bool Object::MonitorExit(Thread* self) {
55 return Monitor::MonitorExit(self, this);
56 }
57
Notify(Thread * self)58 inline void Object::Notify(Thread* self) {
59 Monitor::Notify(self, this);
60 }
61
NotifyAll(Thread * self)62 inline void Object::NotifyAll(Thread* self) {
63 Monitor::NotifyAll(self, this);
64 }
65
Wait(Thread * self)66 inline void Object::Wait(Thread* self) {
67 Monitor::Wait(self, this, 0, 0, true, kWaiting);
68 }
69
Wait(Thread * self,int64_t ms,int32_t ns)70 inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
71 Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
72 }
73
VerifierInstanceOf(const Class * klass)74 inline bool Object::VerifierInstanceOf(const Class* klass) const {
75 DCHECK(klass != NULL);
76 DCHECK(GetClass() != NULL);
77 return klass->IsInterface() || InstanceOf(klass);
78 }
79
InstanceOf(const Class * klass)80 inline bool Object::InstanceOf(const Class* klass) const {
81 DCHECK(klass != NULL);
82 DCHECK(GetClass() != NULL);
83 return klass->IsAssignableFrom(GetClass());
84 }
85
IsClass()86 inline bool Object::IsClass() const {
87 Class* java_lang_Class = GetClass()->GetClass();
88 return GetClass() == java_lang_Class;
89 }
90
AsClass()91 inline Class* Object::AsClass() {
92 DCHECK(IsClass());
93 return down_cast<Class*>(this);
94 }
95
AsClass()96 inline const Class* Object::AsClass() const {
97 DCHECK(IsClass());
98 return down_cast<const Class*>(this);
99 }
100
IsObjectArray()101 inline bool Object::IsObjectArray() const {
102 return IsArrayInstance() && !GetClass()->GetComponentType()->IsPrimitive();
103 }
104
105 template<class T>
AsObjectArray()106 inline ObjectArray<T>* Object::AsObjectArray() {
107 DCHECK(IsObjectArray());
108 return down_cast<ObjectArray<T>*>(this);
109 }
110
111 template<class T>
AsObjectArray()112 inline const ObjectArray<T>* Object::AsObjectArray() const {
113 DCHECK(IsObjectArray());
114 return down_cast<const ObjectArray<T>*>(this);
115 }
116
IsArrayInstance()117 inline bool Object::IsArrayInstance() const {
118 return GetClass()->IsArrayClass();
119 }
120
IsArtField()121 inline bool Object::IsArtField() const {
122 return GetClass()->IsArtFieldClass();
123 }
124
AsArtField()125 inline ArtField* Object::AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
126 DCHECK(IsArtField());
127 return down_cast<ArtField*>(this);
128 }
129
AsArtField()130 inline const ArtField* Object::AsArtField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
131 DCHECK(IsArtField());
132 return down_cast<const ArtField*>(this);
133 }
134
IsArtMethod()135 inline bool Object::IsArtMethod() const {
136 return GetClass()->IsArtMethodClass();
137 }
138
AsArtMethod()139 inline ArtMethod* Object::AsArtMethod() {
140 DCHECK(IsArtMethod());
141 return down_cast<ArtMethod*>(this);
142 }
143
AsArtMethod()144 inline const ArtMethod* Object::AsArtMethod() const {
145 DCHECK(IsArtMethod());
146 return down_cast<const ArtMethod*>(this);
147 }
148
IsReferenceInstance()149 inline bool Object::IsReferenceInstance() const {
150 return GetClass()->IsReferenceClass();
151 }
152
AsArray()153 inline Array* Object::AsArray() {
154 DCHECK(IsArrayInstance());
155 return down_cast<Array*>(this);
156 }
157
AsArray()158 inline const Array* Object::AsArray() const {
159 DCHECK(IsArrayInstance());
160 return down_cast<const Array*>(this);
161 }
162
AsBooleanArray()163 inline BooleanArray* Object::AsBooleanArray() {
164 DCHECK(GetClass()->IsArrayClass());
165 DCHECK(GetClass()->GetComponentType()->IsPrimitiveBoolean());
166 return down_cast<BooleanArray*>(this);
167 }
168
AsByteArray()169 inline ByteArray* Object::AsByteArray() {
170 DCHECK(GetClass()->IsArrayClass());
171 DCHECK(GetClass()->GetComponentType()->IsPrimitiveByte());
172 return down_cast<ByteArray*>(this);
173 }
174
AsCharArray()175 inline CharArray* Object::AsCharArray() {
176 DCHECK(GetClass()->IsArrayClass());
177 DCHECK(GetClass()->GetComponentType()->IsPrimitiveChar());
178 return down_cast<CharArray*>(this);
179 }
180
AsShortArray()181 inline ShortArray* Object::AsShortArray() {
182 DCHECK(GetClass()->IsArrayClass());
183 DCHECK(GetClass()->GetComponentType()->IsPrimitiveShort());
184 return down_cast<ShortArray*>(this);
185 }
186
AsIntArray()187 inline IntArray* Object::AsIntArray() {
188 DCHECK(GetClass()->IsArrayClass());
189 DCHECK(GetClass()->GetComponentType()->IsPrimitiveInt() ||
190 GetClass()->GetComponentType()->IsPrimitiveFloat());
191 return down_cast<IntArray*>(this);
192 }
193
AsLongArray()194 inline LongArray* Object::AsLongArray() {
195 DCHECK(GetClass()->IsArrayClass());
196 DCHECK(GetClass()->GetComponentType()->IsPrimitiveLong() ||
197 GetClass()->GetComponentType()->IsPrimitiveDouble());
198 return down_cast<LongArray*>(this);
199 }
200
AsString()201 inline String* Object::AsString() {
202 DCHECK(GetClass()->IsStringClass());
203 return down_cast<String*>(this);
204 }
205
AsThrowable()206 inline Throwable* Object::AsThrowable() {
207 DCHECK(GetClass()->IsThrowableClass());
208 return down_cast<Throwable*>(this);
209 }
210
IsWeakReferenceInstance()211 inline bool Object::IsWeakReferenceInstance() const {
212 return GetClass()->IsWeakReferenceClass();
213 }
214
IsSoftReferenceInstance()215 inline bool Object::IsSoftReferenceInstance() const {
216 return GetClass()->IsSoftReferenceClass();
217 }
218
IsFinalizerReferenceInstance()219 inline bool Object::IsFinalizerReferenceInstance() const {
220 return GetClass()->IsFinalizerReferenceClass();
221 }
222
IsPhantomReferenceInstance()223 inline bool Object::IsPhantomReferenceInstance() const {
224 return GetClass()->IsPhantomReferenceClass();
225 }
226
SizeOf()227 inline size_t Object::SizeOf() const {
228 size_t result;
229 if (IsArrayInstance()) {
230 result = AsArray()->SizeOf();
231 } else if (IsClass()) {
232 result = AsClass()->SizeOf();
233 } else {
234 result = GetClass()->GetObjectSize();
235 }
236 DCHECK(!IsArtField() || result == sizeof(ArtField));
237 DCHECK(!IsArtMethod() || result == sizeof(ArtMethod));
238 return result;
239 }
240
GetField64(MemberOffset field_offset,bool is_volatile)241 inline uint64_t Object::GetField64(MemberOffset field_offset, bool is_volatile) const {
242 VerifyObject(this);
243 const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
244 const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr);
245 if (UNLIKELY(is_volatile)) {
246 uint64_t result = QuasiAtomic::Read64(addr);
247 ANDROID_MEMBAR_FULL();
248 return result;
249 } else {
250 return *addr;
251 }
252 }
253
SetField64(MemberOffset field_offset,uint64_t new_value,bool is_volatile)254 inline void Object::SetField64(MemberOffset field_offset, uint64_t new_value, bool is_volatile) {
255 VerifyObject(this);
256 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
257 int64_t* addr = reinterpret_cast<int64_t*>(raw_addr);
258 if (UNLIKELY(is_volatile)) {
259 ANDROID_MEMBAR_STORE();
260 QuasiAtomic::Write64(addr, new_value);
261 // Post-store barrier not required due to use of atomic op or mutex.
262 } else {
263 *addr = new_value;
264 }
265 }
266
WriteBarrierField(const Object * dst,MemberOffset field_offset,const Object * new_value)267 inline void Object::WriteBarrierField(const Object* dst, MemberOffset field_offset,
268 const Object* new_value) {
269 Runtime::Current()->GetHeap()->WriteBarrierField(dst, field_offset, new_value);
270 }
271
VerifyObject(const Object * obj)272 inline void Object::VerifyObject(const Object* obj) {
273 if (kIsDebugBuild) {
274 Runtime::Current()->GetHeap()->VerifyObject(obj);
275 }
276 }
277
278 } // namespace mirror
279 } // namespace art
280
281 #endif // ART_RUNTIME_MIRROR_OBJECT_INL_H_
282