blob: 2581fad74006dc550a61b68d6a9b33318388fcf6 [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"
Mathieu Chartier52e4b432014-06-10 11:22:31 -070029#include "object_array-inl.h"
Hiroshi Yamauchi800ac2d2014-04-02 17:32:54 -070030#include "read_barrier-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080031#include "runtime.h"
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -070032#include "reference.h"
Ian Rogers05f30572013-02-20 12:13:11 -080033#include "throwable.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080034
35namespace art {
36namespace mirror {
37
Mingyao Yang98d1cc82014-05-15 17:02:16 -070038inline uint32_t Object::ClassSize() {
39 uint32_t vtable_entries = kVTableLength;
Fred Shih37f05ef2014-07-16 18:38:08 -070040 return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0);
Mingyao Yang98d1cc82014-05-15 17:02:16 -070041}
42
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -070043template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Ian Rogersef7d42f2014-01-06 12:55:46 -080044inline Class* Object::GetClass() {
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -070045 return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070046 OFFSET_OF_OBJECT_MEMBER(Object, klass_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080047}
48
Mathieu Chartier4e305412014-02-19 10:54:44 -080049template<VerifyObjectFlags kVerifyFlags>
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080050inline void Object::SetClass(Class* new_klass) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -070051 // new_klass may be null prior to class linker initialization.
Ian Rogersef7d42f2014-01-06 12:55:46 -080052 // We don't mark the card as this occurs as part of object allocation. Not all objects have
53 // backing cards, such as large objects.
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010054 // We use non transactional version since we can't undo this write. We also disable checking as
55 // we may run in transaction mode here.
Mathieu Chartier4e305412014-02-19 10:54:44 -080056 SetFieldObjectWithoutWriteBarrier<false, false,
57 static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>(
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070058 OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080059}
60
Mathieu Chartierbbd695c2014-04-16 09:48:48 -070061inline LockWord Object::GetLockWord(bool as_volatile) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070062 if (as_volatile) {
63 return LockWord(GetField32Volatile(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
64 }
65 return LockWord(GetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
Ian Rogersd9c4fc92013-10-01 19:45:43 -070066}
67
Mathieu Chartierbbd695c2014-04-16 09:48:48 -070068inline void Object::SetLockWord(LockWord new_val, bool as_volatile) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010069 // Force use of non-transactional mode and do not check.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070070 if (as_volatile) {
71 SetField32Volatile<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
72 } else {
73 SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
74 }
Ian Rogersd9c4fc92013-10-01 19:45:43 -070075}
76
Ian Rogers228602f2014-07-10 02:07:54 -070077inline bool Object::CasLockWordWeakSequentiallyConsistent(LockWord old_val, LockWord new_val) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010078 // Force use of non-transactional mode and do not check.
Ian Rogers228602f2014-07-10 02:07:54 -070079 return CasFieldWeakSequentiallyConsistent32<false, false>(
80 OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
Ian Rogersd9c4fc92013-10-01 19:45:43 -070081}
82
Hans Boehmd8434432014-07-11 09:56:07 -070083inline bool Object::CasLockWordWeakRelaxed(LockWord old_val, LockWord new_val) {
84 // Force use of non-transactional mode and do not check.
85 return CasFieldWeakRelaxed32<false, false>(
86 OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
87}
88
Ian Rogersd9c4fc92013-10-01 19:45:43 -070089inline uint32_t Object::GetLockOwnerThreadId() {
90 return Monitor::GetLockOwnerThreadId(this);
Ian Rogers05f30572013-02-20 12:13:11 -080091}
92
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -080093inline mirror::Object* Object::MonitorEnter(Thread* self) {
94 return Monitor::MonitorEnter(self, this);
Ian Rogers05f30572013-02-20 12:13:11 -080095}
96
97inline bool Object::MonitorExit(Thread* self) {
98 return Monitor::MonitorExit(self, this);
99}
100
101inline void Object::Notify(Thread* self) {
102 Monitor::Notify(self, this);
103}
104
105inline void Object::NotifyAll(Thread* self) {
106 Monitor::NotifyAll(self, this);
107}
108
109inline void Object::Wait(Thread* self) {
110 Monitor::Wait(self, this, 0, 0, true, kWaiting);
111}
112
113inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
114 Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
115}
116
Hiroshi Yamauchi624468c2014-03-31 15:14:47 -0700117inline Object* Object::GetReadBarrierPointer() {
118#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
119 DCHECK(kUseBakerOrBrooksReadBarrier);
Hiroshi Yamauchi6a154a42014-05-02 14:26:13 -0700120 return GetFieldObject<Object, kVerifyNone, kWithoutReadBarrier>(
121 OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_));
Hiroshi Yamauchi9d04a202014-01-31 13:35:49 -0800122#else
123 LOG(FATAL) << "Unreachable";
Ian Rogers2c4257b2014-10-24 14:20:06 -0700124 UNREACHABLE();
Hiroshi Yamauchi9d04a202014-01-31 13:35:49 -0800125#endif
126}
127
Hiroshi Yamauchi9103c862014-04-22 13:51:07 -0700128inline void Object::SetReadBarrierPointer(Object* rb_ptr) {
Hiroshi Yamauchi624468c2014-03-31 15:14:47 -0700129#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
130 DCHECK(kUseBakerOrBrooksReadBarrier);
Hiroshi Yamauchi9d04a202014-01-31 13:35:49 -0800131 // We don't mark the card as this occurs as part of object allocation. Not all objects have
132 // backing cards, such as large objects.
133 SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>(
Hiroshi Yamauchi6a154a42014-05-02 14:26:13 -0700134 OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_ptr);
Hiroshi Yamauchi9d04a202014-01-31 13:35:49 -0800135#else
136 LOG(FATAL) << "Unreachable";
Ian Rogers2c4257b2014-10-24 14:20:06 -0700137 UNREACHABLE();
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700138 UNUSED(rb_ptr);
Hiroshi Yamauchi9d04a202014-01-31 13:35:49 -0800139#endif
140}
141
Hiroshi Yamauchi9103c862014-04-22 13:51:07 -0700142inline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) {
143#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
144 DCHECK(kUseBakerOrBrooksReadBarrier);
145 MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_);
Ian Rogers13735952014-10-08 12:43:28 -0700146 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + offset.SizeValue();
Ian Rogers228602f2014-07-10 02:07:54 -0700147 Atomic<uint32_t>* atomic_rb_ptr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
Hiroshi Yamauchi9103c862014-04-22 13:51:07 -0700148 HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr));
149 HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr));
Hiroshi Yamauchi9103c862014-04-22 13:51:07 -0700150 do {
Ian Rogers228602f2014-07-10 02:07:54 -0700151 if (UNLIKELY(atomic_rb_ptr->LoadRelaxed() != expected_ref.reference_)) {
Hiroshi Yamauchi9103c862014-04-22 13:51:07 -0700152 // Lost the race.
153 return false;
154 }
Ian Rogers228602f2014-07-10 02:07:54 -0700155 } while (!atomic_rb_ptr->CompareExchangeWeakSequentiallyConsistent(expected_ref.reference_,
156 new_ref.reference_));
Hiroshi Yamauchi9103c862014-04-22 13:51:07 -0700157 return true;
158#else
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700159 UNUSED(expected_rb_ptr, rb_ptr);
Hiroshi Yamauchi9103c862014-04-22 13:51:07 -0700160 LOG(FATAL) << "Unreachable";
Ian Rogers2c4257b2014-10-24 14:20:06 -0700161 UNREACHABLE();
Hiroshi Yamauchi9103c862014-04-22 13:51:07 -0700162#endif
163}
164
Hiroshi Yamauchi624468c2014-03-31 15:14:47 -0700165inline void Object::AssertReadBarrierPointer() const {
Hiroshi Yamauchi800ac2d2014-04-02 17:32:54 -0700166 if (kUseBakerReadBarrier) {
167 Object* obj = const_cast<Object*>(this);
168 DCHECK(obj->GetReadBarrierPointer() == nullptr)
169 << "Bad Baker pointer: obj=" << reinterpret_cast<void*>(obj)
170 << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
Ian Rogers2c4257b2014-10-24 14:20:06 -0700171 } else {
172 CHECK(kUseBrooksReadBarrier);
Hiroshi Yamauchi800ac2d2014-04-02 17:32:54 -0700173 Object* obj = const_cast<Object*>(this);
174 DCHECK_EQ(obj, obj->GetReadBarrierPointer())
175 << "Bad Brooks pointer: obj=" << reinterpret_cast<void*>(obj)
176 << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
Hiroshi Yamauchi800ac2d2014-04-02 17:32:54 -0700177 }
Hiroshi Yamauchi9d04a202014-01-31 13:35:49 -0800178}
179
Mathieu Chartier4e305412014-02-19 10:54:44 -0800180template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800181inline bool Object::VerifierInstanceOf(Class* klass) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700182 DCHECK(klass != nullptr);
183 DCHECK(GetClass<kVerifyFlags>() != nullptr);
Jeff Haoa3faaf42013-09-03 19:07:00 -0700184 return klass->IsInterface() || InstanceOf(klass);
185}
186
Mathieu Chartier4e305412014-02-19 10:54:44 -0800187template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800188inline bool Object::InstanceOf(Class* klass) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700189 DCHECK(klass != nullptr);
190 DCHECK(GetClass<kVerifyNone>() != nullptr);
Mathieu Chartier4e305412014-02-19 10:54:44 -0800191 return klass->IsAssignableFrom(GetClass<kVerifyFlags>());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800192}
193
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700194template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800195inline bool Object::IsClass() {
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700196 Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
197 template GetClass<kVerifyFlags, kReadBarrierOption>();
198 return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis),
199 kReadBarrierOption>() == java_lang_Class;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800200}
201
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700202template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800203inline Class* Object::AsClass() {
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700204 DCHECK((IsClass<kVerifyFlags, kReadBarrierOption>()));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800205 return down_cast<Class*>(this);
206}
207
Mathieu Chartier4e305412014-02-19 10:54:44 -0800208template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800209inline bool Object::IsObjectArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800210 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
211 return IsArrayInstance<kVerifyFlags>() &&
212 !GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitive();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800213}
214
Mathieu Chartier4e305412014-02-19 10:54:44 -0800215template<class T, VerifyObjectFlags kVerifyFlags>
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800216inline ObjectArray<T>* Object::AsObjectArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800217 DCHECK(IsObjectArray<kVerifyFlags>());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800218 return down_cast<ObjectArray<T>*>(this);
219}
220
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700221template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800222inline bool Object::IsArrayInstance() {
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700223 return GetClass<kVerifyFlags, kReadBarrierOption>()->
224 template IsArrayClass<kVerifyFlags, kReadBarrierOption>();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800225}
226
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700227template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800228inline bool Object::IsArtMethod() {
Hiroshi Yamauchi4f1ebc22014-06-25 14:30:41 -0700229 return GetClass<kVerifyFlags, kReadBarrierOption>()->
230 template IsArtMethodClass<kReadBarrierOption>();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800231}
232
Mathieu Chartier4e305412014-02-19 10:54:44 -0800233template<VerifyObjectFlags kVerifyFlags>
Brian Carlstromea46f952013-07-30 01:26:50 -0700234inline ArtMethod* Object::AsArtMethod() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800235 DCHECK(IsArtMethod<kVerifyFlags>());
Brian Carlstromea46f952013-07-30 01:26:50 -0700236 return down_cast<ArtMethod*>(this);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800237}
238
Mathieu Chartier4e305412014-02-19 10:54:44 -0800239template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800240inline bool Object::IsReferenceInstance() {
Fred Shih4ee7a662014-07-11 09:59:27 -0700241 return GetClass<kVerifyFlags>()->IsTypeOfReferenceClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800242}
243
Mathieu Chartier4e305412014-02-19 10:54:44 -0800244template<VerifyObjectFlags kVerifyFlags>
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -0700245inline Reference* Object::AsReference() {
246 DCHECK(IsReferenceInstance<kVerifyFlags>());
247 return down_cast<Reference*>(this);
248}
249
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700250template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Ian Rogers05f30572013-02-20 12:13:11 -0800251inline Array* Object::AsArray() {
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700252 DCHECK((IsArrayInstance<kVerifyFlags, kReadBarrierOption>()));
Ian Rogers05f30572013-02-20 12:13:11 -0800253 return down_cast<Array*>(this);
254}
255
Mathieu Chartier4e305412014-02-19 10:54:44 -0800256template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800257inline BooleanArray* Object::AsBooleanArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800258 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
259 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
260 DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean());
Ian Rogers05f30572013-02-20 12:13:11 -0800261 return down_cast<BooleanArray*>(this);
262}
263
Mathieu Chartier4e305412014-02-19 10:54:44 -0800264template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800265inline ByteArray* Object::AsByteArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800266 static const VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
267 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
268 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte());
Ian Rogers05f30572013-02-20 12:13:11 -0800269 return down_cast<ByteArray*>(this);
270}
271
Mathieu Chartier4e305412014-02-19 10:54:44 -0800272template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800273inline ByteArray* Object::AsByteSizedArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800274 constexpr VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
275 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
276 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() ||
277 GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800278 return down_cast<ByteArray*>(this);
279}
280
Mathieu Chartier4e305412014-02-19 10:54:44 -0800281template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800282inline CharArray* Object::AsCharArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800283 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
284 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
285 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
Ian Rogers05f30572013-02-20 12:13:11 -0800286 return down_cast<CharArray*>(this);
287}
288
Mathieu Chartier4e305412014-02-19 10:54:44 -0800289template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800290inline ShortArray* Object::AsShortArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800291 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
292 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
293 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort());
Ian Rogers05f30572013-02-20 12:13:11 -0800294 return down_cast<ShortArray*>(this);
295}
296
Mathieu Chartier4e305412014-02-19 10:54:44 -0800297template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800298inline ShortArray* Object::AsShortSizedArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800299 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
300 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
301 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() ||
302 GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800303 return down_cast<ShortArray*>(this);
304}
305
Mathieu Chartier4e305412014-02-19 10:54:44 -0800306template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800307inline IntArray* Object::AsIntArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800308 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700309 CHECK(GetClass<kVerifyFlags>()->IsArrayClass());
310 CHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveInt() ||
Mathieu Chartier4e305412014-02-19 10:54:44 -0800311 GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
Ian Rogers05f30572013-02-20 12:13:11 -0800312 return down_cast<IntArray*>(this);
313}
314
Mathieu Chartier4e305412014-02-19 10:54:44 -0800315template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800316inline LongArray* Object::AsLongArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800317 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700318 CHECK(GetClass<kVerifyFlags>()->IsArrayClass());
319 CHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveLong() ||
Mathieu Chartier4e305412014-02-19 10:54:44 -0800320 GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
Ian Rogers05f30572013-02-20 12:13:11 -0800321 return down_cast<LongArray*>(this);
322}
323
Mathieu Chartier4e305412014-02-19 10:54:44 -0800324template<VerifyObjectFlags kVerifyFlags>
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100325inline FloatArray* Object::AsFloatArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800326 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
327 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
328 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100329 return down_cast<FloatArray*>(this);
330}
331
Mathieu Chartier4e305412014-02-19 10:54:44 -0800332template<VerifyObjectFlags kVerifyFlags>
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100333inline DoubleArray* Object::AsDoubleArray() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800334 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
335 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
336 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100337 return down_cast<DoubleArray*>(this);
338}
339
Mathieu Chartier4e305412014-02-19 10:54:44 -0800340template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800341inline String* Object::AsString() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800342 DCHECK(GetClass<kVerifyFlags>()->IsStringClass());
Ian Rogers05f30572013-02-20 12:13:11 -0800343 return down_cast<String*>(this);
344}
345
Mathieu Chartier4e305412014-02-19 10:54:44 -0800346template<VerifyObjectFlags kVerifyFlags>
Ian Rogers05f30572013-02-20 12:13:11 -0800347inline Throwable* Object::AsThrowable() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800348 DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass());
Ian Rogers05f30572013-02-20 12:13:11 -0800349 return down_cast<Throwable*>(this);
350}
351
Mathieu Chartier4e305412014-02-19 10:54:44 -0800352template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800353inline bool Object::IsWeakReferenceInstance() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800354 return GetClass<kVerifyFlags>()->IsWeakReferenceClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800355}
356
Mathieu Chartier4e305412014-02-19 10:54:44 -0800357template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800358inline bool Object::IsSoftReferenceInstance() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800359 return GetClass<kVerifyFlags>()->IsSoftReferenceClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800360}
361
Mathieu Chartier4e305412014-02-19 10:54:44 -0800362template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800363inline bool Object::IsFinalizerReferenceInstance() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800364 return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800365}
366
Mathieu Chartier4e305412014-02-19 10:54:44 -0800367template<VerifyObjectFlags kVerifyFlags>
Mathieu Chartier8fa2dad2014-03-13 12:22:56 -0700368inline FinalizerReference* Object::AsFinalizerReference() {
369 DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>());
370 return down_cast<FinalizerReference*>(this);
371}
372
373template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800374inline bool Object::IsPhantomReferenceInstance() {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800375 return GetClass<kVerifyFlags>()->IsPhantomReferenceClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800376}
377
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700378template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800379inline size_t Object::SizeOf() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800380 size_t result;
Mathieu Chartier4e305412014-02-19 10:54:44 -0800381 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700382 if (IsArrayInstance<kVerifyFlags, kReadBarrierOption>()) {
383 result = AsArray<kNewFlags, kReadBarrierOption>()->
384 template SizeOf<kNewFlags, kReadBarrierOption>();
385 } else if (IsClass<kNewFlags, kReadBarrierOption>()) {
386 result = AsClass<kNewFlags, kReadBarrierOption>()->
387 template SizeOf<kNewFlags, kReadBarrierOption>();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800388 } else {
Hiroshi Yamauchi25023c72014-05-09 11:45:53 -0700389 result = GetClass<kNewFlags, kReadBarrierOption>()->
390 template GetObjectSize<kNewFlags, kReadBarrierOption>();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800391 }
Hiroshi Yamauchi9103c862014-04-22 13:51:07 -0700392 DCHECK_GE(result, sizeof(Object))
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700393 << " class=" << PrettyTypeOf(GetClass<kNewFlags, kReadBarrierOption>());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800394 return result;
395}
396
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700397template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
Fred Shih37f05ef2014-07-16 18:38:08 -0700398inline uint8_t Object::GetFieldBoolean(MemberOffset field_offset) {
399 if (kVerifyFlags & kVerifyThis) {
400 VerifyObject(this);
401 }
402 return GetField<uint8_t, kIsVolatile>(field_offset);
403}
404
405template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
406inline int8_t Object::GetFieldByte(MemberOffset field_offset) {
407 if (kVerifyFlags & kVerifyThis) {
408 VerifyObject(this);
409 }
410 return GetField<int8_t, kIsVolatile>(field_offset);
411}
412
413template<VerifyObjectFlags kVerifyFlags>
414inline uint8_t Object::GetFieldBooleanVolatile(MemberOffset field_offset) {
415 return GetFieldBoolean<kVerifyFlags, true>(field_offset);
416}
417
418template<VerifyObjectFlags kVerifyFlags>
419inline int8_t Object::GetFieldByteVolatile(MemberOffset field_offset) {
420 return GetFieldByte<kVerifyFlags, true>(field_offset);
421}
422
423template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
424 bool kIsVolatile>
425inline void Object::SetFieldBoolean(MemberOffset field_offset, uint8_t new_value)
426 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
427 if (kCheckTransaction) {
428 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
429 }
430 if (kTransactionActive) {
431 Runtime::Current()->RecordWriteFieldBoolean(this, field_offset,
432 GetFieldBoolean<kVerifyFlags, kIsVolatile>(field_offset),
433 kIsVolatile);
434 }
435 if (kVerifyFlags & kVerifyThis) {
436 VerifyObject(this);
437 }
438 SetField<uint8_t, kIsVolatile>(field_offset, new_value);
439}
440
441template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
442 bool kIsVolatile>
443inline void Object::SetFieldByte(MemberOffset field_offset, int8_t new_value)
444 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
445 if (kCheckTransaction) {
446 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
447 }
448 if (kTransactionActive) {
449 Runtime::Current()->RecordWriteFieldByte(this, field_offset,
450 GetFieldByte<kVerifyFlags, kIsVolatile>(field_offset),
451 kIsVolatile);
452 }
453 if (kVerifyFlags & kVerifyThis) {
454 VerifyObject(this);
455 }
456 SetField<int8_t, kIsVolatile>(field_offset, new_value);
457}
458
459template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
460inline void Object::SetFieldBooleanVolatile(MemberOffset field_offset, uint8_t new_value) {
461 return SetFieldBoolean<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
462 field_offset, new_value);
463}
464
465template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
466inline void Object::SetFieldByteVolatile(MemberOffset field_offset, int8_t new_value) {
467 return SetFieldByte<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
468 field_offset, new_value);
469}
470
471template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
472inline uint16_t Object::GetFieldChar(MemberOffset field_offset) {
473 if (kVerifyFlags & kVerifyThis) {
474 VerifyObject(this);
475 }
476 return GetField<uint16_t, kIsVolatile>(field_offset);
477}
478
479template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
480inline int16_t Object::GetFieldShort(MemberOffset field_offset) {
481 if (kVerifyFlags & kVerifyThis) {
482 VerifyObject(this);
483 }
484 return GetField<int16_t, kIsVolatile>(field_offset);
485}
486
487template<VerifyObjectFlags kVerifyFlags>
488inline uint16_t Object::GetFieldCharVolatile(MemberOffset field_offset) {
489 return GetFieldChar<kVerifyFlags, true>(field_offset);
490}
491
492template<VerifyObjectFlags kVerifyFlags>
493inline int16_t Object::GetFieldShortVolatile(MemberOffset field_offset) {
494 return GetFieldShort<kVerifyFlags, true>(field_offset);
495}
496
497template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
498 bool kIsVolatile>
499inline void Object::SetFieldChar(MemberOffset field_offset, uint16_t new_value) {
500 if (kCheckTransaction) {
501 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
502 }
503 if (kTransactionActive) {
504 Runtime::Current()->RecordWriteFieldChar(this, field_offset,
505 GetFieldChar<kVerifyFlags, kIsVolatile>(field_offset),
506 kIsVolatile);
507 }
508 if (kVerifyFlags & kVerifyThis) {
509 VerifyObject(this);
510 }
511 SetField<uint16_t, kIsVolatile>(field_offset, new_value);
512}
513
514template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
515 bool kIsVolatile>
516inline void Object::SetFieldShort(MemberOffset field_offset, int16_t new_value) {
517 if (kCheckTransaction) {
518 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
519 }
520 if (kTransactionActive) {
521 Runtime::Current()->RecordWriteFieldChar(this, field_offset,
522 GetFieldShort<kVerifyFlags, kIsVolatile>(field_offset),
523 kIsVolatile);
524 }
525 if (kVerifyFlags & kVerifyThis) {
526 VerifyObject(this);
527 }
528 SetField<int16_t, kIsVolatile>(field_offset, new_value);
529}
530
531template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
532inline void Object::SetFieldCharVolatile(MemberOffset field_offset, uint16_t new_value) {
533 return SetFieldChar<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
534 field_offset, new_value);
535}
536
537template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
538inline void Object::SetFieldShortVolatile(MemberOffset field_offset, int16_t new_value) {
539 return SetFieldShort<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
540 field_offset, new_value);
541}
542
543template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700544inline int32_t Object::GetField32(MemberOffset field_offset) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800545 if (kVerifyFlags & kVerifyThis) {
546 VerifyObject(this);
547 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700548 return GetField<int32_t, kIsVolatile>(field_offset);
Ian Rogersb122a4b2013-11-19 18:00:50 -0800549}
550
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700551template<VerifyObjectFlags kVerifyFlags>
552inline int32_t Object::GetField32Volatile(MemberOffset field_offset) {
553 return GetField32<kVerifyFlags, true>(field_offset);
554}
555
556template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
557 bool kIsVolatile>
558inline void Object::SetField32(MemberOffset field_offset, int32_t new_value) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100559 if (kCheckTransaction) {
560 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
561 }
562 if (kTransactionActive) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700563 Runtime::Current()->RecordWriteField32(this, field_offset,
564 GetField32<kVerifyFlags, kIsVolatile>(field_offset),
565 kIsVolatile);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100566 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800567 if (kVerifyFlags & kVerifyThis) {
Ian Rogersb122a4b2013-11-19 18:00:50 -0800568 VerifyObject(this);
569 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700570 SetField<int32_t, kIsVolatile>(field_offset, new_value);
Ian Rogersb122a4b2013-11-19 18:00:50 -0800571}
572
Mathieu Chartier4e305412014-02-19 10:54:44 -0800573template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700574inline void Object::SetField32Volatile(MemberOffset field_offset, int32_t new_value) {
575 SetField32<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, new_value);
576}
577
Hans Boehmd8434432014-07-11 09:56:07 -0700578// TODO: Pass memory_order_ and strong/weak as arguments to avoid code duplication?
579
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700580template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
Ian Rogers228602f2014-07-10 02:07:54 -0700581inline bool Object::CasFieldWeakSequentiallyConsistent32(MemberOffset field_offset,
582 int32_t old_value, int32_t new_value) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100583 if (kCheckTransaction) {
584 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
585 }
586 if (kTransactionActive) {
587 Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
588 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800589 if (kVerifyFlags & kVerifyThis) {
590 VerifyObject(this);
591 }
Ian Rogers13735952014-10-08 12:43:28 -0700592 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
Ian Rogers228602f2014-07-10 02:07:54 -0700593 AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
Hans Boehm30359612014-05-21 17:46:23 -0700594
Ian Rogers228602f2014-07-10 02:07:54 -0700595 return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value);
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700596}
597
Hans Boehmd8434432014-07-11 09:56:07 -0700598template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
599inline bool Object::CasFieldWeakRelaxed32(MemberOffset field_offset,
600 int32_t old_value, int32_t new_value) {
601 if (kCheckTransaction) {
602 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
603 }
604 if (kTransactionActive) {
605 Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
606 }
607 if (kVerifyFlags & kVerifyThis) {
608 VerifyObject(this);
609 }
Ian Rogers13735952014-10-08 12:43:28 -0700610 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
Hans Boehmd8434432014-07-11 09:56:07 -0700611 AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
612
613 return atomic_addr->CompareExchangeWeakRelaxed(old_value, new_value);
614}
615
616template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
617inline bool Object::CasFieldStrongSequentiallyConsistent32(MemberOffset field_offset,
618 int32_t old_value, int32_t new_value) {
619 if (kCheckTransaction) {
620 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
621 }
622 if (kTransactionActive) {
623 Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
624 }
625 if (kVerifyFlags & kVerifyThis) {
626 VerifyObject(this);
627 }
Ian Rogers13735952014-10-08 12:43:28 -0700628 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
Hans Boehmd8434432014-07-11 09:56:07 -0700629 AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
630
631 return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value);
632}
633
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700634template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
635inline int64_t Object::GetField64(MemberOffset field_offset) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800636 if (kVerifyFlags & kVerifyThis) {
637 VerifyObject(this);
638 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700639 return GetField<int64_t, kIsVolatile>(field_offset);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800640}
641
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700642template<VerifyObjectFlags kVerifyFlags>
643inline int64_t Object::GetField64Volatile(MemberOffset field_offset) {
644 return GetField64<kVerifyFlags, true>(field_offset);
645}
646
647template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
648 bool kIsVolatile>
649inline void Object::SetField64(MemberOffset field_offset, int64_t new_value) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100650 if (kCheckTransaction) {
651 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
652 }
653 if (kTransactionActive) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700654 Runtime::Current()->RecordWriteField64(this, field_offset,
655 GetField64<kVerifyFlags, kIsVolatile>(field_offset),
656 kIsVolatile);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100657 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800658 if (kVerifyFlags & kVerifyThis) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800659 VerifyObject(this);
660 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700661 SetField<int64_t, kIsVolatile>(field_offset, new_value);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800662}
663
Mathieu Chartier4e305412014-02-19 10:54:44 -0800664template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700665inline void Object::SetField64Volatile(MemberOffset field_offset, int64_t new_value) {
666 return SetField64<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset,
667 new_value);
668}
669
Fred Shih37f05ef2014-07-16 18:38:08 -0700670template<typename kSize, bool kIsVolatile>
671inline void Object::SetField(MemberOffset field_offset, kSize new_value) {
Ian Rogers13735952014-10-08 12:43:28 -0700672 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
Fred Shih37f05ef2014-07-16 18:38:08 -0700673 kSize* addr = reinterpret_cast<kSize*>(raw_addr);
674 if (kIsVolatile) {
675 reinterpret_cast<Atomic<kSize>*>(addr)->StoreSequentiallyConsistent(new_value);
676 } else {
677 reinterpret_cast<Atomic<kSize>*>(addr)->StoreJavaData(new_value);
678 }
679}
680
681template<typename kSize, bool kIsVolatile>
682inline kSize Object::GetField(MemberOffset field_offset) {
Ian Rogers13735952014-10-08 12:43:28 -0700683 const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value();
Fred Shih37f05ef2014-07-16 18:38:08 -0700684 const kSize* addr = reinterpret_cast<const kSize*>(raw_addr);
685 if (kIsVolatile) {
686 return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadSequentiallyConsistent();
687 } else {
688 return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadJavaData();
689 }
690}
691
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700692template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
Ian Rogers228602f2014-07-10 02:07:54 -0700693inline bool Object::CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset,
694 int64_t old_value, int64_t new_value) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100695 if (kCheckTransaction) {
696 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
697 }
698 if (kTransactionActive) {
699 Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
700 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800701 if (kVerifyFlags & kVerifyThis) {
702 VerifyObject(this);
703 }
Ian Rogers13735952014-10-08 12:43:28 -0700704 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
Ian Rogers228602f2014-07-10 02:07:54 -0700705 Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
706 return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800707}
708
Hans Boehmd8434432014-07-11 09:56:07 -0700709template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
710inline bool Object::CasFieldStrongSequentiallyConsistent64(MemberOffset field_offset,
711 int64_t old_value, int64_t new_value) {
712 if (kCheckTransaction) {
713 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
714 }
715 if (kTransactionActive) {
716 Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
717 }
718 if (kVerifyFlags & kVerifyThis) {
719 VerifyObject(this);
720 }
Ian Rogers13735952014-10-08 12:43:28 -0700721 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
Hans Boehmd8434432014-07-11 09:56:07 -0700722 Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
723 return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value);
724}
725
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700726template<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption,
727 bool kIsVolatile>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700728inline T* Object::GetFieldObject(MemberOffset field_offset) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800729 if (kVerifyFlags & kVerifyThis) {
730 VerifyObject(this);
731 }
Ian Rogers13735952014-10-08 12:43:28 -0700732 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
Ian Rogersef7d42f2014-01-06 12:55:46 -0800733 HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr);
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700734 T* result = ReadBarrier::Barrier<T, kReadBarrierOption>(this, field_offset, objref_addr);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700735 if (kIsVolatile) {
Hans Boehm30359612014-05-21 17:46:23 -0700736 // TODO: Refactor to use a SequentiallyConsistent load instead.
737 QuasiAtomic::ThreadFenceAcquire(); // Ensure visibility of operations preceding store.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800738 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800739 if (kVerifyFlags & kVerifyReads) {
740 VerifyObject(result);
741 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800742 return result;
743}
744
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700745template<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700746inline T* Object::GetFieldObjectVolatile(MemberOffset field_offset) {
Hiroshi Yamauchi6e83c172014-05-01 21:25:41 -0700747 return GetFieldObject<T, kVerifyFlags, kReadBarrierOption, true>(field_offset);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700748}
749
750template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
751 bool kIsVolatile>
752inline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset,
753 Object* new_value) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100754 if (kCheckTransaction) {
755 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
756 }
757 if (kTransactionActive) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700758 mirror::Object* obj;
759 if (kIsVolatile) {
760 obj = GetFieldObjectVolatile<Object>(field_offset);
761 } else {
762 obj = GetFieldObject<Object>(field_offset);
763 }
764 Runtime::Current()->RecordWriteFieldReference(this, field_offset, obj, true);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100765 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800766 if (kVerifyFlags & kVerifyThis) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800767 VerifyObject(this);
768 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800769 if (kVerifyFlags & kVerifyWrites) {
770 VerifyObject(new_value);
771 }
Ian Rogers13735952014-10-08 12:43:28 -0700772 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
Ian Rogersef7d42f2014-01-06 12:55:46 -0800773 HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700774 if (kIsVolatile) {
Hans Boehm30359612014-05-21 17:46:23 -0700775 // TODO: Refactor to use a SequentiallyConsistent store instead.
776 QuasiAtomic::ThreadFenceRelease(); // Ensure that prior accesses are visible before store.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800777 objref_addr->Assign(new_value);
Hans Boehm30359612014-05-21 17:46:23 -0700778 QuasiAtomic::ThreadFenceSequentiallyConsistent();
779 // Ensure this store occurs before any volatile loads.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800780 } else {
781 objref_addr->Assign(new_value);
782 }
783}
784
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700785template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
786 bool kIsVolatile>
787inline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value) {
788 SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags,
789 kIsVolatile>(field_offset, new_value);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800790 if (new_value != nullptr) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800791 Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700792 // TODO: Check field assignment could theoretically cause thread suspension, TODO: fix this.
793 CheckFieldAssignment(field_offset, new_value);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800794 }
795}
796
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700797template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
798inline void Object::SetFieldObjectVolatile(MemberOffset field_offset, Object* new_value) {
799 SetFieldObject<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset,
800 new_value);
801}
802
Mathieu Chartier4e305412014-02-19 10:54:44 -0800803template <VerifyObjectFlags kVerifyFlags>
804inline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) {
805 if (kVerifyFlags & kVerifyThis) {
806 VerifyObject(this);
807 }
Ian Rogers13735952014-10-08 12:43:28 -0700808 return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<uint8_t*>(this) +
Mathieu Chartier4e305412014-02-19 10:54:44 -0800809 field_offset.Int32Value());
810}
811
812template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
Ian Rogers228602f2014-07-10 02:07:54 -0700813inline bool Object::CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset,
814 Object* old_value, Object* new_value) {
Hiroshi Yamauchi2cd334a2015-01-09 14:03:35 -0800815 bool success = CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier<
816 kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value);
817 if (success) {
818 Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
819 }
820 return success;
821}
822
823template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
824inline bool Object::CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier(
825 MemberOffset field_offset, Object* old_value, Object* new_value) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100826 if (kCheckTransaction) {
827 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
828 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800829 if (kVerifyFlags & kVerifyThis) {
830 VerifyObject(this);
831 }
832 if (kVerifyFlags & kVerifyWrites) {
833 VerifyObject(new_value);
834 }
835 if (kVerifyFlags & kVerifyReads) {
836 VerifyObject(old_value);
837 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100838 if (kTransactionActive) {
839 Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
840 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800841 HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
842 HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
Ian Rogers13735952014-10-08 12:43:28 -0700843 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
Ian Rogers228602f2014-07-10 02:07:54 -0700844 Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
845
846 bool success = atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_ref.reference_,
847 new_ref.reference_);
Hiroshi Yamauchi2cd334a2015-01-09 14:03:35 -0800848 return success;
849}
Ian Rogers228602f2014-07-10 02:07:54 -0700850
Hiroshi Yamauchi2cd334a2015-01-09 14:03:35 -0800851template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
852inline bool Object::CasFieldStrongSequentiallyConsistentObject(MemberOffset field_offset,
853 Object* old_value, Object* new_value) {
854 bool success = CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier<
855 kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800856 if (success) {
857 Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
858 }
859 return success;
860}
861
Hans Boehmd8434432014-07-11 09:56:07 -0700862template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
Hiroshi Yamauchi2cd334a2015-01-09 14:03:35 -0800863inline bool Object::CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier(
864 MemberOffset field_offset, Object* old_value, Object* new_value) {
Hans Boehmd8434432014-07-11 09:56:07 -0700865 if (kCheckTransaction) {
866 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
867 }
868 if (kVerifyFlags & kVerifyThis) {
869 VerifyObject(this);
870 }
871 if (kVerifyFlags & kVerifyWrites) {
872 VerifyObject(new_value);
873 }
874 if (kVerifyFlags & kVerifyReads) {
875 VerifyObject(old_value);
876 }
877 if (kTransactionActive) {
878 Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
879 }
880 HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
881 HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
Ian Rogers13735952014-10-08 12:43:28 -0700882 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
Hans Boehmd8434432014-07-11 09:56:07 -0700883 Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
884
885 bool success = atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_ref.reference_,
886 new_ref.reference_);
Hans Boehmd8434432014-07-11 09:56:07 -0700887 return success;
888}
889
Mathieu Chartier407f7022014-02-18 14:37:05 -0800890template<bool kVisitClass, bool kIsStatic, typename Visitor>
891inline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) {
Ian Rogerscdc1aaf2014-10-09 13:21:38 -0700892 if (!kIsStatic && (ref_offsets != mirror::Class::kClassWalkSuper)) {
893 // Instance fields and not the slow-path.
894 if (kVisitClass) {
895 visitor(this, ClassOffset(), kIsStatic);
Mathieu Chartier407f7022014-02-18 14:37:05 -0800896 }
Ian Rogerscdc1aaf2014-10-09 13:21:38 -0700897 uint32_t field_offset = mirror::kObjectHeaderSize;
Mathieu Chartier407f7022014-02-18 14:37:05 -0800898 while (ref_offsets != 0) {
Ian Rogerscdc1aaf2014-10-09 13:21:38 -0700899 if ((ref_offsets & 1) != 0) {
900 visitor(this, MemberOffset(field_offset), kIsStatic);
901 }
902 ref_offsets >>= 1;
903 field_offset += sizeof(mirror::HeapReference<mirror::Object>);
Mathieu Chartier407f7022014-02-18 14:37:05 -0800904 }
905 } else {
Mingyao Yangfaff0f02014-09-10 12:03:22 -0700906 // There is no reference offset bitmap. In the non-static case, walk up the class
Mathieu Chartier407f7022014-02-18 14:37:05 -0800907 // inheritance hierarchy and find reference offsets the hard way. In the static case, just
908 // consider this class.
909 for (mirror::Class* klass = kIsStatic ? AsClass() : GetClass(); klass != nullptr;
910 klass = kIsStatic ? nullptr : klass->GetSuperClass()) {
911 size_t num_reference_fields =
912 kIsStatic ? klass->NumReferenceStaticFields() : klass->NumReferenceInstanceFields();
Vladimir Marko76649e82014-11-10 18:32:59 +0000913 if (num_reference_fields == 0u) {
914 continue;
915 }
916 MemberOffset field_offset = kIsStatic
917 ? klass->GetFirstReferenceStaticFieldOffset()
918 : klass->GetFirstReferenceInstanceFieldOffset();
Mathieu Chartier407f7022014-02-18 14:37:05 -0800919 for (size_t i = 0; i < num_reference_fields; ++i) {
Mathieu Chartier407f7022014-02-18 14:37:05 -0800920 // TODO: Do a simpler check?
Mathieu Chartier52e4b432014-06-10 11:22:31 -0700921 if (kVisitClass || field_offset.Uint32Value() != ClassOffset().Uint32Value()) {
922 visitor(this, field_offset, kIsStatic);
Mathieu Chartier407f7022014-02-18 14:37:05 -0800923 }
Vladimir Marko76649e82014-11-10 18:32:59 +0000924 field_offset = MemberOffset(field_offset.Uint32Value() +
925 sizeof(mirror::HeapReference<mirror::Object>));
Mathieu Chartier407f7022014-02-18 14:37:05 -0800926 }
927 }
928 }
929}
930
931template<bool kVisitClass, typename Visitor>
932inline void Object::VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
933 VisitFieldsReferences<kVisitClass, false>(
934 klass->GetReferenceInstanceOffsets<kVerifyNone>(), visitor);
935}
936
937template<bool kVisitClass, typename Visitor>
938inline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700939 DCHECK(!klass->IsTemp());
Mingyao Yangfaff0f02014-09-10 12:03:22 -0700940 klass->VisitFieldsReferences<kVisitClass, true>(0, visitor);
Mathieu Chartier407f7022014-02-18 14:37:05 -0800941}
942
943template <const bool kVisitClass, VerifyObjectFlags kVerifyFlags, typename Visitor,
944 typename JavaLangRefVisitor>
945inline void Object::VisitReferences(const Visitor& visitor,
946 const JavaLangRefVisitor& ref_visitor) {
947 mirror::Class* klass = GetClass<kVerifyFlags>();
Mathieu Chartier52e4b432014-06-10 11:22:31 -0700948 if (klass == Class::GetJavaLangClass()) {
949 AsClass<kVerifyNone>()->VisitReferences<kVisitClass>(klass, visitor);
950 } else if (klass->IsArrayClass()) {
951 if (klass->IsObjectArrayClass<kVerifyNone>()) {
952 AsObjectArray<mirror::Object, kVerifyNone>()->VisitReferences<kVisitClass>(visitor);
953 } else if (kVisitClass) {
954 visitor(this, ClassOffset(), false);
Mathieu Chartier407f7022014-02-18 14:37:05 -0800955 }
956 } else {
Mathieu Chartier52e4b432014-06-10 11:22:31 -0700957 DCHECK(!klass->IsVariableSize());
Mathieu Chartier580a8df2014-03-26 15:15:57 -0700958 VisitInstanceFieldsReferences<kVisitClass>(klass, visitor);
Fred Shih4ee7a662014-07-11 09:59:27 -0700959 if (UNLIKELY(klass->IsTypeOfReferenceClass<kVerifyNone>())) {
Mathieu Chartier407f7022014-02-18 14:37:05 -0800960 ref_visitor(klass, AsReference());
961 }
962 }
963}
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800964} // namespace mirror
965} // namespace art
966
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700967#endif // ART_RUNTIME_MIRROR_OBJECT_INL_H_