blob: 5ed3db342ca4fbb7634fabb69106771561679f2f [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 Rogers05f30572013-02-20 12:13:11 -080027#include "monitor.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080028#include "runtime.h"
Ian Rogers05f30572013-02-20 12:13:11 -080029#include "throwable.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080030
31namespace art {
32namespace mirror {
33
34inline Class* Object::GetClass() const {
35 return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Object, klass_), false);
36}
37
38inline void Object::SetClass(Class* new_klass) {
39 // new_klass may be NULL prior to class linker initialization
40 // We don't mark the card since the class is guaranteed to be referenced from another location.
41 // Proxy classes are held live by the class loader, and other classes are roots of the class
42 // linker.
43 SetFieldPtr(OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass, false, false);
44}
45
Ian Rogers05f30572013-02-20 12:13:11 -080046inline uint32_t Object::GetThinLockId() {
47 return Monitor::GetThinLockId(monitor_);
48}
49
50inline void Object::MonitorEnter(Thread* self) {
51 Monitor::MonitorEnter(self, this);
52}
53
54inline bool Object::MonitorExit(Thread* self) {
55 return Monitor::MonitorExit(self, this);
56}
57
58inline void Object::Notify(Thread* self) {
59 Monitor::Notify(self, this);
60}
61
62inline void Object::NotifyAll(Thread* self) {
63 Monitor::NotifyAll(self, this);
64}
65
66inline void Object::Wait(Thread* self) {
67 Monitor::Wait(self, this, 0, 0, true, kWaiting);
68}
69
70inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
71 Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
72}
73
Jeff Haoa3faaf42013-09-03 19:07:00 -070074inline bool Object::VerifierInstanceOf(const Class* klass) const {
75 DCHECK(klass != NULL);
76 DCHECK(GetClass() != NULL);
77 return klass->IsInterface() || InstanceOf(klass);
78}
79
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080080inline bool Object::InstanceOf(const Class* klass) const {
81 DCHECK(klass != NULL);
82 DCHECK(GetClass() != NULL);
83 return klass->IsAssignableFrom(GetClass());
84}
85
86inline bool Object::IsClass() const {
87 Class* java_lang_Class = GetClass()->GetClass();
88 return GetClass() == java_lang_Class;
89}
90
91inline Class* Object::AsClass() {
92 DCHECK(IsClass());
93 return down_cast<Class*>(this);
94}
95
96inline const Class* Object::AsClass() const {
97 DCHECK(IsClass());
98 return down_cast<const Class*>(this);
99}
100
101inline bool Object::IsObjectArray() const {
102 return IsArrayInstance() && !GetClass()->GetComponentType()->IsPrimitive();
103}
104
105template<class T>
106inline ObjectArray<T>* Object::AsObjectArray() {
107 DCHECK(IsObjectArray());
108 return down_cast<ObjectArray<T>*>(this);
109}
110
111template<class T>
112inline const ObjectArray<T>* Object::AsObjectArray() const {
113 DCHECK(IsObjectArray());
114 return down_cast<const ObjectArray<T>*>(this);
115}
116
117inline bool Object::IsArrayInstance() const {
118 return GetClass()->IsArrayClass();
119}
120
Brian Carlstromea46f952013-07-30 01:26:50 -0700121inline bool Object::IsArtField() const {
122 return GetClass()->IsArtFieldClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800123}
124
Brian Carlstromea46f952013-07-30 01:26:50 -0700125inline ArtField* Object::AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
126 DCHECK(IsArtField());
127 return down_cast<ArtField*>(this);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800128}
129
Brian Carlstromea46f952013-07-30 01:26:50 -0700130inline const ArtField* Object::AsArtField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
131 DCHECK(IsArtField());
132 return down_cast<const ArtField*>(this);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800133}
134
Brian Carlstromea46f952013-07-30 01:26:50 -0700135inline bool Object::IsArtMethod() const {
136 return GetClass()->IsArtMethodClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800137}
138
Brian Carlstromea46f952013-07-30 01:26:50 -0700139inline ArtMethod* Object::AsArtMethod() {
140 DCHECK(IsArtMethod());
141 return down_cast<ArtMethod*>(this);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800142}
143
Brian Carlstromea46f952013-07-30 01:26:50 -0700144inline const ArtMethod* Object::AsArtMethod() const {
145 DCHECK(IsArtMethod());
146 return down_cast<const ArtMethod*>(this);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800147}
148
149inline bool Object::IsReferenceInstance() const {
150 return GetClass()->IsReferenceClass();
151}
152
Ian Rogers05f30572013-02-20 12:13:11 -0800153inline Array* Object::AsArray() {
154 DCHECK(IsArrayInstance());
155 return down_cast<Array*>(this);
156}
157
158inline const Array* Object::AsArray() const {
159 DCHECK(IsArrayInstance());
160 return down_cast<const Array*>(this);
161}
162
163inline BooleanArray* Object::AsBooleanArray() {
164 DCHECK(GetClass()->IsArrayClass());
165 DCHECK(GetClass()->GetComponentType()->IsPrimitiveBoolean());
166 return down_cast<BooleanArray*>(this);
167}
168
169inline ByteArray* Object::AsByteArray() {
170 DCHECK(GetClass()->IsArrayClass());
171 DCHECK(GetClass()->GetComponentType()->IsPrimitiveByte());
172 return down_cast<ByteArray*>(this);
173}
174
175inline CharArray* Object::AsCharArray() {
176 DCHECK(GetClass()->IsArrayClass());
177 DCHECK(GetClass()->GetComponentType()->IsPrimitiveChar());
178 return down_cast<CharArray*>(this);
179}
180
181inline ShortArray* Object::AsShortArray() {
182 DCHECK(GetClass()->IsArrayClass());
183 DCHECK(GetClass()->GetComponentType()->IsPrimitiveShort());
184 return down_cast<ShortArray*>(this);
185}
186
187inline IntArray* Object::AsIntArray() {
188 DCHECK(GetClass()->IsArrayClass());
189 DCHECK(GetClass()->GetComponentType()->IsPrimitiveInt() ||
190 GetClass()->GetComponentType()->IsPrimitiveFloat());
191 return down_cast<IntArray*>(this);
192}
193
194inline LongArray* Object::AsLongArray() {
195 DCHECK(GetClass()->IsArrayClass());
196 DCHECK(GetClass()->GetComponentType()->IsPrimitiveLong() ||
197 GetClass()->GetComponentType()->IsPrimitiveDouble());
198 return down_cast<LongArray*>(this);
199}
200
201inline String* Object::AsString() {
202 DCHECK(GetClass()->IsStringClass());
203 return down_cast<String*>(this);
204}
205
206inline Throwable* Object::AsThrowable() {
207 DCHECK(GetClass()->IsThrowableClass());
208 return down_cast<Throwable*>(this);
209}
210
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800211inline bool Object::IsWeakReferenceInstance() const {
212 return GetClass()->IsWeakReferenceClass();
213}
214
215inline bool Object::IsSoftReferenceInstance() const {
216 return GetClass()->IsSoftReferenceClass();
217}
218
219inline bool Object::IsFinalizerReferenceInstance() const {
220 return GetClass()->IsFinalizerReferenceClass();
221}
222
223inline bool Object::IsPhantomReferenceInstance() const {
224 return GetClass()->IsPhantomReferenceClass();
225}
226
227inline size_t Object::SizeOf() const {
228 size_t result;
229 if (IsArrayInstance()) {
230 result = AsArray()->SizeOf();
231 } else if (IsClass()) {
232 result = AsClass()->SizeOf();
233 } else {
234 result = GetClass()->GetObjectSize();
235 }
Brian Carlstromea46f952013-07-30 01:26:50 -0700236 DCHECK(!IsArtField() || result == sizeof(ArtField));
237 DCHECK(!IsArtMethod() || result == sizeof(ArtMethod));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800238 return result;
239}
240
241inline uint64_t Object::GetField64(MemberOffset field_offset, bool is_volatile) const {
242 VerifyObject(this);
243 const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
244 const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr);
245 if (UNLIKELY(is_volatile)) {
246 uint64_t result = QuasiAtomic::Read64(addr);
247 ANDROID_MEMBAR_FULL();
248 return result;
249 } else {
250 return *addr;
251 }
252}
253
254inline void Object::SetField64(MemberOffset field_offset, uint64_t new_value, bool is_volatile) {
255 VerifyObject(this);
256 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
257 int64_t* addr = reinterpret_cast<int64_t*>(raw_addr);
258 if (UNLIKELY(is_volatile)) {
259 ANDROID_MEMBAR_STORE();
260 QuasiAtomic::Write64(addr, new_value);
261 // Post-store barrier not required due to use of atomic op or mutex.
262 } else {
263 *addr = new_value;
264 }
265}
266
267inline void Object::WriteBarrierField(const Object* dst, MemberOffset field_offset,
268 const Object* new_value) {
269 Runtime::Current()->GetHeap()->WriteBarrierField(dst, field_offset, new_value);
270}
271
Ian Rogers04d7aa92013-03-16 14:29:17 -0700272inline void Object::VerifyObject(const Object* obj) {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700273 if (kIsDebugBuild) {
274 Runtime::Current()->GetHeap()->VerifyObject(obj);
275 }
Ian Rogers04d7aa92013-03-16 14:29:17 -0700276}
277
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800278} // namespace mirror
279} // namespace art
280
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700281#endif // ART_RUNTIME_MIRROR_OBJECT_INL_H_