blob: df8104d552260eb7c1fef2efabb1542f4b7ed061 [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
Mathieu Chartier4e305412014-02-19 10:54:44 -080035template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -080036inline Class* Object::GetClass() {
Mathieu Chartier4e305412014-02-19 10:54:44 -080037 return GetFieldObject<Class, kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, klass_), false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080038}
39
Mathieu Chartier4e305412014-02-19 10:54:44 -080040template<VerifyObjectFlags kVerifyFlags>
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080041inline void Object::SetClass(Class* new_klass) {
Ian Rogersef7d42f2014-01-06 12:55:46 -080042 // new_klass may be NULL prior to class linker initialization.
43 // We don't mark the card as this occurs as part of object allocation. Not all objects have
44 // backing cards, such as large objects.
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010045 // We use non transactional version since we can't undo this write. We also disable checking as
46 // we may run in transaction mode here.
Mathieu Chartier4e305412014-02-19 10:54:44 -080047 SetFieldObjectWithoutWriteBarrier<false, false,
48 static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>(
49 OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080050}
51
Ian Rogersef7d42f2014-01-06 12:55:46 -080052inline LockWord Object::GetLockWord() {
Ian Rogersd9c4fc92013-10-01 19:45:43 -070053 return LockWord(GetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), true));
54}
55
56inline void Object::SetLockWord(LockWord new_val) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010057 // Force use of non-transactional mode and do not check.
58 SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue(), true);
Ian Rogersd9c4fc92013-10-01 19:45:43 -070059}
60
61inline bool Object::CasLockWord(LockWord old_val, LockWord new_val) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010062 // Force use of non-transactional mode and do not check.
63 return CasField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(),
64 new_val.GetValue());
Ian Rogersd9c4fc92013-10-01 19:45:43 -070065}
66
67inline uint32_t Object::GetLockOwnerThreadId() {
68 return Monitor::GetLockOwnerThreadId(this);
Ian Rogers05f30572013-02-20 12:13:11 -080069}
70
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -080071inline mirror::Object* Object::MonitorEnter(Thread* self) {
72 return Monitor::MonitorEnter(self, this);
Ian Rogers05f30572013-02-20 12:13:11 -080073}
74
75inline bool Object::MonitorExit(Thread* self) {
76 return Monitor::MonitorExit(self, this);
77}
78
79inline void Object::Notify(Thread* self) {
80 Monitor::Notify(self, this);
81}
82
83inline void Object::NotifyAll(Thread* self) {
84 Monitor::NotifyAll(self, this);
85}
86
87inline void Object::Wait(Thread* self) {
88 Monitor::Wait(self, this, 0, 0, true, kWaiting);
89}
90
91inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
92 Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
93}
94
Mathieu Chartier4e305412014-02-19 10:54:44 -080095template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -080096inline bool Object::VerifierInstanceOf(Class* klass) {
Jeff Haoa3faaf42013-09-03 19:07:00 -070097 DCHECK(klass != NULL);
Mathieu Chartier4e305412014-02-19 10:54:44 -080098 DCHECK(GetClass<kVerifyFlags>() != NULL);
Jeff Haoa3faaf42013-09-03 19:07:00 -070099 return klass->IsInterface() || InstanceOf(klass);
100}
101
Mathieu Chartier4e305412014-02-19 10:54:44 -0800102template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800103inline bool Object::InstanceOf(Class* klass) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800104 DCHECK(klass != NULL);
Mathieu Chartier4e305412014-02-19 10:54:44 -0800105 DCHECK(GetClass<kVerifyNone>() != NULL);
106 return klass->IsAssignableFrom(GetClass<kVerifyFlags>());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800107}
108
Mathieu Chartier4e305412014-02-19 10:54:44 -0800109template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800110inline bool Object::IsClass() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800111 Class* java_lang_Class = GetClass<kVerifyFlags>()->GetClass();
112 return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() ==
113 java_lang_Class;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800114}
115
Mathieu Chartier4e305412014-02-19 10:54:44 -0800116template<VerifyObjectFlags kVerifyFlags>
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800117inline Class* Object::AsClass() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800118 DCHECK(IsClass<kVerifyFlags>());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800119 return down_cast<Class*>(this);
120}
121
Mathieu Chartier4e305412014-02-19 10:54:44 -0800122template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800123inline bool Object::IsObjectArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800124 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
125 return IsArrayInstance<kVerifyFlags>() &&
126 !GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitive();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800127}
128
Mathieu Chartier4e305412014-02-19 10:54:44 -0800129template<class T, VerifyObjectFlags kVerifyFlags>
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800130inline ObjectArray<T>* Object::AsObjectArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800131 DCHECK(IsObjectArray<kVerifyFlags>());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800132 return down_cast<ObjectArray<T>*>(this);
133}
134
Mathieu Chartier4e305412014-02-19 10:54:44 -0800135template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800136inline bool Object::IsArrayInstance() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800137 return GetClass<kVerifyFlags>()->IsArrayClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800138}
139
Mathieu Chartier4e305412014-02-19 10:54:44 -0800140template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800141inline bool Object::IsArtField() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800142 return GetClass<kVerifyFlags>()->IsArtFieldClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800143}
144
Mathieu Chartier4e305412014-02-19 10:54:44 -0800145template<VerifyObjectFlags kVerifyFlags>
146inline ArtField* Object::AsArtField() {
147 DCHECK(IsArtField<kVerifyFlags>());
Brian Carlstromea46f952013-07-30 01:26:50 -0700148 return down_cast<ArtField*>(this);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800149}
150
Mathieu Chartier4e305412014-02-19 10:54:44 -0800151template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800152inline bool Object::IsArtMethod() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800153 return GetClass<kVerifyFlags>()->IsArtMethodClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800154}
155
Mathieu Chartier4e305412014-02-19 10:54:44 -0800156template<VerifyObjectFlags kVerifyFlags>
Brian Carlstromea46f952013-07-30 01:26:50 -0700157inline ArtMethod* Object::AsArtMethod() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800158 DCHECK(IsArtMethod<kVerifyFlags>());
Brian Carlstromea46f952013-07-30 01:26:50 -0700159 return down_cast<ArtMethod*>(this);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800160}
161
Mathieu Chartier4e305412014-02-19 10:54:44 -0800162template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800163inline bool Object::IsReferenceInstance() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800164 return GetClass<kVerifyFlags>()->IsReferenceClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800165}
166
Mathieu Chartier4e305412014-02-19 10:54:44 -0800167template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800168inline Array* Object::AsArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800169 DCHECK(IsArrayInstance<kVerifyFlags>());
Ian Rogers05f30572013-02-20 12:13:11 -0800170 return down_cast<Array*>(this);
171}
172
Mathieu Chartier4e305412014-02-19 10:54:44 -0800173template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800174inline BooleanArray* Object::AsBooleanArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800175 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
176 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
177 DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean());
Ian Rogers05f30572013-02-20 12:13:11 -0800178 return down_cast<BooleanArray*>(this);
179}
180
Mathieu Chartier4e305412014-02-19 10:54:44 -0800181template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800182inline ByteArray* Object::AsByteArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800183 static const VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
184 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
185 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte());
Ian Rogers05f30572013-02-20 12:13:11 -0800186 return down_cast<ByteArray*>(this);
187}
188
Mathieu Chartier4e305412014-02-19 10:54:44 -0800189template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800190inline ByteArray* Object::AsByteSizedArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800191 constexpr VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
192 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
193 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() ||
194 GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800195 return down_cast<ByteArray*>(this);
196}
197
Mathieu Chartier4e305412014-02-19 10:54:44 -0800198template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800199inline CharArray* Object::AsCharArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800200 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
201 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
202 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
Ian Rogers05f30572013-02-20 12:13:11 -0800203 return down_cast<CharArray*>(this);
204}
205
Mathieu Chartier4e305412014-02-19 10:54:44 -0800206template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800207inline ShortArray* Object::AsShortArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800208 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
209 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
210 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort());
Ian Rogers05f30572013-02-20 12:13:11 -0800211 return down_cast<ShortArray*>(this);
212}
213
Mathieu Chartier4e305412014-02-19 10:54:44 -0800214template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800215inline ShortArray* Object::AsShortSizedArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800216 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
217 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
218 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() ||
219 GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800220 return down_cast<ShortArray*>(this);
221}
222
Mathieu Chartier4e305412014-02-19 10:54:44 -0800223template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800224inline IntArray* Object::AsIntArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800225 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
226 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
227 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveInt() ||
228 GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
Ian Rogers05f30572013-02-20 12:13:11 -0800229 return down_cast<IntArray*>(this);
230}
231
Mathieu Chartier4e305412014-02-19 10:54:44 -0800232template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800233inline LongArray* Object::AsLongArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800234 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
235 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
236 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveLong() ||
237 GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
Ian Rogers05f30572013-02-20 12:13:11 -0800238 return down_cast<LongArray*>(this);
239}
240
Mathieu Chartier4e305412014-02-19 10:54:44 -0800241template<VerifyObjectFlags kVerifyFlags>
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100242inline FloatArray* Object::AsFloatArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800243 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
244 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
245 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100246 return down_cast<FloatArray*>(this);
247}
248
Mathieu Chartier4e305412014-02-19 10:54:44 -0800249template<VerifyObjectFlags kVerifyFlags>
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100250inline DoubleArray* Object::AsDoubleArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800251 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
252 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
253 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100254 return down_cast<DoubleArray*>(this);
255}
256
Mathieu Chartier4e305412014-02-19 10:54:44 -0800257template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800258inline String* Object::AsString() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800259 DCHECK(GetClass<kVerifyFlags>()->IsStringClass());
Ian Rogers05f30572013-02-20 12:13:11 -0800260 return down_cast<String*>(this);
261}
262
Mathieu Chartier4e305412014-02-19 10:54:44 -0800263template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800264inline Throwable* Object::AsThrowable() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800265 DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass());
Ian Rogers05f30572013-02-20 12:13:11 -0800266 return down_cast<Throwable*>(this);
267}
268
Mathieu Chartier4e305412014-02-19 10:54:44 -0800269template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800270inline bool Object::IsWeakReferenceInstance() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800271 return GetClass<kVerifyFlags>()->IsWeakReferenceClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800272}
273
Mathieu Chartier4e305412014-02-19 10:54:44 -0800274template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800275inline bool Object::IsSoftReferenceInstance() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800276 return GetClass<kVerifyFlags>()->IsSoftReferenceClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800277}
278
Mathieu Chartier4e305412014-02-19 10:54:44 -0800279template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800280inline bool Object::IsFinalizerReferenceInstance() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800281 return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800282}
283
Mathieu Chartier4e305412014-02-19 10:54:44 -0800284template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800285inline bool Object::IsPhantomReferenceInstance() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800286 return GetClass<kVerifyFlags>()->IsPhantomReferenceClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800287}
288
Mathieu Chartier4e305412014-02-19 10:54:44 -0800289template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800290inline size_t Object::SizeOf() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800291 size_t result;
Mathieu Chartier4e305412014-02-19 10:54:44 -0800292 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
293 if (IsArrayInstance<kVerifyFlags>()) {
294 result = AsArray<kNewFlags>()->SizeOf<>();
295 } else if (IsClass<kNewFlags>()) {
296 result = AsClass<kNewFlags>()->SizeOf<kNewFlags>();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800297 } else {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800298 result = GetClass<kNewFlags>()->GetObjectSize();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800299 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800300 DCHECK_GE(result, sizeof(Object)) << " class=" << PrettyTypeOf(GetClass<kNewFlags>());
301 DCHECK(!IsArtField<kNewFlags>() || result == sizeof(ArtField));
302 DCHECK(!IsArtMethod<kNewFlags>() || result == sizeof(ArtMethod));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800303 return result;
304}
305
Mathieu Chartier4e305412014-02-19 10:54:44 -0800306template<VerifyObjectFlags kVerifyFlags>
Ian Rogers29501cf2014-02-07 21:00:25 -0800307inline int32_t Object::GetField32(MemberOffset field_offset, bool is_volatile) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800308 if (kVerifyFlags & kVerifyThis) {
309 VerifyObject(this);
310 }
Ian Rogersb122a4b2013-11-19 18:00:50 -0800311 const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
312 const int32_t* word_addr = reinterpret_cast<const int32_t*>(raw_addr);
313 if (UNLIKELY(is_volatile)) {
314 int32_t result = *(reinterpret_cast<volatile int32_t*>(const_cast<int32_t*>(word_addr)));
Ian Rogersef7d42f2014-01-06 12:55:46 -0800315 QuasiAtomic::MembarLoadLoad(); // Ensure volatile loads don't re-order.
Ian Rogersb122a4b2013-11-19 18:00:50 -0800316 return result;
317 } else {
318 return *word_addr;
319 }
320}
321
Mathieu Chartier4e305412014-02-19 10:54:44 -0800322template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
323inline void Object::SetField32(MemberOffset field_offset, int32_t new_value, bool is_volatile) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100324 if (kCheckTransaction) {
325 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
326 }
327 if (kTransactionActive) {
328 Runtime::Current()->RecordWriteField32(this, field_offset, GetField32(field_offset, is_volatile),
329 is_volatile);
330 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800331 if (kVerifyFlags & kVerifyThis) {
Ian Rogersb122a4b2013-11-19 18:00:50 -0800332 VerifyObject(this);
333 }
334 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
Ian Rogers29501cf2014-02-07 21:00:25 -0800335 int32_t* word_addr = reinterpret_cast<int32_t*>(raw_addr);
Ian Rogersb122a4b2013-11-19 18:00:50 -0800336 if (UNLIKELY(is_volatile)) {
337 QuasiAtomic::MembarStoreStore(); // Ensure this store occurs after others in the queue.
338 *word_addr = new_value;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800339 QuasiAtomic::MembarStoreLoad(); // Ensure this store occurs before any volatile loads.
Ian Rogersb122a4b2013-11-19 18:00:50 -0800340 } else {
341 *word_addr = new_value;
342 }
343}
344
Mathieu Chartier4e305412014-02-19 10:54:44 -0800345template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
Ian Rogers29501cf2014-02-07 21:00:25 -0800346inline bool Object::CasField32(MemberOffset field_offset, int32_t old_value, int32_t new_value) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100347 if (kCheckTransaction) {
348 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
349 }
350 if (kTransactionActive) {
351 Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
352 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800353 if (kVerifyFlags & kVerifyThis) {
354 VerifyObject(this);
355 }
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700356 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
Ian Rogers29501cf2014-02-07 21:00:25 -0800357 volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr);
Ian Rogersb122a4b2013-11-19 18:00:50 -0800358 return __sync_bool_compare_and_swap(addr, old_value, new_value);
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700359}
360
Mathieu Chartier4e305412014-02-19 10:54:44 -0800361template<VerifyObjectFlags kVerifyFlags>
Ian Rogers29501cf2014-02-07 21:00:25 -0800362inline int64_t Object::GetField64(MemberOffset field_offset, bool is_volatile) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800363 if (kVerifyFlags & kVerifyThis) {
364 VerifyObject(this);
365 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800366 const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
367 const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr);
368 if (UNLIKELY(is_volatile)) {
Ian Rogers29501cf2014-02-07 21:00:25 -0800369 int64_t result = QuasiAtomic::Read64(addr);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800370 QuasiAtomic::MembarLoadLoad(); // Ensure volatile loads don't re-order.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800371 return result;
372 } else {
373 return *addr;
374 }
375}
376
Mathieu Chartier4e305412014-02-19 10:54:44 -0800377template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
378inline void Object::SetField64(MemberOffset field_offset, int64_t new_value, bool is_volatile) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100379 if (kCheckTransaction) {
380 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
381 }
382 if (kTransactionActive) {
383 Runtime::Current()->RecordWriteField64(this, field_offset, GetField64(field_offset, is_volatile),
384 is_volatile);
385 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800386 if (kVerifyFlags & kVerifyThis) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800387 VerifyObject(this);
388 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800389 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
390 int64_t* addr = reinterpret_cast<int64_t*>(raw_addr);
391 if (UNLIKELY(is_volatile)) {
Ian Rogersb122a4b2013-11-19 18:00:50 -0800392 QuasiAtomic::MembarStoreStore(); // Ensure this store occurs after others in the queue.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800393 QuasiAtomic::Write64(addr, new_value);
Ian Rogersb122a4b2013-11-19 18:00:50 -0800394 if (!QuasiAtomic::LongAtomicsUseMutexes()) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800395 QuasiAtomic::MembarStoreLoad(); // Ensure this store occurs before any volatile loads.
Ian Rogersb122a4b2013-11-19 18:00:50 -0800396 } else {
397 // Fence from from mutex is enough.
398 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800399 } else {
400 *addr = new_value;
401 }
402}
403
Mathieu Chartier4e305412014-02-19 10:54:44 -0800404template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
Ian Rogers29501cf2014-02-07 21:00:25 -0800405inline bool Object::CasField64(MemberOffset field_offset, int64_t old_value, int64_t new_value) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100406 if (kCheckTransaction) {
407 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
408 }
409 if (kTransactionActive) {
410 Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
411 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800412 if (kVerifyFlags & kVerifyThis) {
413 VerifyObject(this);
414 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800415 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
Ian Rogers29501cf2014-02-07 21:00:25 -0800416 volatile int64_t* addr = reinterpret_cast<volatile int64_t*>(raw_addr);
417 return QuasiAtomic::Cas64(old_value, new_value, addr);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800418}
419
Mathieu Chartier4e305412014-02-19 10:54:44 -0800420template<class T, VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800421inline T* Object::GetFieldObject(MemberOffset field_offset, bool is_volatile) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800422 if (kVerifyFlags & kVerifyThis) {
423 VerifyObject(this);
424 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800425 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
426 HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr);
427 HeapReference<T> objref = *objref_addr;
428
429 if (UNLIKELY(is_volatile)) {
430 QuasiAtomic::MembarLoadLoad(); // Ensure loads don't re-order.
431 }
432 T* result = objref.AsMirrorPtr();
Mathieu Chartier4e305412014-02-19 10:54:44 -0800433 if (kVerifyFlags & kVerifyReads) {
434 VerifyObject(result);
435 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800436 return result;
437}
438
Mathieu Chartier4e305412014-02-19 10:54:44 -0800439template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800440inline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset, Object* new_value,
Mathieu Chartier4e305412014-02-19 10:54:44 -0800441 bool is_volatile) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100442 if (kCheckTransaction) {
443 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
444 }
445 if (kTransactionActive) {
446 Runtime::Current()->RecordWriteFieldReference(this, field_offset,
447 GetFieldObject<Object>(field_offset, is_volatile),
448 true);
449 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800450 if (kVerifyFlags & kVerifyThis) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800451 VerifyObject(this);
452 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800453 if (kVerifyFlags & kVerifyWrites) {
454 VerifyObject(new_value);
455 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800456 HeapReference<Object> objref(HeapReference<Object>::FromMirrorPtr(new_value));
457 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
458 HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr);
459 if (UNLIKELY(is_volatile)) {
460 QuasiAtomic::MembarStoreStore(); // Ensure this store occurs after others in the queue.
461 objref_addr->Assign(new_value);
462 QuasiAtomic::MembarStoreLoad(); // Ensure this store occurs before any loads.
463 } else {
464 objref_addr->Assign(new_value);
465 }
466}
467
Mathieu Chartier4e305412014-02-19 10:54:44 -0800468template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
469inline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value, bool is_volatile) {
470 SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags>(
471 field_offset, new_value, is_volatile);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800472 if (new_value != nullptr) {
473 CheckFieldAssignment(field_offset, new_value);
474 Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
475 }
476}
477
Mathieu Chartier4e305412014-02-19 10:54:44 -0800478template <VerifyObjectFlags kVerifyFlags>
479inline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) {
480 if (kVerifyFlags & kVerifyThis) {
481 VerifyObject(this);
482 }
483 return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<byte*>(this) +
484 field_offset.Int32Value());
485}
486
487template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
488inline bool Object::CasFieldObject(MemberOffset field_offset, Object* old_value,
489 Object* new_value) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100490 if (kCheckTransaction) {
491 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
492 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800493 if (kVerifyFlags & kVerifyThis) {
494 VerifyObject(this);
495 }
496 if (kVerifyFlags & kVerifyWrites) {
497 VerifyObject(new_value);
498 }
499 if (kVerifyFlags & kVerifyReads) {
500 VerifyObject(old_value);
501 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100502 if (kTransactionActive) {
503 Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
504 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800505 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
Ian Rogers29501cf2014-02-07 21:00:25 -0800506 volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800507 HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
508 HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
509 bool success = __sync_bool_compare_and_swap(addr, old_ref.reference_, new_ref.reference_);
510 if (success) {
511 Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
512 }
513 return success;
514}
515
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800516} // namespace mirror
517} // namespace art
518
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700519#endif // ART_RUNTIME_MIRROR_OBJECT_INL_H_