blob: 70291c1ad61e95ea2cf26c0bd52603eee6b9b799 [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.
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010043 // We use non transactional version since we can't undo this write. We also disable checking as
44 // we may run in transaction mode here.
45 SetFieldObjectWithoutWriteBarrier<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, klass_),
46 new_klass, false, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080047}
48
Ian Rogersef7d42f2014-01-06 12:55:46 -080049inline LockWord Object::GetLockWord() {
Ian Rogersd9c4fc92013-10-01 19:45:43 -070050 return LockWord(GetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), true));
51}
52
53inline void Object::SetLockWord(LockWord new_val) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010054 // Force use of non-transactional mode and do not check.
55 SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue(), true);
Ian Rogersd9c4fc92013-10-01 19:45:43 -070056}
57
58inline bool Object::CasLockWord(LockWord old_val, LockWord new_val) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010059 // Force use of non-transactional mode and do not check.
60 return CasField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(),
61 new_val.GetValue());
Ian Rogersd9c4fc92013-10-01 19:45:43 -070062}
63
64inline uint32_t Object::GetLockOwnerThreadId() {
65 return Monitor::GetLockOwnerThreadId(this);
Ian Rogers05f30572013-02-20 12:13:11 -080066}
67
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -080068inline mirror::Object* Object::MonitorEnter(Thread* self) {
69 return Monitor::MonitorEnter(self, this);
Ian Rogers05f30572013-02-20 12:13:11 -080070}
71
72inline bool Object::MonitorExit(Thread* self) {
73 return Monitor::MonitorExit(self, this);
74}
75
76inline void Object::Notify(Thread* self) {
77 Monitor::Notify(self, this);
78}
79
80inline void Object::NotifyAll(Thread* self) {
81 Monitor::NotifyAll(self, this);
82}
83
84inline void Object::Wait(Thread* self) {
85 Monitor::Wait(self, this, 0, 0, true, kWaiting);
86}
87
88inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
89 Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
90}
91
Ian Rogersef7d42f2014-01-06 12:55:46 -080092inline bool Object::VerifierInstanceOf(Class* klass) {
Jeff Haoa3faaf42013-09-03 19:07:00 -070093 DCHECK(klass != NULL);
94 DCHECK(GetClass() != NULL);
95 return klass->IsInterface() || InstanceOf(klass);
96}
97
Ian Rogersef7d42f2014-01-06 12:55:46 -080098inline bool Object::InstanceOf(Class* klass) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080099 DCHECK(klass != NULL);
100 DCHECK(GetClass() != NULL);
101 return klass->IsAssignableFrom(GetClass());
102}
103
Ian Rogersef7d42f2014-01-06 12:55:46 -0800104inline bool Object::IsClass() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800105 Class* java_lang_Class = GetClass()->GetClass();
106 return GetClass() == java_lang_Class;
107}
108
109inline Class* Object::AsClass() {
110 DCHECK(IsClass());
111 return down_cast<Class*>(this);
112}
113
Ian Rogersef7d42f2014-01-06 12:55:46 -0800114inline bool Object::IsObjectArray() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800115 return IsArrayInstance() && !GetClass()->GetComponentType()->IsPrimitive();
116}
117
118template<class T>
119inline ObjectArray<T>* Object::AsObjectArray() {
120 DCHECK(IsObjectArray());
121 return down_cast<ObjectArray<T>*>(this);
122}
123
Ian Rogersef7d42f2014-01-06 12:55:46 -0800124inline bool Object::IsArrayInstance() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800125 return GetClass()->IsArrayClass();
126}
127
Ian Rogersef7d42f2014-01-06 12:55:46 -0800128inline bool Object::IsArtField() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700129 return GetClass()->IsArtFieldClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800130}
131
Brian Carlstromea46f952013-07-30 01:26:50 -0700132inline ArtField* Object::AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
133 DCHECK(IsArtField());
134 return down_cast<ArtField*>(this);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800135}
136
Ian Rogersef7d42f2014-01-06 12:55:46 -0800137inline bool Object::IsArtMethod() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700138 return GetClass()->IsArtMethodClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800139}
140
Brian Carlstromea46f952013-07-30 01:26:50 -0700141inline ArtMethod* Object::AsArtMethod() {
142 DCHECK(IsArtMethod());
143 return down_cast<ArtMethod*>(this);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800144}
145
Ian Rogersef7d42f2014-01-06 12:55:46 -0800146inline bool Object::IsReferenceInstance() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800147 return GetClass()->IsReferenceClass();
148}
149
Ian Rogers05f30572013-02-20 12:13:11 -0800150inline Array* Object::AsArray() {
151 DCHECK(IsArrayInstance());
152 return down_cast<Array*>(this);
153}
154
Ian Rogers05f30572013-02-20 12:13:11 -0800155inline BooleanArray* Object::AsBooleanArray() {
156 DCHECK(GetClass()->IsArrayClass());
157 DCHECK(GetClass()->GetComponentType()->IsPrimitiveBoolean());
158 return down_cast<BooleanArray*>(this);
159}
160
161inline ByteArray* Object::AsByteArray() {
162 DCHECK(GetClass()->IsArrayClass());
163 DCHECK(GetClass()->GetComponentType()->IsPrimitiveByte());
164 return down_cast<ByteArray*>(this);
165}
166
Ian Rogersef7d42f2014-01-06 12:55:46 -0800167inline ByteArray* Object::AsByteSizedArray() {
168 DCHECK(GetClass()->IsArrayClass());
169 DCHECK(GetClass()->GetComponentType()->IsPrimitiveByte() ||
170 GetClass()->GetComponentType()->IsPrimitiveBoolean());
171 return down_cast<ByteArray*>(this);
172}
173
Ian Rogers05f30572013-02-20 12:13:11 -0800174inline CharArray* Object::AsCharArray() {
175 DCHECK(GetClass()->IsArrayClass());
176 DCHECK(GetClass()->GetComponentType()->IsPrimitiveChar());
177 return down_cast<CharArray*>(this);
178}
179
180inline ShortArray* Object::AsShortArray() {
181 DCHECK(GetClass()->IsArrayClass());
182 DCHECK(GetClass()->GetComponentType()->IsPrimitiveShort());
183 return down_cast<ShortArray*>(this);
184}
185
Ian Rogersef7d42f2014-01-06 12:55:46 -0800186inline ShortArray* Object::AsShortSizedArray() {
187 DCHECK(GetClass()->IsArrayClass());
188 DCHECK(GetClass()->GetComponentType()->IsPrimitiveShort() ||
189 GetClass()->GetComponentType()->IsPrimitiveChar());
190 return down_cast<ShortArray*>(this);
191}
192
Ian Rogers05f30572013-02-20 12:13:11 -0800193inline IntArray* Object::AsIntArray() {
194 DCHECK(GetClass()->IsArrayClass());
195 DCHECK(GetClass()->GetComponentType()->IsPrimitiveInt() ||
196 GetClass()->GetComponentType()->IsPrimitiveFloat());
197 return down_cast<IntArray*>(this);
198}
199
200inline LongArray* Object::AsLongArray() {
201 DCHECK(GetClass()->IsArrayClass());
202 DCHECK(GetClass()->GetComponentType()->IsPrimitiveLong() ||
203 GetClass()->GetComponentType()->IsPrimitiveDouble());
204 return down_cast<LongArray*>(this);
205}
206
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100207inline FloatArray* Object::AsFloatArray() {
208 DCHECK(GetClass()->IsArrayClass());
209 DCHECK(GetClass()->GetComponentType()->IsPrimitiveFloat());
210 return down_cast<FloatArray*>(this);
211}
212
213inline DoubleArray* Object::AsDoubleArray() {
214 DCHECK(GetClass()->IsArrayClass());
215 DCHECK(GetClass()->GetComponentType()->IsPrimitiveDouble());
216 return down_cast<DoubleArray*>(this);
217}
218
Ian Rogers05f30572013-02-20 12:13:11 -0800219inline String* Object::AsString() {
220 DCHECK(GetClass()->IsStringClass());
221 return down_cast<String*>(this);
222}
223
224inline Throwable* Object::AsThrowable() {
225 DCHECK(GetClass()->IsThrowableClass());
226 return down_cast<Throwable*>(this);
227}
228
Ian Rogersef7d42f2014-01-06 12:55:46 -0800229inline bool Object::IsWeakReferenceInstance() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800230 return GetClass()->IsWeakReferenceClass();
231}
232
Ian Rogersef7d42f2014-01-06 12:55:46 -0800233inline bool Object::IsSoftReferenceInstance() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800234 return GetClass()->IsSoftReferenceClass();
235}
236
Ian Rogersef7d42f2014-01-06 12:55:46 -0800237inline bool Object::IsFinalizerReferenceInstance() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800238 return GetClass()->IsFinalizerReferenceClass();
239}
240
Ian Rogersef7d42f2014-01-06 12:55:46 -0800241inline bool Object::IsPhantomReferenceInstance() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800242 return GetClass()->IsPhantomReferenceClass();
243}
244
Ian Rogersef7d42f2014-01-06 12:55:46 -0800245inline size_t Object::SizeOf() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800246 size_t result;
247 if (IsArrayInstance()) {
248 result = AsArray()->SizeOf();
249 } else if (IsClass()) {
250 result = AsClass()->SizeOf();
251 } else {
252 result = GetClass()->GetObjectSize();
253 }
Mathieu Chartier79b4f382013-10-23 15:21:37 -0700254 DCHECK_GE(result, sizeof(Object)) << " class=" << PrettyTypeOf(GetClass());
Brian Carlstromea46f952013-07-30 01:26:50 -0700255 DCHECK(!IsArtField() || result == sizeof(ArtField));
256 DCHECK(!IsArtMethod() || result == sizeof(ArtMethod));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800257 return result;
258}
259
Ian Rogers29501cf2014-02-07 21:00:25 -0800260inline int32_t Object::GetField32(MemberOffset field_offset, bool is_volatile) {
Ian Rogersb122a4b2013-11-19 18:00:50 -0800261 VerifyObject(this);
262 const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
263 const int32_t* word_addr = reinterpret_cast<const int32_t*>(raw_addr);
264 if (UNLIKELY(is_volatile)) {
265 int32_t result = *(reinterpret_cast<volatile int32_t*>(const_cast<int32_t*>(word_addr)));
Ian Rogersef7d42f2014-01-06 12:55:46 -0800266 QuasiAtomic::MembarLoadLoad(); // Ensure volatile loads don't re-order.
Ian Rogersb122a4b2013-11-19 18:00:50 -0800267 return result;
268 } else {
269 return *word_addr;
270 }
271}
272
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100273template<bool kTransactionActive, bool kCheckTransaction>
Ian Rogers29501cf2014-02-07 21:00:25 -0800274inline void Object::SetField32(MemberOffset field_offset, int32_t new_value, bool is_volatile,
Ian Rogersb122a4b2013-11-19 18:00:50 -0800275 bool this_is_valid) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100276 if (kCheckTransaction) {
277 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
278 }
279 if (kTransactionActive) {
280 Runtime::Current()->RecordWriteField32(this, field_offset, GetField32(field_offset, is_volatile),
281 is_volatile);
282 }
Ian Rogersb122a4b2013-11-19 18:00:50 -0800283 if (this_is_valid) {
284 VerifyObject(this);
285 }
286 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
Ian Rogers29501cf2014-02-07 21:00:25 -0800287 int32_t* word_addr = reinterpret_cast<int32_t*>(raw_addr);
Ian Rogersb122a4b2013-11-19 18:00:50 -0800288 if (UNLIKELY(is_volatile)) {
289 QuasiAtomic::MembarStoreStore(); // Ensure this store occurs after others in the queue.
290 *word_addr = new_value;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800291 QuasiAtomic::MembarStoreLoad(); // Ensure this store occurs before any volatile loads.
Ian Rogersb122a4b2013-11-19 18:00:50 -0800292 } else {
293 *word_addr = new_value;
294 }
295}
296
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100297template<bool kTransactionActive, bool kCheckTransaction>
Ian Rogers29501cf2014-02-07 21:00:25 -0800298inline bool Object::CasField32(MemberOffset field_offset, int32_t old_value, int32_t new_value) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100299 if (kCheckTransaction) {
300 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
301 }
302 if (kTransactionActive) {
303 Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
304 }
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700305 VerifyObject(this);
306 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
Ian Rogers29501cf2014-02-07 21:00:25 -0800307 volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr);
Ian Rogersb122a4b2013-11-19 18:00:50 -0800308 return __sync_bool_compare_and_swap(addr, old_value, new_value);
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700309}
310
Ian Rogers29501cf2014-02-07 21:00:25 -0800311inline int64_t Object::GetField64(MemberOffset field_offset, bool is_volatile) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800312 VerifyObject(this);
313 const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
314 const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr);
315 if (UNLIKELY(is_volatile)) {
Ian Rogers29501cf2014-02-07 21:00:25 -0800316 int64_t result = QuasiAtomic::Read64(addr);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800317 QuasiAtomic::MembarLoadLoad(); // Ensure volatile loads don't re-order.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800318 return result;
319 } else {
320 return *addr;
321 }
322}
323
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100324template<bool kTransactionActive, bool kCheckTransaction>
Ian Rogers29501cf2014-02-07 21:00:25 -0800325inline void Object::SetField64(MemberOffset field_offset, int64_t new_value, bool is_volatile,
Ian Rogersef7d42f2014-01-06 12:55:46 -0800326 bool this_is_valid) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100327 if (kCheckTransaction) {
328 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
329 }
330 if (kTransactionActive) {
331 Runtime::Current()->RecordWriteField64(this, field_offset, GetField64(field_offset, is_volatile),
332 is_volatile);
333 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800334 if (this_is_valid) {
335 VerifyObject(this);
336 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800337 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
338 int64_t* addr = reinterpret_cast<int64_t*>(raw_addr);
339 if (UNLIKELY(is_volatile)) {
Ian Rogersb122a4b2013-11-19 18:00:50 -0800340 QuasiAtomic::MembarStoreStore(); // Ensure this store occurs after others in the queue.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800341 QuasiAtomic::Write64(addr, new_value);
Ian Rogersb122a4b2013-11-19 18:00:50 -0800342 if (!QuasiAtomic::LongAtomicsUseMutexes()) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800343 QuasiAtomic::MembarStoreLoad(); // Ensure this store occurs before any volatile loads.
Ian Rogersb122a4b2013-11-19 18:00:50 -0800344 } else {
345 // Fence from from mutex is enough.
346 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800347 } else {
348 *addr = new_value;
349 }
350}
351
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100352template<bool kTransactionActive, bool kCheckTransaction>
Ian Rogers29501cf2014-02-07 21:00:25 -0800353inline bool Object::CasField64(MemberOffset field_offset, int64_t old_value, int64_t new_value) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100354 if (kCheckTransaction) {
355 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
356 }
357 if (kTransactionActive) {
358 Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
359 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800360 VerifyObject(this);
361 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
Ian Rogers29501cf2014-02-07 21:00:25 -0800362 volatile int64_t* addr = reinterpret_cast<volatile int64_t*>(raw_addr);
363 return QuasiAtomic::Cas64(old_value, new_value, addr);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800364}
365
Ian Rogersef7d42f2014-01-06 12:55:46 -0800366template<class T>
367inline T* Object::GetFieldObject(MemberOffset field_offset, bool is_volatile) {
368 VerifyObject(this);
369 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
370 HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr);
371 HeapReference<T> objref = *objref_addr;
372
373 if (UNLIKELY(is_volatile)) {
374 QuasiAtomic::MembarLoadLoad(); // Ensure loads don't re-order.
375 }
376 T* result = objref.AsMirrorPtr();
377 VerifyObject(result);
378 return result;
379}
380
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100381template<bool kTransactionActive, bool kCheckTransaction>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800382inline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset, Object* new_value,
383 bool is_volatile, bool this_is_valid) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100384 if (kCheckTransaction) {
385 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
386 }
387 if (kTransactionActive) {
388 Runtime::Current()->RecordWriteFieldReference(this, field_offset,
389 GetFieldObject<Object>(field_offset, is_volatile),
390 true);
391 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800392 if (this_is_valid) {
393 VerifyObject(this);
394 }
395 VerifyObject(new_value);
396 HeapReference<Object> objref(HeapReference<Object>::FromMirrorPtr(new_value));
397 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
398 HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr);
399 if (UNLIKELY(is_volatile)) {
400 QuasiAtomic::MembarStoreStore(); // Ensure this store occurs after others in the queue.
401 objref_addr->Assign(new_value);
402 QuasiAtomic::MembarStoreLoad(); // Ensure this store occurs before any loads.
403 } else {
404 objref_addr->Assign(new_value);
405 }
406}
407
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100408template<bool kTransactionActive, bool kCheckTransaction>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800409inline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value, bool is_volatile,
410 bool this_is_valid) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100411 SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction>(field_offset, new_value,
412 is_volatile,
413 this_is_valid);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800414 if (new_value != nullptr) {
415 CheckFieldAssignment(field_offset, new_value);
416 Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
417 }
418}
419
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100420template<bool kTransactionActive, bool kCheckTransaction>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800421inline bool Object::CasFieldObject(MemberOffset field_offset, Object* old_value, Object* new_value) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100422 if (kCheckTransaction) {
423 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
424 }
425 if (kTransactionActive) {
426 Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
427 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800428 VerifyObject(this);
429 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
Ian Rogers29501cf2014-02-07 21:00:25 -0800430 volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800431 HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
432 HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
433 bool success = __sync_bool_compare_and_swap(addr, old_ref.reference_, new_ref.reference_);
434 if (success) {
435 Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
436 }
437 return success;
438}
439
440inline void Object::VerifyObject(Object* obj) {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700441 if (kIsDebugBuild) {
442 Runtime::Current()->GetHeap()->VerifyObject(obj);
443 }
Ian Rogers04d7aa92013-03-16 14:29:17 -0700444}
445
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800446} // namespace mirror
447} // namespace art
448
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700449#endif // ART_RUNTIME_MIRROR_OBJECT_INL_H_