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 34 inline Class* Object::GetClass() const { 35 return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Object, klass_), false); 36 } 37 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 46 inline uint32_t Object::GetThinLockId() { 47 return Monitor::GetThinLockId(monitor_); 48 } 49 50 inline void Object::MonitorEnter(Thread* self) { 51 Monitor::MonitorEnter(self, this); 52 } 53 54 inline bool Object::MonitorExit(Thread* self) { 55 return Monitor::MonitorExit(self, this); 56 } 57 58 inline void Object::Notify(Thread* self) { 59 Monitor::Notify(self, this); 60 } 61 62 inline void Object::NotifyAll(Thread* self) { 63 Monitor::NotifyAll(self, this); 64 } 65 66 inline void Object::Wait(Thread* self) { 67 Monitor::Wait(self, this, 0, 0, true, kWaiting); 68 } 69 70 inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) { 71 Monitor::Wait(self, this, ms, ns, true, kTimedWaiting); 72 } 73 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 80 inline bool Object::InstanceOf(const Class* klass) const { 81 DCHECK(klass != NULL); 82 DCHECK(GetClass() != NULL); 83 return klass->IsAssignableFrom(GetClass()); 84 } 85 86 inline bool Object::IsClass() const { 87 Class* java_lang_Class = GetClass()->GetClass(); 88 return GetClass() == java_lang_Class; 89 } 90 91 inline Class* Object::AsClass() { 92 DCHECK(IsClass()); 93 return down_cast<Class*>(this); 94 } 95 96 inline const Class* Object::AsClass() const { 97 DCHECK(IsClass()); 98 return down_cast<const Class*>(this); 99 } 100 101 inline bool Object::IsObjectArray() const { 102 return IsArrayInstance() && !GetClass()->GetComponentType()->IsPrimitive(); 103 } 104 105 template<class T> 106 inline ObjectArray<T>* Object::AsObjectArray() { 107 DCHECK(IsObjectArray()); 108 return down_cast<ObjectArray<T>*>(this); 109 } 110 111 template<class T> 112 inline const ObjectArray<T>* Object::AsObjectArray() const { 113 DCHECK(IsObjectArray()); 114 return down_cast<const ObjectArray<T>*>(this); 115 } 116 117 inline bool Object::IsArrayInstance() const { 118 return GetClass()->IsArrayClass(); 119 } 120 121 inline bool Object::IsArtField() const { 122 return GetClass()->IsArtFieldClass(); 123 } 124 125 inline ArtField* Object::AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 126 DCHECK(IsArtField()); 127 return down_cast<ArtField*>(this); 128 } 129 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 135 inline bool Object::IsArtMethod() const { 136 return GetClass()->IsArtMethodClass(); 137 } 138 139 inline ArtMethod* Object::AsArtMethod() { 140 DCHECK(IsArtMethod()); 141 return down_cast<ArtMethod*>(this); 142 } 143 144 inline const ArtMethod* Object::AsArtMethod() const { 145 DCHECK(IsArtMethod()); 146 return down_cast<const ArtMethod*>(this); 147 } 148 149 inline bool Object::IsReferenceInstance() const { 150 return GetClass()->IsReferenceClass(); 151 } 152 153 inline Array* Object::AsArray() { 154 DCHECK(IsArrayInstance()); 155 return down_cast<Array*>(this); 156 } 157 158 inline const Array* Object::AsArray() const { 159 DCHECK(IsArrayInstance()); 160 return down_cast<const Array*>(this); 161 } 162 163 inline BooleanArray* Object::AsBooleanArray() { 164 DCHECK(GetClass()->IsArrayClass()); 165 DCHECK(GetClass()->GetComponentType()->IsPrimitiveBoolean()); 166 return down_cast<BooleanArray*>(this); 167 } 168 169 inline ByteArray* Object::AsByteArray() { 170 DCHECK(GetClass()->IsArrayClass()); 171 DCHECK(GetClass()->GetComponentType()->IsPrimitiveByte()); 172 return down_cast<ByteArray*>(this); 173 } 174 175 inline CharArray* Object::AsCharArray() { 176 DCHECK(GetClass()->IsArrayClass()); 177 DCHECK(GetClass()->GetComponentType()->IsPrimitiveChar()); 178 return down_cast<CharArray*>(this); 179 } 180 181 inline ShortArray* Object::AsShortArray() { 182 DCHECK(GetClass()->IsArrayClass()); 183 DCHECK(GetClass()->GetComponentType()->IsPrimitiveShort()); 184 return down_cast<ShortArray*>(this); 185 } 186 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 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 201 inline String* Object::AsString() { 202 DCHECK(GetClass()->IsStringClass()); 203 return down_cast<String*>(this); 204 } 205 206 inline Throwable* Object::AsThrowable() { 207 DCHECK(GetClass()->IsThrowableClass()); 208 return down_cast<Throwable*>(this); 209 } 210 211 inline bool Object::IsWeakReferenceInstance() const { 212 return GetClass()->IsWeakReferenceClass(); 213 } 214 215 inline bool Object::IsSoftReferenceInstance() const { 216 return GetClass()->IsSoftReferenceClass(); 217 } 218 219 inline bool Object::IsFinalizerReferenceInstance() const { 220 return GetClass()->IsFinalizerReferenceClass(); 221 } 222 223 inline bool Object::IsPhantomReferenceInstance() const { 224 return GetClass()->IsPhantomReferenceClass(); 225 } 226 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 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 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 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 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