blob: 3913c817ee60e1d5f9b6e015b2c2821ddd23d1e0 [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
17#ifndef ART_SRC_MIRROR_OBJECT_INL_H_
18#define ART_SRC_MIRROR_OBJECT_INL_H_
19
20#include "object.h"
21
22#include "abstract_method.h"
23#include "atomic.h"
24#include "array.h"
25#include "field.h"
26#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
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080074inline bool Object::InstanceOf(const Class* klass) const {
75 DCHECK(klass != NULL);
76 DCHECK(GetClass() != NULL);
77 return klass->IsAssignableFrom(GetClass());
78}
79
80inline bool Object::IsClass() const {
81 Class* java_lang_Class = GetClass()->GetClass();
82 return GetClass() == java_lang_Class;
83}
84
85inline Class* Object::AsClass() {
86 DCHECK(IsClass());
87 return down_cast<Class*>(this);
88}
89
90inline const Class* Object::AsClass() const {
91 DCHECK(IsClass());
92 return down_cast<const Class*>(this);
93}
94
95inline bool Object::IsObjectArray() const {
96 return IsArrayInstance() && !GetClass()->GetComponentType()->IsPrimitive();
97}
98
99template<class T>
100inline ObjectArray<T>* Object::AsObjectArray() {
101 DCHECK(IsObjectArray());
102 return down_cast<ObjectArray<T>*>(this);
103}
104
105template<class T>
106inline const ObjectArray<T>* Object::AsObjectArray() const {
107 DCHECK(IsObjectArray());
108 return down_cast<const ObjectArray<T>*>(this);
109}
110
111inline bool Object::IsArrayInstance() const {
112 return GetClass()->IsArrayClass();
113}
114
115inline bool Object::IsField() const {
116 return GetClass()->IsFieldClass();
117}
118
119inline Field* Object::AsField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
120 DCHECK(IsField());
121 return down_cast<Field*>(this);
122}
123
124inline const Field* Object::AsField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
125 DCHECK(IsField());
126 return down_cast<const Field*>(this);
127}
128
129inline bool Object::IsMethod() const {
130 return GetClass()->IsMethodClass();
131}
132
133inline AbstractMethod* Object::AsMethod() {
134 DCHECK(IsMethod());
135 return down_cast<AbstractMethod*>(this);
136}
137
138inline const AbstractMethod* Object::AsMethod() const {
139 DCHECK(IsMethod());
140 return down_cast<const AbstractMethod*>(this);
141}
142
143inline bool Object::IsReferenceInstance() const {
144 return GetClass()->IsReferenceClass();
145}
146
Ian Rogers05f30572013-02-20 12:13:11 -0800147inline Array* Object::AsArray() {
148 DCHECK(IsArrayInstance());
149 return down_cast<Array*>(this);
150}
151
152inline const Array* Object::AsArray() const {
153 DCHECK(IsArrayInstance());
154 return down_cast<const Array*>(this);
155}
156
157inline BooleanArray* Object::AsBooleanArray() {
158 DCHECK(GetClass()->IsArrayClass());
159 DCHECK(GetClass()->GetComponentType()->IsPrimitiveBoolean());
160 return down_cast<BooleanArray*>(this);
161}
162
163inline ByteArray* Object::AsByteArray() {
164 DCHECK(GetClass()->IsArrayClass());
165 DCHECK(GetClass()->GetComponentType()->IsPrimitiveByte());
166 return down_cast<ByteArray*>(this);
167}
168
169inline CharArray* Object::AsCharArray() {
170 DCHECK(GetClass()->IsArrayClass());
171 DCHECK(GetClass()->GetComponentType()->IsPrimitiveChar());
172 return down_cast<CharArray*>(this);
173}
174
175inline ShortArray* Object::AsShortArray() {
176 DCHECK(GetClass()->IsArrayClass());
177 DCHECK(GetClass()->GetComponentType()->IsPrimitiveShort());
178 return down_cast<ShortArray*>(this);
179}
180
181inline IntArray* Object::AsIntArray() {
182 DCHECK(GetClass()->IsArrayClass());
183 DCHECK(GetClass()->GetComponentType()->IsPrimitiveInt() ||
184 GetClass()->GetComponentType()->IsPrimitiveFloat());
185 return down_cast<IntArray*>(this);
186}
187
188inline LongArray* Object::AsLongArray() {
189 DCHECK(GetClass()->IsArrayClass());
190 DCHECK(GetClass()->GetComponentType()->IsPrimitiveLong() ||
191 GetClass()->GetComponentType()->IsPrimitiveDouble());
192 return down_cast<LongArray*>(this);
193}
194
195inline String* Object::AsString() {
196 DCHECK(GetClass()->IsStringClass());
197 return down_cast<String*>(this);
198}
199
200inline Throwable* Object::AsThrowable() {
201 DCHECK(GetClass()->IsThrowableClass());
202 return down_cast<Throwable*>(this);
203}
204
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800205inline bool Object::IsWeakReferenceInstance() const {
206 return GetClass()->IsWeakReferenceClass();
207}
208
209inline bool Object::IsSoftReferenceInstance() const {
210 return GetClass()->IsSoftReferenceClass();
211}
212
213inline bool Object::IsFinalizerReferenceInstance() const {
214 return GetClass()->IsFinalizerReferenceClass();
215}
216
217inline bool Object::IsPhantomReferenceInstance() const {
218 return GetClass()->IsPhantomReferenceClass();
219}
220
221inline size_t Object::SizeOf() const {
222 size_t result;
223 if (IsArrayInstance()) {
224 result = AsArray()->SizeOf();
225 } else if (IsClass()) {
226 result = AsClass()->SizeOf();
227 } else {
228 result = GetClass()->GetObjectSize();
229 }
230 DCHECK(!IsField() || result == sizeof(Field));
231 DCHECK(!IsMethod() || result == sizeof(AbstractMethod));
232 return result;
233}
234
235inline uint64_t Object::GetField64(MemberOffset field_offset, bool is_volatile) const {
236 VerifyObject(this);
237 const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
238 const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr);
239 if (UNLIKELY(is_volatile)) {
240 uint64_t result = QuasiAtomic::Read64(addr);
241 ANDROID_MEMBAR_FULL();
242 return result;
243 } else {
244 return *addr;
245 }
246}
247
248inline void Object::SetField64(MemberOffset field_offset, uint64_t new_value, bool is_volatile) {
249 VerifyObject(this);
250 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
251 int64_t* addr = reinterpret_cast<int64_t*>(raw_addr);
252 if (UNLIKELY(is_volatile)) {
253 ANDROID_MEMBAR_STORE();
254 QuasiAtomic::Write64(addr, new_value);
255 // Post-store barrier not required due to use of atomic op or mutex.
256 } else {
257 *addr = new_value;
258 }
259}
260
261inline void Object::WriteBarrierField(const Object* dst, MemberOffset field_offset,
262 const Object* new_value) {
263 Runtime::Current()->GetHeap()->WriteBarrierField(dst, field_offset, new_value);
264}
265
Ian Rogers04d7aa92013-03-16 14:29:17 -0700266inline void Object::VerifyObject(const Object* obj) {
267 Runtime::Current()->GetHeap()->VerifyObject(obj);
268}
269
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800270} // namespace mirror
271} // namespace art
272
273#endif // ART_SRC_MIRROR_OBJECT_INL_H_