object-inl.h revision a3faaf4bece7f42529c013fe87bd41de59798656
1/*
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_RUNTIME_MIRROR_OBJECT_INL_H_
18#define ART_RUNTIME_MIRROR_OBJECT_INL_H_
19
20#include "object.h"
21
22#include "art_field.h"
23#include "art_method.h"
24#include "atomic.h"
25#include "array-inl.h"
26#include "class.h"
27#include "monitor.h"
28#include "runtime.h"
29#include "throwable.h"
30
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
46inline 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
74inline bool Object::VerifierInstanceOf(const Class* klass) const {
75  DCHECK(klass != NULL);
76  DCHECK(GetClass() != NULL);
77  return klass->IsInterface() || InstanceOf(klass);
78}
79
80inline 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
121inline bool Object::IsArtField() const {
122  return GetClass()->IsArtFieldClass();
123}
124
125inline ArtField* Object::AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
126  DCHECK(IsArtField());
127  return down_cast<ArtField*>(this);
128}
129
130inline const ArtField* Object::AsArtField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
131  DCHECK(IsArtField());
132  return down_cast<const ArtField*>(this);
133}
134
135inline bool Object::IsArtMethod() const {
136  return GetClass()->IsArtMethodClass();
137}
138
139inline ArtMethod* Object::AsArtMethod() {
140  DCHECK(IsArtMethod());
141  return down_cast<ArtMethod*>(this);
142}
143
144inline const ArtMethod* Object::AsArtMethod() const {
145  DCHECK(IsArtMethod());
146  return down_cast<const ArtMethod*>(this);
147}
148
149inline bool Object::IsReferenceInstance() const {
150  return GetClass()->IsReferenceClass();
151}
152
153inline 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
211inline 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  }
236  DCHECK(!IsArtField()  || result == sizeof(ArtField));
237  DCHECK(!IsArtMethod() || result == sizeof(ArtMethod));
238  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
272inline void Object::VerifyObject(const Object* obj) {
273  if (kIsDebugBuild) {
274    Runtime::Current()->GetHeap()->VerifyObject(obj);
275  }
276}
277
278}  // namespace mirror
279}  // namespace art
280
281#endif  // ART_RUNTIME_MIRROR_OBJECT_INL_H_
282