• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
31 namespace art {
32 namespace mirror {
33 
GetClass()34 inline Class* Object::GetClass() const {
35   return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Object, klass_), false);
36 }
37 
SetClass(Class * new_klass)38 inline 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 
GetThinLockId()46 inline uint32_t Object::GetThinLockId() {
47   return Monitor::GetThinLockId(monitor_);
48 }
49 
MonitorEnter(Thread * self)50 inline void Object::MonitorEnter(Thread* self) {
51   Monitor::MonitorEnter(self, this);
52 }
53 
MonitorExit(Thread * self)54 inline bool Object::MonitorExit(Thread* self) {
55   return Monitor::MonitorExit(self, this);
56 }
57 
Notify(Thread * self)58 inline void Object::Notify(Thread* self) {
59   Monitor::Notify(self, this);
60 }
61 
NotifyAll(Thread * self)62 inline void Object::NotifyAll(Thread* self) {
63   Monitor::NotifyAll(self, this);
64 }
65 
Wait(Thread * self)66 inline void Object::Wait(Thread* self) {
67   Monitor::Wait(self, this, 0, 0, true, kWaiting);
68 }
69 
Wait(Thread * self,int64_t ms,int32_t ns)70 inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
71   Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
72 }
73 
VerifierInstanceOf(const Class * klass)74 inline bool Object::VerifierInstanceOf(const Class* klass) const {
75   DCHECK(klass != NULL);
76   DCHECK(GetClass() != NULL);
77   return klass->IsInterface() || InstanceOf(klass);
78 }
79 
InstanceOf(const Class * klass)80 inline bool Object::InstanceOf(const Class* klass) const {
81   DCHECK(klass != NULL);
82   DCHECK(GetClass() != NULL);
83   return klass->IsAssignableFrom(GetClass());
84 }
85 
IsClass()86 inline bool Object::IsClass() const {
87   Class* java_lang_Class = GetClass()->GetClass();
88   return GetClass() == java_lang_Class;
89 }
90 
AsClass()91 inline Class* Object::AsClass() {
92   DCHECK(IsClass());
93   return down_cast<Class*>(this);
94 }
95 
AsClass()96 inline const Class* Object::AsClass() const {
97   DCHECK(IsClass());
98   return down_cast<const Class*>(this);
99 }
100 
IsObjectArray()101 inline bool Object::IsObjectArray() const {
102   return IsArrayInstance() && !GetClass()->GetComponentType()->IsPrimitive();
103 }
104 
105 template<class T>
AsObjectArray()106 inline ObjectArray<T>* Object::AsObjectArray() {
107   DCHECK(IsObjectArray());
108   return down_cast<ObjectArray<T>*>(this);
109 }
110 
111 template<class T>
AsObjectArray()112 inline const ObjectArray<T>* Object::AsObjectArray() const {
113   DCHECK(IsObjectArray());
114   return down_cast<const ObjectArray<T>*>(this);
115 }
116 
IsArrayInstance()117 inline bool Object::IsArrayInstance() const {
118   return GetClass()->IsArrayClass();
119 }
120 
IsArtField()121 inline bool Object::IsArtField() const {
122   return GetClass()->IsArtFieldClass();
123 }
124 
AsArtField()125 inline ArtField* Object::AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
126   DCHECK(IsArtField());
127   return down_cast<ArtField*>(this);
128 }
129 
AsArtField()130 inline const ArtField* Object::AsArtField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
131   DCHECK(IsArtField());
132   return down_cast<const ArtField*>(this);
133 }
134 
IsArtMethod()135 inline bool Object::IsArtMethod() const {
136   return GetClass()->IsArtMethodClass();
137 }
138 
AsArtMethod()139 inline ArtMethod* Object::AsArtMethod() {
140   DCHECK(IsArtMethod());
141   return down_cast<ArtMethod*>(this);
142 }
143 
AsArtMethod()144 inline const ArtMethod* Object::AsArtMethod() const {
145   DCHECK(IsArtMethod());
146   return down_cast<const ArtMethod*>(this);
147 }
148 
IsReferenceInstance()149 inline bool Object::IsReferenceInstance() const {
150   return GetClass()->IsReferenceClass();
151 }
152 
AsArray()153 inline Array* Object::AsArray() {
154   DCHECK(IsArrayInstance());
155   return down_cast<Array*>(this);
156 }
157 
AsArray()158 inline const Array* Object::AsArray() const {
159   DCHECK(IsArrayInstance());
160   return down_cast<const Array*>(this);
161 }
162 
AsBooleanArray()163 inline BooleanArray* Object::AsBooleanArray() {
164   DCHECK(GetClass()->IsArrayClass());
165   DCHECK(GetClass()->GetComponentType()->IsPrimitiveBoolean());
166   return down_cast<BooleanArray*>(this);
167 }
168 
AsByteArray()169 inline ByteArray* Object::AsByteArray() {
170   DCHECK(GetClass()->IsArrayClass());
171   DCHECK(GetClass()->GetComponentType()->IsPrimitiveByte());
172   return down_cast<ByteArray*>(this);
173 }
174 
AsCharArray()175 inline CharArray* Object::AsCharArray() {
176   DCHECK(GetClass()->IsArrayClass());
177   DCHECK(GetClass()->GetComponentType()->IsPrimitiveChar());
178   return down_cast<CharArray*>(this);
179 }
180 
AsShortArray()181 inline ShortArray* Object::AsShortArray() {
182   DCHECK(GetClass()->IsArrayClass());
183   DCHECK(GetClass()->GetComponentType()->IsPrimitiveShort());
184   return down_cast<ShortArray*>(this);
185 }
186 
AsIntArray()187 inline IntArray* Object::AsIntArray() {
188   DCHECK(GetClass()->IsArrayClass());
189   DCHECK(GetClass()->GetComponentType()->IsPrimitiveInt() ||
190          GetClass()->GetComponentType()->IsPrimitiveFloat());
191   return down_cast<IntArray*>(this);
192 }
193 
AsLongArray()194 inline LongArray* Object::AsLongArray() {
195   DCHECK(GetClass()->IsArrayClass());
196   DCHECK(GetClass()->GetComponentType()->IsPrimitiveLong() ||
197          GetClass()->GetComponentType()->IsPrimitiveDouble());
198   return down_cast<LongArray*>(this);
199 }
200 
AsString()201 inline String* Object::AsString() {
202   DCHECK(GetClass()->IsStringClass());
203   return down_cast<String*>(this);
204 }
205 
AsThrowable()206 inline Throwable* Object::AsThrowable() {
207   DCHECK(GetClass()->IsThrowableClass());
208   return down_cast<Throwable*>(this);
209 }
210 
IsWeakReferenceInstance()211 inline bool Object::IsWeakReferenceInstance() const {
212   return GetClass()->IsWeakReferenceClass();
213 }
214 
IsSoftReferenceInstance()215 inline bool Object::IsSoftReferenceInstance() const {
216   return GetClass()->IsSoftReferenceClass();
217 }
218 
IsFinalizerReferenceInstance()219 inline bool Object::IsFinalizerReferenceInstance() const {
220   return GetClass()->IsFinalizerReferenceClass();
221 }
222 
IsPhantomReferenceInstance()223 inline bool Object::IsPhantomReferenceInstance() const {
224   return GetClass()->IsPhantomReferenceClass();
225 }
226 
SizeOf()227 inline 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 
GetField64(MemberOffset field_offset,bool is_volatile)241 inline 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 
SetField64(MemberOffset field_offset,uint64_t new_value,bool is_volatile)254 inline 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 
WriteBarrierField(const Object * dst,MemberOffset field_offset,const Object * new_value)267 inline 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 
VerifyObject(const Object * obj)272 inline 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