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