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