blob: afa411204b42175d678237579e1d862050526b9c [file] [log] [blame]
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001/*
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
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_MIRROR_OBJECT_INL_H_
18#define ART_RUNTIME_MIRROR_OBJECT_INL_H_
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080019
20#include "object.h"
21
Brian Carlstromea46f952013-07-30 01:26:50 -070022#include "art_field.h"
23#include "art_method.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080024#include "atomic.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070025#include "array-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080026#include "class.h"
Ian Rogersd9c4fc92013-10-01 19:45:43 -070027#include "lock_word-inl.h"
Ian Rogers05f30572013-02-20 12:13:11 -080028#include "monitor.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080029#include "runtime.h"
Ian Rogers05f30572013-02-20 12:13:11 -080030#include "throwable.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080031
32namespace art {
33namespace mirror {
34
Ian Rogersef7d42f2014-01-06 12:55:46 -080035inline Class* Object::GetClass() {
36 return GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(Object, klass_), false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080037}
38
39inline void Object::SetClass(Class* new_klass) {
Ian Rogersef7d42f2014-01-06 12:55:46 -080040 // new_klass may be NULL prior to class linker initialization.
41 // We don't mark the card as this occurs as part of object allocation. Not all objects have
42 // backing cards, such as large objects.
43 SetFieldObjectWithoutWriteBarrier(OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass, false, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080044}
45
Ian Rogersef7d42f2014-01-06 12:55:46 -080046inline LockWord Object::GetLockWord() {
Ian Rogersd9c4fc92013-10-01 19:45:43 -070047 return LockWord(GetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), true));
48}
49
50inline void Object::SetLockWord(LockWord new_val) {
51 SetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue(), true);
52}
53
54inline bool Object::CasLockWord(LockWord old_val, LockWord new_val) {
55 return CasField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(),
56 new_val.GetValue());
57}
58
59inline uint32_t Object::GetLockOwnerThreadId() {
60 return Monitor::GetLockOwnerThreadId(this);
Ian Rogers05f30572013-02-20 12:13:11 -080061}
62
63inline void Object::MonitorEnter(Thread* self) {
64 Monitor::MonitorEnter(self, this);
65}
66
67inline bool Object::MonitorExit(Thread* self) {
68 return Monitor::MonitorExit(self, this);
69}
70
71inline void Object::Notify(Thread* self) {
72 Monitor::Notify(self, this);
73}
74
75inline void Object::NotifyAll(Thread* self) {
76 Monitor::NotifyAll(self, this);
77}
78
79inline void Object::Wait(Thread* self) {
80 Monitor::Wait(self, this, 0, 0, true, kWaiting);
81}
82
83inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
84 Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
85}
86
Ian Rogersef7d42f2014-01-06 12:55:46 -080087inline bool Object::VerifierInstanceOf(Class* klass) {
Jeff Haoa3faaf42013-09-03 19:07:00 -070088 DCHECK(klass != NULL);
89 DCHECK(GetClass() != NULL);
90 return klass->IsInterface() || InstanceOf(klass);
91}
92
Ian Rogersef7d42f2014-01-06 12:55:46 -080093inline bool Object::InstanceOf(Class* klass) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080094 DCHECK(klass != NULL);
95 DCHECK(GetClass() != NULL);
96 return klass->IsAssignableFrom(GetClass());
97}
98
Ian Rogersef7d42f2014-01-06 12:55:46 -080099inline bool Object::IsClass() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800100 Class* java_lang_Class = GetClass()->GetClass();
101 return GetClass() == java_lang_Class;
102}
103
104inline Class* Object::AsClass() {
105 DCHECK(IsClass());
106 return down_cast<Class*>(this);
107}
108
Ian Rogersef7d42f2014-01-06 12:55:46 -0800109inline bool Object::IsObjectArray() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800110 return IsArrayInstance() && !GetClass()->GetComponentType()->IsPrimitive();
111}
112
113template<class T>
114inline ObjectArray<T>* Object::AsObjectArray() {
115 DCHECK(IsObjectArray());
116 return down_cast<ObjectArray<T>*>(this);
117}
118
Ian Rogersef7d42f2014-01-06 12:55:46 -0800119inline bool Object::IsArrayInstance() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800120 return GetClass()->IsArrayClass();
121}
122
Ian Rogersef7d42f2014-01-06 12:55:46 -0800123inline bool Object::IsArtField() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700124 return GetClass()->IsArtFieldClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800125}
126
Brian Carlstromea46f952013-07-30 01:26:50 -0700127inline ArtField* Object::AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
128 DCHECK(IsArtField());
129 return down_cast<ArtField*>(this);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800130}
131
Ian Rogersef7d42f2014-01-06 12:55:46 -0800132inline bool Object::IsArtMethod() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700133 return GetClass()->IsArtMethodClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800134}
135
Brian Carlstromea46f952013-07-30 01:26:50 -0700136inline ArtMethod* Object::AsArtMethod() {
137 DCHECK(IsArtMethod());
138 return down_cast<ArtMethod*>(this);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800139}
140
Ian Rogersef7d42f2014-01-06 12:55:46 -0800141inline bool Object::IsReferenceInstance() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800142 return GetClass()->IsReferenceClass();
143}
144
Ian Rogers05f30572013-02-20 12:13:11 -0800145inline Array* Object::AsArray() {
146 DCHECK(IsArrayInstance());
147 return down_cast<Array*>(this);
148}
149
Ian Rogers05f30572013-02-20 12:13:11 -0800150inline BooleanArray* Object::AsBooleanArray() {
151 DCHECK(GetClass()->IsArrayClass());
152 DCHECK(GetClass()->GetComponentType()->IsPrimitiveBoolean());
153 return down_cast<BooleanArray*>(this);
154}
155
156inline ByteArray* Object::AsByteArray() {
157 DCHECK(GetClass()->IsArrayClass());
158 DCHECK(GetClass()->GetComponentType()->IsPrimitiveByte());
159 return down_cast<ByteArray*>(this);
160}
161
Ian Rogersef7d42f2014-01-06 12:55:46 -0800162inline ByteArray* Object::AsByteSizedArray() {
163 DCHECK(GetClass()->IsArrayClass());
164 DCHECK(GetClass()->GetComponentType()->IsPrimitiveByte() ||
165 GetClass()->GetComponentType()->IsPrimitiveBoolean());
166 return down_cast<ByteArray*>(this);
167}
168
Ian Rogers05f30572013-02-20 12:13:11 -0800169inline CharArray* Object::AsCharArray() {
170 DCHECK(GetClass()->IsArrayClass());
171 DCHECK(GetClass()->GetComponentType()->IsPrimitiveChar());
172 return down_cast<CharArray*>(this);
173}
174
175inline ShortArray* Object::AsShortArray() {
176 DCHECK(GetClass()->IsArrayClass());
177 DCHECK(GetClass()->GetComponentType()->IsPrimitiveShort());
178 return down_cast<ShortArray*>(this);
179}
180
Ian Rogersef7d42f2014-01-06 12:55:46 -0800181inline ShortArray* Object::AsShortSizedArray() {
182 DCHECK(GetClass()->IsArrayClass());
183 DCHECK(GetClass()->GetComponentType()->IsPrimitiveShort() ||
184 GetClass()->GetComponentType()->IsPrimitiveChar());
185 return down_cast<ShortArray*>(this);
186}
187
Ian Rogers05f30572013-02-20 12:13:11 -0800188inline IntArray* Object::AsIntArray() {
189 DCHECK(GetClass()->IsArrayClass());
190 DCHECK(GetClass()->GetComponentType()->IsPrimitiveInt() ||
191 GetClass()->GetComponentType()->IsPrimitiveFloat());
192 return down_cast<IntArray*>(this);
193}
194
195inline LongArray* Object::AsLongArray() {
196 DCHECK(GetClass()->IsArrayClass());
197 DCHECK(GetClass()->GetComponentType()->IsPrimitiveLong() ||
198 GetClass()->GetComponentType()->IsPrimitiveDouble());
199 return down_cast<LongArray*>(this);
200}
201
202inline String* Object::AsString() {
203 DCHECK(GetClass()->IsStringClass());
204 return down_cast<String*>(this);
205}
206
207inline Throwable* Object::AsThrowable() {
208 DCHECK(GetClass()->IsThrowableClass());
209 return down_cast<Throwable*>(this);
210}
211
Ian Rogersef7d42f2014-01-06 12:55:46 -0800212inline bool Object::IsWeakReferenceInstance() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800213 return GetClass()->IsWeakReferenceClass();
214}
215
Ian Rogersef7d42f2014-01-06 12:55:46 -0800216inline bool Object::IsSoftReferenceInstance() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800217 return GetClass()->IsSoftReferenceClass();
218}
219
Ian Rogersef7d42f2014-01-06 12:55:46 -0800220inline bool Object::IsFinalizerReferenceInstance() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800221 return GetClass()->IsFinalizerReferenceClass();
222}
223
Ian Rogersef7d42f2014-01-06 12:55:46 -0800224inline bool Object::IsPhantomReferenceInstance() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800225 return GetClass()->IsPhantomReferenceClass();
226}
227
Ian Rogersef7d42f2014-01-06 12:55:46 -0800228inline size_t Object::SizeOf() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800229 size_t result;
230 if (IsArrayInstance()) {
231 result = AsArray()->SizeOf();
232 } else if (IsClass()) {
233 result = AsClass()->SizeOf();
234 } else {
235 result = GetClass()->GetObjectSize();
236 }
Mathieu Chartier79b4f382013-10-23 15:21:37 -0700237 DCHECK_GE(result, sizeof(Object)) << " class=" << PrettyTypeOf(GetClass());
Brian Carlstromea46f952013-07-30 01:26:50 -0700238 DCHECK(!IsArtField() || result == sizeof(ArtField));
239 DCHECK(!IsArtMethod() || result == sizeof(ArtMethod));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800240 return result;
241}
242
Ian Rogersef7d42f2014-01-06 12:55:46 -0800243inline uint32_t Object::GetField32(MemberOffset field_offset, bool is_volatile) {
Ian Rogersb122a4b2013-11-19 18:00:50 -0800244 VerifyObject(this);
245 const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
246 const int32_t* word_addr = reinterpret_cast<const int32_t*>(raw_addr);
247 if (UNLIKELY(is_volatile)) {
248 int32_t result = *(reinterpret_cast<volatile int32_t*>(const_cast<int32_t*>(word_addr)));
Ian Rogersef7d42f2014-01-06 12:55:46 -0800249 QuasiAtomic::MembarLoadLoad(); // Ensure volatile loads don't re-order.
Ian Rogersb122a4b2013-11-19 18:00:50 -0800250 return result;
251 } else {
252 return *word_addr;
253 }
254}
255
256inline void Object::SetField32(MemberOffset field_offset, uint32_t new_value, bool is_volatile,
257 bool this_is_valid) {
258 if (this_is_valid) {
259 VerifyObject(this);
260 }
261 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
262 uint32_t* word_addr = reinterpret_cast<uint32_t*>(raw_addr);
263 if (UNLIKELY(is_volatile)) {
264 QuasiAtomic::MembarStoreStore(); // Ensure this store occurs after others in the queue.
265 *word_addr = new_value;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800266 QuasiAtomic::MembarStoreLoad(); // Ensure this store occurs before any volatile loads.
Ian Rogersb122a4b2013-11-19 18:00:50 -0800267 } else {
268 *word_addr = new_value;
269 }
270}
271
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700272inline bool Object::CasField32(MemberOffset field_offset, uint32_t old_value, uint32_t new_value) {
273 VerifyObject(this);
274 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
Ian Rogersb122a4b2013-11-19 18:00:50 -0800275 volatile uint32_t* addr = reinterpret_cast<volatile uint32_t*>(raw_addr);
276 return __sync_bool_compare_and_swap(addr, old_value, new_value);
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700277}
278
Ian Rogersef7d42f2014-01-06 12:55:46 -0800279inline uint64_t Object::GetField64(MemberOffset field_offset, bool is_volatile) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800280 VerifyObject(this);
281 const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
282 const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr);
283 if (UNLIKELY(is_volatile)) {
284 uint64_t result = QuasiAtomic::Read64(addr);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800285 QuasiAtomic::MembarLoadLoad(); // Ensure volatile loads don't re-order.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800286 return result;
287 } else {
288 return *addr;
289 }
290}
291
Ian Rogersef7d42f2014-01-06 12:55:46 -0800292inline void Object::SetField64(MemberOffset field_offset, uint64_t new_value, bool is_volatile,
293 bool this_is_valid) {
294 if (this_is_valid) {
295 VerifyObject(this);
296 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800297 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
298 int64_t* addr = reinterpret_cast<int64_t*>(raw_addr);
299 if (UNLIKELY(is_volatile)) {
Ian Rogersb122a4b2013-11-19 18:00:50 -0800300 QuasiAtomic::MembarStoreStore(); // Ensure this store occurs after others in the queue.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800301 QuasiAtomic::Write64(addr, new_value);
Ian Rogersb122a4b2013-11-19 18:00:50 -0800302 if (!QuasiAtomic::LongAtomicsUseMutexes()) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800303 QuasiAtomic::MembarStoreLoad(); // Ensure this store occurs before any volatile loads.
Ian Rogersb122a4b2013-11-19 18:00:50 -0800304 } else {
305 // Fence from from mutex is enough.
306 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800307 } else {
308 *addr = new_value;
309 }
310}
311
Ian Rogersef7d42f2014-01-06 12:55:46 -0800312inline bool Object::CasField64(MemberOffset field_offset, uint64_t old_value, uint64_t new_value) {
313 VerifyObject(this);
314 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
315 volatile uint64_t* addr = reinterpret_cast<volatile uint64_t*>(raw_addr);
316 return __sync_bool_compare_and_swap(addr, old_value, new_value);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800317}
318
Ian Rogersef7d42f2014-01-06 12:55:46 -0800319template<class T>
320inline T* Object::GetFieldObject(MemberOffset field_offset, bool is_volatile) {
321 VerifyObject(this);
322 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
323 HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr);
324 HeapReference<T> objref = *objref_addr;
325
326 if (UNLIKELY(is_volatile)) {
327 QuasiAtomic::MembarLoadLoad(); // Ensure loads don't re-order.
328 }
329 T* result = objref.AsMirrorPtr();
330 VerifyObject(result);
331 return result;
332}
333
334inline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset, Object* new_value,
335 bool is_volatile, bool this_is_valid) {
336 if (this_is_valid) {
337 VerifyObject(this);
338 }
339 VerifyObject(new_value);
340 HeapReference<Object> objref(HeapReference<Object>::FromMirrorPtr(new_value));
341 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
342 HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr);
343 if (UNLIKELY(is_volatile)) {
344 QuasiAtomic::MembarStoreStore(); // Ensure this store occurs after others in the queue.
345 objref_addr->Assign(new_value);
346 QuasiAtomic::MembarStoreLoad(); // Ensure this store occurs before any loads.
347 } else {
348 objref_addr->Assign(new_value);
349 }
350}
351
352inline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value, bool is_volatile,
353 bool this_is_valid) {
354 SetFieldObjectWithoutWriteBarrier(field_offset, new_value, is_volatile, this_is_valid);
355 if (new_value != nullptr) {
356 CheckFieldAssignment(field_offset, new_value);
357 Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
358 }
359}
360
361inline bool Object::CasFieldObject(MemberOffset field_offset, Object* old_value, Object* new_value) {
362 VerifyObject(this);
363 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
364 volatile uint32_t* addr = reinterpret_cast<volatile uint32_t*>(raw_addr);
365 HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
366 HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
367 bool success = __sync_bool_compare_and_swap(addr, old_ref.reference_, new_ref.reference_);
368 if (success) {
369 Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
370 }
371 return success;
372}
373
374inline void Object::VerifyObject(Object* obj) {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700375 if (kIsDebugBuild) {
376 Runtime::Current()->GetHeap()->VerifyObject(obj);
377 }
Ian Rogers04d7aa92013-03-16 14:29:17 -0700378}
379
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800380} // namespace mirror
381} // namespace art
382
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700383#endif // ART_RUNTIME_MIRROR_OBJECT_INL_H_