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