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_ART_METHOD_INL_H_ 18 #define ART_RUNTIME_ART_METHOD_INL_H_ 19 20 #include "art_method.h" 21 22 #include "art_field.h" 23 #include "base/callee_save_type.h" 24 #include "base/logging.h" 25 #include "class_linker-inl.h" 26 #include "common_throws.h" 27 #include "dex_file.h" 28 #include "dex_file_annotations.h" 29 #include "dex_file-inl.h" 30 #include "gc_root-inl.h" 31 #include "invoke_type.h" 32 #include "jit/profiling_info.h" 33 #include "mirror/class-inl.h" 34 #include "mirror/dex_cache-inl.h" 35 #include "mirror/object-inl.h" 36 #include "mirror/object_array.h" 37 #include "mirror/string.h" 38 #include "oat.h" 39 #include "obj_ptr-inl.h" 40 #include "primitive.h" 41 #include "quick/quick_method_frame_info.h" 42 #include "read_barrier-inl.h" 43 #include "runtime-inl.h" 44 #include "scoped_thread_state_change-inl.h" 45 #include "thread-current-inl.h" 46 #include "utils.h" 47 48 namespace art { 49 50 template <ReadBarrierOption kReadBarrierOption> 51 inline mirror::Class* ArtMethod::GetDeclaringClassUnchecked() { 52 GcRootSource gc_root_source(this); 53 return declaring_class_.Read<kReadBarrierOption>(&gc_root_source); 54 } 55 56 template <ReadBarrierOption kReadBarrierOption> 57 inline mirror::Class* ArtMethod::GetDeclaringClass() { 58 mirror::Class* result = GetDeclaringClassUnchecked<kReadBarrierOption>(); 59 if (kIsDebugBuild) { 60 if (!IsRuntimeMethod()) { 61 CHECK(result != nullptr) << this; 62 if (kCheckDeclaringClassState) { 63 if (!(result->IsIdxLoaded() || result->IsErroneous())) { 64 LOG(FATAL_WITHOUT_ABORT) << "Class status: " << result->GetStatus(); 65 LOG(FATAL) << result->PrettyClass(); 66 } 67 } 68 } else { 69 CHECK(result == nullptr) << this; 70 } 71 } 72 return result; 73 } 74 75 inline void ArtMethod::SetDeclaringClass(ObjPtr<mirror::Class> new_declaring_class) { 76 declaring_class_ = GcRoot<mirror::Class>(new_declaring_class); 77 } 78 79 inline bool ArtMethod::CASDeclaringClass(mirror::Class* expected_class, 80 mirror::Class* desired_class) { 81 GcRoot<mirror::Class> expected_root(expected_class); 82 GcRoot<mirror::Class> desired_root(desired_class); 83 return reinterpret_cast<Atomic<GcRoot<mirror::Class>>*>(&declaring_class_)-> 84 CompareExchangeStrongSequentiallyConsistent( 85 expected_root, desired_root); 86 } 87 88 inline uint16_t ArtMethod::GetMethodIndex() { 89 DCHECK(IsRuntimeMethod() || GetDeclaringClass()->IsResolved()); 90 return method_index_; 91 } 92 93 inline uint16_t ArtMethod::GetMethodIndexDuringLinking() { 94 return method_index_; 95 } 96 97 inline uint32_t ArtMethod::GetDexMethodIndex() { 98 if (kCheckDeclaringClassState) { 99 CHECK(IsRuntimeMethod() || GetDeclaringClass()->IsIdxLoaded() || 100 GetDeclaringClass()->IsErroneous()); 101 } 102 return GetDexMethodIndexUnchecked(); 103 } 104 105 inline mirror::MethodDexCacheType* ArtMethod::GetDexCacheResolvedMethods(PointerSize pointer_size) { 106 return GetNativePointer<mirror::MethodDexCacheType*>(DexCacheResolvedMethodsOffset(pointer_size), 107 pointer_size); 108 } 109 110 inline ArtMethod* ArtMethod::GetDexCacheResolvedMethod(uint16_t method_index, 111 PointerSize pointer_size) { 112 // NOTE: Unchecked, i.e. not throwing AIOOB. We don't even know the length here 113 // without accessing the DexCache and we don't want to do that in release build. 114 DCHECK_LT(method_index, GetInterfaceMethodIfProxy(pointer_size)->GetDexFile()->NumMethodIds()); 115 uint32_t slot_idx = method_index % mirror::DexCache::kDexCacheMethodCacheSize; 116 DCHECK_LT(slot_idx, GetInterfaceMethodIfProxy(pointer_size)->GetDexCache()->NumResolvedMethods()); 117 mirror::MethodDexCachePair pair = mirror::DexCache::GetNativePairPtrSize( 118 GetDexCacheResolvedMethods(pointer_size), slot_idx, pointer_size); 119 ArtMethod* method = pair.GetObjectForIndex(method_index); 120 if (LIKELY(method != nullptr)) { 121 auto* declaring_class = method->GetDeclaringClass(); 122 if (LIKELY(declaring_class == nullptr || !declaring_class->IsErroneous())) { 123 return method; 124 } 125 } 126 return nullptr; 127 } 128 129 inline void ArtMethod::SetDexCacheResolvedMethod(uint16_t method_index, 130 ArtMethod* new_method, 131 PointerSize pointer_size) { 132 // NOTE: Unchecked, i.e. not throwing AIOOB. We don't even know the length here 133 // without accessing the DexCache and we don't want to do that in release build. 134 DCHECK_LT(method_index, GetInterfaceMethodIfProxy(pointer_size)->GetDexFile()->NumMethodIds()); 135 DCHECK(new_method == nullptr || new_method->GetDeclaringClass() != nullptr); 136 uint32_t slot_idx = method_index % mirror::DexCache::kDexCacheMethodCacheSize; 137 DCHECK_LT(slot_idx, GetInterfaceMethodIfProxy(pointer_size)->GetDexCache()->NumResolvedMethods()); 138 mirror::MethodDexCachePair pair(new_method, method_index); 139 mirror::DexCache::SetNativePairPtrSize( 140 GetDexCacheResolvedMethods(pointer_size), slot_idx, pair, pointer_size); 141 } 142 143 inline bool ArtMethod::HasDexCacheResolvedMethods(PointerSize pointer_size) { 144 return GetDexCacheResolvedMethods(pointer_size) != nullptr; 145 } 146 147 inline bool ArtMethod::HasSameDexCacheResolvedMethods(ArtMethod* other, PointerSize pointer_size) { 148 return GetDexCacheResolvedMethods(pointer_size) == 149 other->GetDexCacheResolvedMethods(pointer_size); 150 } 151 152 inline bool ArtMethod::HasSameDexCacheResolvedMethods(mirror::MethodDexCacheType* other_cache, 153 PointerSize pointer_size) { 154 return GetDexCacheResolvedMethods(pointer_size) == other_cache; 155 } 156 157 inline mirror::Class* ArtMethod::GetClassFromTypeIndex(dex::TypeIndex type_idx, bool resolve) { 158 // TODO: Refactor this function into two functions, Resolve...() and Lookup...() 159 // so that we can properly annotate it with no-suspension possible / suspension possible. 160 ObjPtr<mirror::DexCache> dex_cache = GetDexCache(); 161 ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(type_idx); 162 if (UNLIKELY(type == nullptr)) { 163 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 164 if (resolve) { 165 type = class_linker->ResolveType(type_idx, this); 166 CHECK(type != nullptr || Thread::Current()->IsExceptionPending()); 167 } else { 168 type = class_linker->LookupResolvedType( 169 *dex_cache->GetDexFile(), type_idx, dex_cache, GetClassLoader()); 170 } 171 } 172 return type.Ptr(); 173 } 174 175 inline bool ArtMethod::CheckIncompatibleClassChange(InvokeType type) { 176 switch (type) { 177 case kStatic: 178 return !IsStatic(); 179 case kDirect: 180 return !IsDirect() || IsStatic(); 181 case kVirtual: { 182 // We have an error if we are direct or a non-copied (i.e. not part of a real class) interface 183 // method. 184 mirror::Class* methods_class = GetDeclaringClass(); 185 return IsDirect() || (methods_class->IsInterface() && !IsCopied()); 186 } 187 case kSuper: 188 // Constructors and static methods are called with invoke-direct. 189 return IsConstructor() || IsStatic(); 190 case kInterface: { 191 mirror::Class* methods_class = GetDeclaringClass(); 192 return IsDirect() || !(methods_class->IsInterface() || methods_class->IsObjectClass()); 193 } 194 default: 195 LOG(FATAL) << "Unreachable - invocation type: " << type; 196 UNREACHABLE(); 197 } 198 } 199 200 inline bool ArtMethod::IsCalleeSaveMethod() { 201 if (!IsRuntimeMethod()) { 202 return false; 203 } 204 Runtime* runtime = Runtime::Current(); 205 bool result = false; 206 for (uint32_t i = 0; i < static_cast<uint32_t>(CalleeSaveType::kLastCalleeSaveType); i++) { 207 if (this == runtime->GetCalleeSaveMethod(CalleeSaveType(i))) { 208 result = true; 209 break; 210 } 211 } 212 return result; 213 } 214 215 inline bool ArtMethod::IsResolutionMethod() { 216 bool result = this == Runtime::Current()->GetResolutionMethod(); 217 // Check that if we do think it is phony it looks like the resolution method. 218 DCHECK(!result || IsRuntimeMethod()); 219 return result; 220 } 221 222 inline bool ArtMethod::IsImtUnimplementedMethod() { 223 bool result = this == Runtime::Current()->GetImtUnimplementedMethod(); 224 // Check that if we do think it is phony it looks like the imt unimplemented method. 225 DCHECK(!result || IsRuntimeMethod()); 226 return result; 227 } 228 229 inline const DexFile* ArtMethod::GetDexFile() { 230 // It is safe to avoid the read barrier here since the dex file is constant, so if we read the 231 // from-space dex file pointer it will be equal to the to-space copy. 232 return GetDexCache<kWithoutReadBarrier>()->GetDexFile(); 233 } 234 235 inline const char* ArtMethod::GetDeclaringClassDescriptor() { 236 uint32_t dex_method_idx = GetDexMethodIndex(); 237 if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) { 238 return "<runtime method>"; 239 } 240 DCHECK(!IsProxyMethod()); 241 const DexFile* dex_file = GetDexFile(); 242 return dex_file->GetMethodDeclaringClassDescriptor(dex_file->GetMethodId(dex_method_idx)); 243 } 244 245 inline const char* ArtMethod::GetShorty() { 246 uint32_t unused_length; 247 return GetShorty(&unused_length); 248 } 249 250 inline const char* ArtMethod::GetShorty(uint32_t* out_length) { 251 DCHECK(!IsProxyMethod()); 252 const DexFile* dex_file = GetDexFile(); 253 return dex_file->GetMethodShorty(dex_file->GetMethodId(GetDexMethodIndex()), out_length); 254 } 255 256 inline const Signature ArtMethod::GetSignature() { 257 uint32_t dex_method_idx = GetDexMethodIndex(); 258 if (dex_method_idx != DexFile::kDexNoIndex) { 259 DCHECK(!IsProxyMethod()); 260 const DexFile* dex_file = GetDexFile(); 261 return dex_file->GetMethodSignature(dex_file->GetMethodId(dex_method_idx)); 262 } 263 return Signature::NoSignature(); 264 } 265 266 inline const char* ArtMethod::GetName() { 267 uint32_t dex_method_idx = GetDexMethodIndex(); 268 if (LIKELY(dex_method_idx != DexFile::kDexNoIndex)) { 269 DCHECK(!IsProxyMethod()); 270 const DexFile* dex_file = GetDexFile(); 271 return dex_file->GetMethodName(dex_file->GetMethodId(dex_method_idx)); 272 } 273 Runtime* const runtime = Runtime::Current(); 274 if (this == runtime->GetResolutionMethod()) { 275 return "<runtime internal resolution method>"; 276 } else if (this == runtime->GetImtConflictMethod()) { 277 return "<runtime internal imt conflict method>"; 278 } else if (this == runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveAllCalleeSaves)) { 279 return "<runtime internal callee-save all registers method>"; 280 } else if (this == runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveRefsOnly)) { 281 return "<runtime internal callee-save reference registers method>"; 282 } else if (this == runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveRefsAndArgs)) { 283 return "<runtime internal callee-save reference and argument registers method>"; 284 } else if (this == runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverything)) { 285 return "<runtime internal save-every-register method>"; 286 } else { 287 return "<unknown runtime internal method>"; 288 } 289 } 290 291 inline const DexFile::CodeItem* ArtMethod::GetCodeItem() { 292 return GetDexFile()->GetCodeItem(GetCodeItemOffset()); 293 } 294 295 inline bool ArtMethod::IsResolvedTypeIdx(dex::TypeIndex type_idx) { 296 DCHECK(!IsProxyMethod()); 297 return GetClassFromTypeIndex(type_idx, /* resolve */ false) != nullptr; 298 } 299 300 inline int32_t ArtMethod::GetLineNumFromDexPC(uint32_t dex_pc) { 301 DCHECK(!IsProxyMethod()); 302 if (dex_pc == DexFile::kDexNoIndex) { 303 return IsNative() ? -2 : -1; 304 } 305 return annotations::GetLineNumFromPC(GetDexFile(), this, dex_pc); 306 } 307 308 inline const DexFile::ProtoId& ArtMethod::GetPrototype() { 309 DCHECK(!IsProxyMethod()); 310 const DexFile* dex_file = GetDexFile(); 311 return dex_file->GetMethodPrototype(dex_file->GetMethodId(GetDexMethodIndex())); 312 } 313 314 inline const DexFile::TypeList* ArtMethod::GetParameterTypeList() { 315 DCHECK(!IsProxyMethod()); 316 const DexFile* dex_file = GetDexFile(); 317 const DexFile::ProtoId& proto = dex_file->GetMethodPrototype( 318 dex_file->GetMethodId(GetDexMethodIndex())); 319 return dex_file->GetProtoParameters(proto); 320 } 321 322 inline const char* ArtMethod::GetDeclaringClassSourceFile() { 323 DCHECK(!IsProxyMethod()); 324 return GetDeclaringClass()->GetSourceFile(); 325 } 326 327 inline uint16_t ArtMethod::GetClassDefIndex() { 328 DCHECK(!IsProxyMethod()); 329 if (LIKELY(!IsObsolete())) { 330 return GetDeclaringClass()->GetDexClassDefIndex(); 331 } else { 332 return FindObsoleteDexClassDefIndex(); 333 } 334 } 335 336 inline const DexFile::ClassDef& ArtMethod::GetClassDef() { 337 DCHECK(!IsProxyMethod()); 338 return GetDexFile()->GetClassDef(GetClassDefIndex()); 339 } 340 341 inline const char* ArtMethod::GetReturnTypeDescriptor() { 342 DCHECK(!IsProxyMethod()); 343 const DexFile* dex_file = GetDexFile(); 344 const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex()); 345 const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id); 346 return dex_file->GetTypeDescriptor(dex_file->GetTypeId(proto_id.return_type_idx_)); 347 } 348 349 inline Primitive::Type ArtMethod::GetReturnTypePrimitive() { 350 return Primitive::GetType(GetReturnTypeDescriptor()[0]); 351 } 352 353 inline const char* ArtMethod::GetTypeDescriptorFromTypeIdx(dex::TypeIndex type_idx) { 354 DCHECK(!IsProxyMethod()); 355 const DexFile* dex_file = GetDexFile(); 356 return dex_file->GetTypeDescriptor(dex_file->GetTypeId(type_idx)); 357 } 358 359 inline mirror::ClassLoader* ArtMethod::GetClassLoader() { 360 DCHECK(!IsProxyMethod()); 361 return GetDeclaringClass()->GetClassLoader(); 362 } 363 364 template <ReadBarrierOption kReadBarrierOption> 365 inline mirror::DexCache* ArtMethod::GetDexCache() { 366 if (LIKELY(!IsObsolete())) { 367 mirror::Class* klass = GetDeclaringClass<kReadBarrierOption>(); 368 return klass->GetDexCache<kDefaultVerifyFlags, kReadBarrierOption>(); 369 } else { 370 DCHECK(!IsProxyMethod()); 371 return GetObsoleteDexCache(); 372 } 373 } 374 375 inline bool ArtMethod::IsProxyMethod() { 376 // Avoid read barrier since the from-space version of the class will have the correct proxy class 377 // flags since they are constant for the lifetime of the class. 378 return GetDeclaringClass<kWithoutReadBarrier>()->IsProxyClass(); 379 } 380 381 inline ArtMethod* ArtMethod::GetInterfaceMethodIfProxy(PointerSize pointer_size) { 382 if (LIKELY(!IsProxyMethod())) { 383 return this; 384 } 385 uint32_t method_index = GetDexMethodIndex(); 386 uint32_t slot_idx = method_index % mirror::DexCache::kDexCacheMethodCacheSize; 387 mirror::MethodDexCachePair pair = mirror::DexCache::GetNativePairPtrSize( 388 GetDexCacheResolvedMethods(pointer_size), slot_idx, pointer_size); 389 ArtMethod* interface_method = pair.GetObjectForIndex(method_index); 390 if (LIKELY(interface_method != nullptr)) { 391 DCHECK_EQ(interface_method, Runtime::Current()->GetClassLinker()->FindMethodForProxy(this)); 392 } else { 393 interface_method = Runtime::Current()->GetClassLinker()->FindMethodForProxy(this); 394 DCHECK(interface_method != nullptr); 395 } 396 return interface_method; 397 } 398 399 inline void ArtMethod::SetDexCacheResolvedMethods(mirror::MethodDexCacheType* new_dex_cache_methods, 400 PointerSize pointer_size) { 401 SetNativePointer(DexCacheResolvedMethodsOffset(pointer_size), 402 new_dex_cache_methods, 403 pointer_size); 404 } 405 406 inline mirror::Class* ArtMethod::GetReturnType(bool resolve) { 407 DCHECK(!IsProxyMethod()); 408 const DexFile* dex_file = GetDexFile(); 409 const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex()); 410 const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id); 411 dex::TypeIndex return_type_idx = proto_id.return_type_idx_; 412 return GetClassFromTypeIndex(return_type_idx, resolve); 413 } 414 415 inline bool ArtMethod::HasSingleImplementation() { 416 if (IsFinal() || GetDeclaringClass()->IsFinal()) { 417 // We don't set kAccSingleImplementation for these cases since intrinsic 418 // can use the flag also. 419 return true; 420 } 421 return (GetAccessFlags() & kAccSingleImplementation) != 0; 422 } 423 424 inline void ArtMethod::SetIntrinsic(uint32_t intrinsic) { 425 DCHECK(IsUint<8>(intrinsic)); 426 // Currently we only do intrinsics for static/final methods or methods of final 427 // classes. We don't set kHasSingleImplementation for those methods. 428 DCHECK(IsStatic() || IsFinal() || GetDeclaringClass()->IsFinal()) << 429 "Potential conflict with kAccSingleImplementation"; 430 uint32_t new_value = (GetAccessFlags() & kAccFlagsNotUsedByIntrinsic) | 431 kAccIntrinsic | 432 (intrinsic << POPCOUNT(kAccFlagsNotUsedByIntrinsic)); 433 if (kIsDebugBuild) { 434 uint32_t java_flags = (GetAccessFlags() & kAccJavaFlagsMask); 435 bool is_constructor = IsConstructor(); 436 bool is_synchronized = IsSynchronized(); 437 bool skip_access_checks = SkipAccessChecks(); 438 bool is_fast_native = IsFastNative(); 439 bool is_copied = IsCopied(); 440 bool is_miranda = IsMiranda(); 441 bool is_default = IsDefault(); 442 bool is_default_conflict = IsDefaultConflicting(); 443 bool is_compilable = IsCompilable(); 444 bool must_count_locks = MustCountLocks(); 445 SetAccessFlags(new_value); 446 DCHECK_EQ(java_flags, (GetAccessFlags() & kAccJavaFlagsMask)); 447 DCHECK_EQ(is_constructor, IsConstructor()); 448 DCHECK_EQ(is_synchronized, IsSynchronized()); 449 DCHECK_EQ(skip_access_checks, SkipAccessChecks()); 450 DCHECK_EQ(is_fast_native, IsFastNative()); 451 DCHECK_EQ(is_copied, IsCopied()); 452 DCHECK_EQ(is_miranda, IsMiranda()); 453 DCHECK_EQ(is_default, IsDefault()); 454 DCHECK_EQ(is_default_conflict, IsDefaultConflicting()); 455 DCHECK_EQ(is_compilable, IsCompilable()); 456 DCHECK_EQ(must_count_locks, MustCountLocks()); 457 } else { 458 SetAccessFlags(new_value); 459 } 460 } 461 462 template<ReadBarrierOption kReadBarrierOption, typename RootVisitorType> 463 void ArtMethod::VisitRoots(RootVisitorType& visitor, PointerSize pointer_size) { 464 if (LIKELY(!declaring_class_.IsNull())) { 465 visitor.VisitRoot(declaring_class_.AddressWithoutBarrier()); 466 mirror::Class* klass = declaring_class_.Read<kReadBarrierOption>(); 467 if (UNLIKELY(klass->IsProxyClass())) { 468 // For normal methods, dex cache shortcuts will be visited through the declaring class. 469 // However, for proxies we need to keep the interface method alive, so we visit its roots. 470 ArtMethod* interface_method = GetInterfaceMethodIfProxy(pointer_size); 471 DCHECK(interface_method != nullptr); 472 interface_method->VisitRoots(visitor, pointer_size); 473 } 474 } 475 } 476 477 template <typename Visitor> 478 inline void ArtMethod::UpdateObjectsForImageRelocation(const Visitor& visitor, 479 PointerSize pointer_size) { 480 mirror::Class* old_class = GetDeclaringClassUnchecked<kWithoutReadBarrier>(); 481 mirror::Class* new_class = visitor(old_class); 482 if (old_class != new_class) { 483 SetDeclaringClass(new_class); 484 } 485 mirror::MethodDexCacheType* old_methods = GetDexCacheResolvedMethods(pointer_size); 486 mirror::MethodDexCacheType* new_methods = visitor(old_methods); 487 if (old_methods != new_methods) { 488 SetDexCacheResolvedMethods(new_methods, pointer_size); 489 } 490 } 491 492 template <ReadBarrierOption kReadBarrierOption, typename Visitor> 493 inline void ArtMethod::UpdateEntrypoints(const Visitor& visitor, PointerSize pointer_size) { 494 if (IsNative<kReadBarrierOption>()) { 495 const void* old_native_code = GetEntryPointFromJniPtrSize(pointer_size); 496 const void* new_native_code = visitor(old_native_code); 497 if (old_native_code != new_native_code) { 498 SetEntryPointFromJniPtrSize(new_native_code, pointer_size); 499 } 500 } else { 501 DCHECK(GetDataPtrSize(pointer_size) == nullptr); 502 } 503 const void* old_code = GetEntryPointFromQuickCompiledCodePtrSize(pointer_size); 504 const void* new_code = visitor(old_code); 505 if (old_code != new_code) { 506 SetEntryPointFromQuickCompiledCodePtrSize(new_code, pointer_size); 507 } 508 } 509 510 } // namespace art 511 512 #endif // ART_RUNTIME_ART_METHOD_INL_H_ 513