blob: e460a8d1ccabad3736d389e5ed4b3c29c73f3e32 [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
35inline Class* Object::GetClass() const {
36 return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Object, klass_), false);
37}
38
39inline void Object::SetClass(Class* new_klass) {
40 // new_klass may be NULL prior to class linker initialization
41 // We don't mark the card since the class is guaranteed to be referenced from another location.
42 // Proxy classes are held live by the class loader, and other classes are roots of the class
43 // linker.
44 SetFieldPtr(OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass, false, false);
45}
46
Ian Rogersd9c4fc92013-10-01 19:45:43 -070047inline LockWord Object::GetLockWord() {
48 return LockWord(GetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), true));
49}
50
51inline void Object::SetLockWord(LockWord new_val) {
52 SetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue(), true);
53}
54
55inline bool Object::CasLockWord(LockWord old_val, LockWord new_val) {
56 return CasField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(),
57 new_val.GetValue());
58}
59
60inline uint32_t Object::GetLockOwnerThreadId() {
61 return Monitor::GetLockOwnerThreadId(this);
Ian Rogers05f30572013-02-20 12:13:11 -080062}
63
64inline void Object::MonitorEnter(Thread* self) {
65 Monitor::MonitorEnter(self, this);
66}
67
68inline bool Object::MonitorExit(Thread* self) {
69 return Monitor::MonitorExit(self, this);
70}
71
72inline void Object::Notify(Thread* self) {
73 Monitor::Notify(self, this);
74}
75
76inline void Object::NotifyAll(Thread* self) {
77 Monitor::NotifyAll(self, this);
78}
79
80inline void Object::Wait(Thread* self) {
81 Monitor::Wait(self, this, 0, 0, true, kWaiting);
82}
83
84inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
85 Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
86}
87
Jeff Haoa3faaf42013-09-03 19:07:00 -070088inline bool Object::VerifierInstanceOf(const Class* klass) const {
89 DCHECK(klass != NULL);
90 DCHECK(GetClass() != NULL);
91 return klass->IsInterface() || InstanceOf(klass);
92}
93
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080094inline bool Object::InstanceOf(const Class* klass) const {
95 DCHECK(klass != NULL);
96 DCHECK(GetClass() != NULL);
97 return klass->IsAssignableFrom(GetClass());
98}
99
100inline bool Object::IsClass() const {
101 Class* java_lang_Class = GetClass()->GetClass();
102 return GetClass() == java_lang_Class;
103}
104
105inline Class* Object::AsClass() {
106 DCHECK(IsClass());
107 return down_cast<Class*>(this);
108}
109
110inline const Class* Object::AsClass() const {
111 DCHECK(IsClass());
112 return down_cast<const Class*>(this);
113}
114
115inline bool Object::IsObjectArray() const {
116 return IsArrayInstance() && !GetClass()->GetComponentType()->IsPrimitive();
117}
118
119template<class T>
120inline ObjectArray<T>* Object::AsObjectArray() {
121 DCHECK(IsObjectArray());
122 return down_cast<ObjectArray<T>*>(this);
123}
124
125template<class T>
126inline const ObjectArray<T>* Object::AsObjectArray() const {
127 DCHECK(IsObjectArray());
128 return down_cast<const ObjectArray<T>*>(this);
129}
130
131inline bool Object::IsArrayInstance() const {
132 return GetClass()->IsArrayClass();
133}
134
Brian Carlstromea46f952013-07-30 01:26:50 -0700135inline bool Object::IsArtField() const {
136 return GetClass()->IsArtFieldClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800137}
138
Brian Carlstromea46f952013-07-30 01:26:50 -0700139inline ArtField* Object::AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
140 DCHECK(IsArtField());
141 return down_cast<ArtField*>(this);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800142}
143
Brian Carlstromea46f952013-07-30 01:26:50 -0700144inline const ArtField* Object::AsArtField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
145 DCHECK(IsArtField());
146 return down_cast<const ArtField*>(this);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800147}
148
Brian Carlstromea46f952013-07-30 01:26:50 -0700149inline bool Object::IsArtMethod() const {
150 return GetClass()->IsArtMethodClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800151}
152
Brian Carlstromea46f952013-07-30 01:26:50 -0700153inline ArtMethod* Object::AsArtMethod() {
154 DCHECK(IsArtMethod());
155 return down_cast<ArtMethod*>(this);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800156}
157
Brian Carlstromea46f952013-07-30 01:26:50 -0700158inline const ArtMethod* Object::AsArtMethod() const {
159 DCHECK(IsArtMethod());
160 return down_cast<const ArtMethod*>(this);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800161}
162
163inline bool Object::IsReferenceInstance() const {
164 return GetClass()->IsReferenceClass();
165}
166
Ian Rogers05f30572013-02-20 12:13:11 -0800167inline Array* Object::AsArray() {
168 DCHECK(IsArrayInstance());
169 return down_cast<Array*>(this);
170}
171
172inline const Array* Object::AsArray() const {
173 DCHECK(IsArrayInstance());
174 return down_cast<const Array*>(this);
175}
176
177inline BooleanArray* Object::AsBooleanArray() {
178 DCHECK(GetClass()->IsArrayClass());
179 DCHECK(GetClass()->GetComponentType()->IsPrimitiveBoolean());
180 return down_cast<BooleanArray*>(this);
181}
182
183inline ByteArray* Object::AsByteArray() {
184 DCHECK(GetClass()->IsArrayClass());
185 DCHECK(GetClass()->GetComponentType()->IsPrimitiveByte());
186 return down_cast<ByteArray*>(this);
187}
188
189inline CharArray* Object::AsCharArray() {
190 DCHECK(GetClass()->IsArrayClass());
191 DCHECK(GetClass()->GetComponentType()->IsPrimitiveChar());
192 return down_cast<CharArray*>(this);
193}
194
195inline ShortArray* Object::AsShortArray() {
196 DCHECK(GetClass()->IsArrayClass());
197 DCHECK(GetClass()->GetComponentType()->IsPrimitiveShort());
198 return down_cast<ShortArray*>(this);
199}
200
201inline IntArray* Object::AsIntArray() {
202 DCHECK(GetClass()->IsArrayClass());
203 DCHECK(GetClass()->GetComponentType()->IsPrimitiveInt() ||
204 GetClass()->GetComponentType()->IsPrimitiveFloat());
205 return down_cast<IntArray*>(this);
206}
207
208inline LongArray* Object::AsLongArray() {
209 DCHECK(GetClass()->IsArrayClass());
210 DCHECK(GetClass()->GetComponentType()->IsPrimitiveLong() ||
211 GetClass()->GetComponentType()->IsPrimitiveDouble());
212 return down_cast<LongArray*>(this);
213}
214
215inline String* Object::AsString() {
216 DCHECK(GetClass()->IsStringClass());
217 return down_cast<String*>(this);
218}
219
220inline Throwable* Object::AsThrowable() {
221 DCHECK(GetClass()->IsThrowableClass());
222 return down_cast<Throwable*>(this);
223}
224
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800225inline bool Object::IsWeakReferenceInstance() const {
226 return GetClass()->IsWeakReferenceClass();
227}
228
229inline bool Object::IsSoftReferenceInstance() const {
230 return GetClass()->IsSoftReferenceClass();
231}
232
233inline bool Object::IsFinalizerReferenceInstance() const {
234 return GetClass()->IsFinalizerReferenceClass();
235}
236
237inline bool Object::IsPhantomReferenceInstance() const {
238 return GetClass()->IsPhantomReferenceClass();
239}
240
241inline size_t Object::SizeOf() const {
242 size_t result;
243 if (IsArrayInstance()) {
244 result = AsArray()->SizeOf();
245 } else if (IsClass()) {
246 result = AsClass()->SizeOf();
247 } else {
248 result = GetClass()->GetObjectSize();
249 }
Mathieu Chartier79b4f382013-10-23 15:21:37 -0700250 DCHECK_GE(result, sizeof(Object)) << " class=" << PrettyTypeOf(GetClass());
Brian Carlstromea46f952013-07-30 01:26:50 -0700251 DCHECK(!IsArtField() || result == sizeof(ArtField));
252 DCHECK(!IsArtMethod() || result == sizeof(ArtMethod));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800253 return result;
254}
255
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700256inline bool Object::CasField32(MemberOffset field_offset, uint32_t old_value, uint32_t new_value) {
257 VerifyObject(this);
258 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
259 int32_t* addr = reinterpret_cast<int32_t*>(raw_addr);
260 return android_atomic_release_cas(old_value, new_value, addr) == 0;
261}
262
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800263inline uint64_t Object::GetField64(MemberOffset field_offset, bool is_volatile) const {
264 VerifyObject(this);
265 const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
266 const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr);
267 if (UNLIKELY(is_volatile)) {
268 uint64_t result = QuasiAtomic::Read64(addr);
269 ANDROID_MEMBAR_FULL();
270 return result;
271 } else {
272 return *addr;
273 }
274}
275
276inline void Object::SetField64(MemberOffset field_offset, uint64_t new_value, bool is_volatile) {
277 VerifyObject(this);
278 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
279 int64_t* addr = reinterpret_cast<int64_t*>(raw_addr);
280 if (UNLIKELY(is_volatile)) {
281 ANDROID_MEMBAR_STORE();
282 QuasiAtomic::Write64(addr, new_value);
283 // Post-store barrier not required due to use of atomic op or mutex.
284 } else {
285 *addr = new_value;
286 }
287}
288
289inline void Object::WriteBarrierField(const Object* dst, MemberOffset field_offset,
290 const Object* new_value) {
291 Runtime::Current()->GetHeap()->WriteBarrierField(dst, field_offset, new_value);
292}
293
Ian Rogers04d7aa92013-03-16 14:29:17 -0700294inline void Object::VerifyObject(const Object* obj) {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700295 if (kIsDebugBuild) {
296 Runtime::Current()->GetHeap()->VerifyObject(obj);
297 }
Ian Rogers04d7aa92013-03-16 14:29:17 -0700298}
299
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800300} // namespace mirror
301} // namespace art
302
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700303#endif // ART_RUNTIME_MIRROR_OBJECT_INL_H_