class-inl.h revision 692fafd9778141fa6ef0048c9569abd7ee0253bf
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_CLASS_INL_H_ 18#define ART_RUNTIME_MIRROR_CLASS_INL_H_ 19 20#include "class.h" 21 22#include "art_field.h" 23#include "art_method.h" 24#include "class_loader.h" 25#include "dex_cache.h" 26#include "gc/heap-inl.h" 27#include "iftable.h" 28#include "object_array-inl.h" 29#include "runtime.h" 30#include "string.h" 31 32namespace art { 33namespace mirror { 34 35inline size_t Class::GetObjectSize() const { 36 DCHECK(!IsVariableSize()) << " class=" << PrettyTypeOf(this); 37 DCHECK_EQ(sizeof(size_t), sizeof(int32_t)); 38 return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, object_size_), false); 39} 40 41inline Class* Class::GetSuperClass() const { 42 // Can only get super class for loaded classes (hack for when runtime is 43 // initializing) 44 DCHECK(IsLoaded() || !Runtime::Current()->IsStarted()) << IsLoaded(); 45 return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_), false); 46} 47 48inline ClassLoader* Class::GetClassLoader() const { 49 return GetFieldObject<ClassLoader*>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), false); 50} 51 52inline DexCache* Class::GetDexCache() const { 53 return GetFieldObject<DexCache*>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), false); 54} 55 56inline ObjectArray<ArtMethod>* Class::GetDirectMethods() const { 57 DCHECK(IsLoaded() || IsErroneous()); 58 return GetFieldObject<ObjectArray<ArtMethod>*>( 59 OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), false); 60} 61 62inline void Class::SetDirectMethods(ObjectArray<ArtMethod>* new_direct_methods) 63 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 64 DCHECK(NULL == GetFieldObject<ObjectArray<ArtMethod>*>( 65 OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), false)); 66 DCHECK_NE(0, new_direct_methods->GetLength()); 67 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), 68 new_direct_methods, false); 69} 70 71inline ArtMethod* Class::GetDirectMethod(int32_t i) const 72 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 73 return GetDirectMethods()->Get(i); 74} 75 76inline void Class::SetDirectMethod(uint32_t i, ArtMethod* f) // TODO: uint16_t 77 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 78 ObjectArray<ArtMethod>* direct_methods = 79 GetFieldObject<ObjectArray<ArtMethod>*>( 80 OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), false); 81 direct_methods->Set(i, f); 82} 83 84// Returns the number of static, private, and constructor methods. 85inline size_t Class::NumDirectMethods() const { 86 return (GetDirectMethods() != NULL) ? GetDirectMethods()->GetLength() : 0; 87} 88 89inline ObjectArray<ArtMethod>* Class::GetVirtualMethods() const { 90 DCHECK(IsLoaded() || IsErroneous()); 91 return GetFieldObject<ObjectArray<ArtMethod>*>( 92 OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_), false); 93} 94 95inline void Class::SetVirtualMethods(ObjectArray<ArtMethod>* new_virtual_methods) { 96 // TODO: we reassign virtual methods to grow the table for miranda 97 // methods.. they should really just be assigned once 98 DCHECK_NE(0, new_virtual_methods->GetLength()); 99 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_), 100 new_virtual_methods, false); 101} 102 103inline size_t Class::NumVirtualMethods() const { 104 return (GetVirtualMethods() != NULL) ? GetVirtualMethods()->GetLength() : 0; 105} 106 107inline ArtMethod* Class::GetVirtualMethod(uint32_t i) const 108 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 109 DCHECK(IsResolved() || IsErroneous()); 110 return GetVirtualMethods()->Get(i); 111} 112 113inline ArtMethod* Class::GetVirtualMethodDuringLinking(uint32_t i) const 114 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 115 DCHECK(IsLoaded() || IsErroneous()); 116 return GetVirtualMethods()->Get(i); 117} 118 119inline void Class::SetVirtualMethod(uint32_t i, ArtMethod* f) // TODO: uint16_t 120 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 121 ObjectArray<ArtMethod>* virtual_methods = 122 GetFieldObject<ObjectArray<ArtMethod>*>( 123 OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_), false); 124 virtual_methods->Set(i, f); 125} 126 127inline ObjectArray<ArtMethod>* Class::GetVTable() const { 128 DCHECK(IsResolved() || IsErroneous()); 129 return GetFieldObject<ObjectArray<ArtMethod>*>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), false); 130} 131 132inline ObjectArray<ArtMethod>* Class::GetVTableDuringLinking() const { 133 DCHECK(IsLoaded() || IsErroneous()); 134 return GetFieldObject<ObjectArray<ArtMethod>*>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), false); 135} 136 137inline void Class::SetVTable(ObjectArray<ArtMethod>* new_vtable) 138 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 139 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), new_vtable, false); 140} 141 142inline ObjectArray<ArtMethod>* Class::GetImTable() const { 143 return GetFieldObject<ObjectArray<ArtMethod>*>(OFFSET_OF_OBJECT_MEMBER(Class, imtable_), false); 144} 145 146inline void Class::SetImTable(ObjectArray<ArtMethod>* new_imtable) { 147 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, imtable_), new_imtable, false); 148} 149 150inline bool Class::Implements(const Class* klass) const { 151 DCHECK(klass != NULL); 152 DCHECK(klass->IsInterface()) << PrettyClass(this); 153 // All interfaces implemented directly and by our superclass, and 154 // recursively all super-interfaces of those interfaces, are listed 155 // in iftable_, so we can just do a linear scan through that. 156 int32_t iftable_count = GetIfTableCount(); 157 IfTable* iftable = GetIfTable(); 158 for (int32_t i = 0; i < iftable_count; i++) { 159 if (iftable->GetInterface(i) == klass) { 160 return true; 161 } 162 } 163 return false; 164} 165 166// Determine whether "this" is assignable from "src", where both of these 167// are array classes. 168// 169// Consider an array class, e.g. Y[][], where Y is a subclass of X. 170// Y[][] = Y[][] --> true (identity) 171// X[][] = Y[][] --> true (element superclass) 172// Y = Y[][] --> false 173// Y[] = Y[][] --> false 174// Object = Y[][] --> true (everything is an object) 175// Object[] = Y[][] --> true 176// Object[][] = Y[][] --> true 177// Object[][][] = Y[][] --> false (too many []s) 178// Serializable = Y[][] --> true (all arrays are Serializable) 179// Serializable[] = Y[][] --> true 180// Serializable[][] = Y[][] --> false (unless Y is Serializable) 181// 182// Don't forget about primitive types. 183// Object[] = int[] --> false 184// 185inline bool Class::IsArrayAssignableFromArray(const Class* src) const { 186 DCHECK(IsArrayClass()) << PrettyClass(this); 187 DCHECK(src->IsArrayClass()) << PrettyClass(src); 188 return GetComponentType()->IsAssignableFrom(src->GetComponentType()); 189} 190 191inline bool Class::IsAssignableFromArray(const Class* src) const { 192 DCHECK(!IsInterface()) << PrettyClass(this); // handled first in IsAssignableFrom 193 DCHECK(src->IsArrayClass()) << PrettyClass(src); 194 if (!IsArrayClass()) { 195 // If "this" is not also an array, it must be Object. 196 // src's super should be java_lang_Object, since it is an array. 197 Class* java_lang_Object = src->GetSuperClass(); 198 DCHECK(java_lang_Object != NULL) << PrettyClass(src); 199 DCHECK(java_lang_Object->GetSuperClass() == NULL) << PrettyClass(src); 200 return this == java_lang_Object; 201 } 202 return IsArrayAssignableFromArray(src); 203} 204 205inline bool Class::IsSubClass(const Class* klass) const { 206 DCHECK(!IsInterface()) << PrettyClass(this); 207 DCHECK(!IsArrayClass()) << PrettyClass(this); 208 const Class* current = this; 209 do { 210 if (current == klass) { 211 return true; 212 } 213 current = current->GetSuperClass(); 214 } while (current != NULL); 215 return false; 216} 217 218inline ArtMethod* Class::FindVirtualMethodForInterface(ArtMethod* method) const { 219 Class* declaring_class = method->GetDeclaringClass(); 220 DCHECK(declaring_class != NULL) << PrettyClass(this); 221 DCHECK(declaring_class->IsInterface()) << PrettyMethod(method); 222 // TODO cache to improve lookup speed 223 int32_t iftable_count = GetIfTableCount(); 224 IfTable* iftable = GetIfTable(); 225 for (int32_t i = 0; i < iftable_count; i++) { 226 if (iftable->GetInterface(i) == declaring_class) { 227 return iftable->GetMethodArray(i)->Get(method->GetMethodIndex()); 228 } 229 } 230 return NULL; 231} 232 233inline ArtMethod* Class::FindVirtualMethodForVirtual(ArtMethod* method) const 234 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 235 DCHECK(!method->GetDeclaringClass()->IsInterface() || method->IsMiranda()); 236 // The argument method may from a super class. 237 // Use the index to a potentially overridden one for this instance's class. 238 return GetVTable()->Get(method->GetMethodIndex()); 239} 240 241inline ArtMethod* Class::FindVirtualMethodForSuper(ArtMethod* method) const 242 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 243 DCHECK(!method->GetDeclaringClass()->IsInterface()); 244 return GetSuperClass()->GetVTable()->Get(method->GetMethodIndex()); 245} 246 247inline ArtMethod* Class::FindVirtualMethodForVirtualOrInterface(ArtMethod* method) const { 248 if (method->IsDirect()) { 249 return method; 250 } 251 if (method->GetDeclaringClass()->IsInterface() && !method->IsMiranda()) { 252 return FindVirtualMethodForInterface(method); 253 } 254 return FindVirtualMethodForVirtual(method); 255} 256 257inline IfTable* Class::GetIfTable() const { 258 return GetFieldObject<IfTable*>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), false); 259} 260 261inline int32_t Class::GetIfTableCount() const { 262 IfTable* iftable = GetIfTable(); 263 if (iftable == NULL) { 264 return 0; 265 } 266 return iftable->Count(); 267} 268 269inline void Class::SetIfTable(IfTable* new_iftable) { 270 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), new_iftable, false); 271} 272 273inline ObjectArray<ArtField>* Class::GetIFields() const { 274 DCHECK(IsLoaded() || IsErroneous()); 275 return GetFieldObject<ObjectArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), false); 276} 277 278inline void Class::SetIFields(ObjectArray<ArtField>* new_ifields) 279 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 280 DCHECK(NULL == GetFieldObject<ObjectArray<ArtField>*>( 281 OFFSET_OF_OBJECT_MEMBER(Class, ifields_), false)); 282 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields, false); 283} 284 285inline ObjectArray<ArtField>* Class::GetSFields() const { 286 DCHECK(IsLoaded() || IsErroneous()); 287 return GetFieldObject<ObjectArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), false); 288} 289 290inline void Class::SetSFields(ObjectArray<ArtField>* new_sfields) 291 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 292 DCHECK(NULL == GetFieldObject<ObjectArray<ArtField>*>( 293 OFFSET_OF_OBJECT_MEMBER(Class, sfields_), false)); 294 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields, false); 295} 296 297inline size_t Class::NumStaticFields() const { 298 return (GetSFields() != NULL) ? GetSFields()->GetLength() : 0; 299} 300 301inline ArtField* Class::GetStaticField(uint32_t i) const // TODO: uint16_t 302 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 303 return GetSFields()->Get(i); 304} 305 306inline void Class::SetStaticField(uint32_t i, ArtField* f) // TODO: uint16_t 307 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 308 ObjectArray<ArtField>* sfields= GetFieldObject<ObjectArray<ArtField>*>( 309 OFFSET_OF_OBJECT_MEMBER(Class, sfields_), false); 310 sfields->Set(i, f); 311} 312 313inline size_t Class::NumInstanceFields() const { 314 return (GetIFields() != NULL) ? GetIFields()->GetLength() : 0; 315} 316 317inline ArtField* Class::GetInstanceField(uint32_t i) const // TODO: uint16_t 318 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 319 DCHECK_NE(NumInstanceFields(), 0U); 320 return GetIFields()->Get(i); 321} 322 323inline void Class::SetInstanceField(uint32_t i, ArtField* f) // TODO: uint16_t 324 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 325 ObjectArray<ArtField>* ifields= GetFieldObject<ObjectArray<ArtField>*>( 326 OFFSET_OF_OBJECT_MEMBER(Class, ifields_), false); 327 ifields->Set(i, f); 328} 329 330inline void Class::SetVerifyErrorClass(Class* klass) { 331 CHECK(klass != NULL) << PrettyClass(this); 332 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), klass, false); 333} 334 335inline uint32_t Class::GetAccessFlags() const { 336 // Check class is loaded or this is java.lang.String that has a 337 // circularity issue during loading the names of its members 338 DCHECK(IsLoaded() || IsErroneous() || 339 this == String::GetJavaLangString() || 340 this == ArtField::GetJavaLangReflectArtField() || 341 this == ArtMethod::GetJavaLangReflectArtMethod()); 342 return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), false); 343} 344 345inline String* Class::GetName() const { 346 return GetFieldObject<String*>(OFFSET_OF_OBJECT_MEMBER(Class, name_), false); 347} 348inline void Class::SetName(String* name) { 349 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, name_), name, false); 350} 351 352inline void Class::CheckObjectAlloc() { 353 DCHECK(!IsArrayClass()) << PrettyClass(this); 354 DCHECK(IsInstantiable()) << PrettyClass(this); 355 // TODO: decide whether we want this check. It currently fails during bootstrap. 356 // DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass(this); 357 DCHECK_GE(this->object_size_, sizeof(Object)); 358} 359 360template <bool kIsInstrumented> 361inline Object* Class::Alloc(Thread* self, gc::AllocatorType allocator_type) { 362 CheckObjectAlloc(); 363 gc::Heap* heap = Runtime::Current()->GetHeap(); 364 return heap->AllocObjectWithAllocator<kIsInstrumented, false>(self, this, this->object_size_, 365 allocator_type); 366} 367 368inline Object* Class::AllocObject(Thread* self) { 369 return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentAllocator()); 370} 371 372inline Object* Class::AllocNonMovableObject(Thread* self) { 373 return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentNonMovingAllocator()); 374} 375 376} // namespace mirror 377} // namespace art 378 379#endif // ART_RUNTIME_MIRROR_CLASS_INL_H_ 380