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/logging.h" 24 #include "class_linker-inl.h" 25 #include "common_throws.h" 26 #include "dex_file.h" 27 #include "dex_file-inl.h" 28 #include "gc_root-inl.h" 29 #include "jit/profiling_info.h" 30 #include "mirror/class-inl.h" 31 #include "mirror/dex_cache-inl.h" 32 #include "mirror/object-inl.h" 33 #include "mirror/object_array.h" 34 #include "oat.h" 35 #include "quick/quick_method_frame_info.h" 36 #include "read_barrier-inl.h" 37 #include "runtime-inl.h" 38 #include "scoped_thread_state_change.h" 39 #include "thread-inl.h" 40 #include "utils.h" 41 42 namespace art { 43 44 template <ReadBarrierOption kReadBarrierOption> 45 inline mirror::Class* ArtMethod::GetDeclaringClassUnchecked() { 46 GcRootSource gc_root_source(this); 47 return declaring_class_.Read<kReadBarrierOption>(&gc_root_source); 48 } 49 50 template <ReadBarrierOption kReadBarrierOption> 51 inline mirror::Class* ArtMethod::GetDeclaringClass() { 52 mirror::Class* result = GetDeclaringClassUnchecked<kReadBarrierOption>(); 53 if (kIsDebugBuild) { 54 if (!IsRuntimeMethod()) { 55 CHECK(result != nullptr) << this; 56 CHECK(result->IsIdxLoaded() || result->IsErroneous()) 57 << result->GetStatus() << " " << PrettyClass(result); 58 } else { 59 CHECK(result == nullptr) << this; 60 } 61 } 62 return result; 63 } 64 65 inline void ArtMethod::SetDeclaringClass(mirror::Class* new_declaring_class) { 66 declaring_class_ = GcRoot<mirror::Class>(new_declaring_class); 67 } 68 69 inline bool ArtMethod::CASDeclaringClass(mirror::Class* expected_class, 70 mirror::Class* desired_class) { 71 GcRoot<mirror::Class> expected_root(expected_class); 72 GcRoot<mirror::Class> desired_root(desired_class); 73 return reinterpret_cast<Atomic<GcRoot<mirror::Class>>*>(&declaring_class_)-> 74 CompareExchangeStrongSequentiallyConsistent( 75 expected_root, desired_root); 76 } 77 78 // AssertSharedHeld doesn't work in GetAccessFlags, so use a NO_THREAD_SAFETY_ANALYSIS helper. 79 // TODO: Figure out why ASSERT_SHARED_CAPABILITY doesn't work. 80 template <ReadBarrierOption kReadBarrierOption> 81 ALWAYS_INLINE static inline void DoGetAccessFlagsHelper(ArtMethod* method) 82 NO_THREAD_SAFETY_ANALYSIS { 83 CHECK(method->IsRuntimeMethod() || 84 method->GetDeclaringClass<kReadBarrierOption>()->IsIdxLoaded() || 85 method->GetDeclaringClass<kReadBarrierOption>()->IsErroneous()); 86 } 87 88 template <ReadBarrierOption kReadBarrierOption> 89 inline uint32_t ArtMethod::GetAccessFlags() { 90 if (kIsDebugBuild) { 91 Thread* self = Thread::Current(); 92 if (!Locks::mutator_lock_->IsSharedHeld(self)) { 93 ScopedObjectAccess soa(self); 94 CHECK(IsRuntimeMethod() || 95 GetDeclaringClass<kReadBarrierOption>()->IsIdxLoaded() || 96 GetDeclaringClass<kReadBarrierOption>()->IsErroneous()); 97 } else { 98 // We cannot use SOA in this case. We might be holding the lock, but may not be in the 99 // runnable state (e.g., during GC). 100 Locks::mutator_lock_->AssertSharedHeld(self); 101 DoGetAccessFlagsHelper<kReadBarrierOption>(this); 102 } 103 } 104 return access_flags_; 105 } 106 107 inline uint16_t ArtMethod::GetMethodIndex() { 108 DCHECK(IsRuntimeMethod() || GetDeclaringClass()->IsResolved() || 109 GetDeclaringClass()->IsErroneous()); 110 return method_index_; 111 } 112 113 inline uint16_t ArtMethod::GetMethodIndexDuringLinking() { 114 return method_index_; 115 } 116 117 inline uint32_t ArtMethod::GetDexMethodIndex() { 118 DCHECK(IsRuntimeMethod() || GetDeclaringClass()->IsIdxLoaded() || 119 GetDeclaringClass()->IsErroneous()); 120 return dex_method_index_; 121 } 122 123 inline ArtMethod** ArtMethod::GetDexCacheResolvedMethods(size_t pointer_size) { 124 return GetNativePointer<ArtMethod**>(DexCacheResolvedMethodsOffset(pointer_size), 125 pointer_size); 126 } 127 128 inline ArtMethod* ArtMethod::GetDexCacheResolvedMethod(uint16_t method_index, size_t ptr_size) { 129 // NOTE: Unchecked, i.e. not throwing AIOOB. We don't even know the length here 130 // without accessing the DexCache and we don't want to do that in release build. 131 DCHECK_LT(method_index, 132 GetInterfaceMethodIfProxy(ptr_size)->GetDeclaringClass() 133 ->GetDexCache()->NumResolvedMethods()); 134 ArtMethod* method = mirror::DexCache::GetElementPtrSize(GetDexCacheResolvedMethods(ptr_size), 135 method_index, 136 ptr_size); 137 if (LIKELY(method != nullptr)) { 138 auto* declaring_class = method->GetDeclaringClass(); 139 if (LIKELY(declaring_class == nullptr || !declaring_class->IsErroneous())) { 140 return method; 141 } 142 } 143 return nullptr; 144 } 145 146 inline void ArtMethod::SetDexCacheResolvedMethod(uint16_t method_index, ArtMethod* new_method, 147 size_t ptr_size) { 148 // NOTE: Unchecked, i.e. not throwing AIOOB. We don't even know the length here 149 // without accessing the DexCache and we don't want to do that in release build. 150 DCHECK_LT(method_index, 151 GetInterfaceMethodIfProxy(ptr_size)->GetDeclaringClass() 152 ->GetDexCache()->NumResolvedMethods()); 153 DCHECK(new_method == nullptr || new_method->GetDeclaringClass() != nullptr); 154 mirror::DexCache::SetElementPtrSize(GetDexCacheResolvedMethods(ptr_size), 155 method_index, 156 new_method, 157 ptr_size); 158 } 159 160 inline bool ArtMethod::HasDexCacheResolvedMethods(size_t pointer_size) { 161 return GetDexCacheResolvedMethods(pointer_size) != nullptr; 162 } 163 164 inline bool ArtMethod::HasSameDexCacheResolvedMethods(ArtMethod** other_cache, 165 size_t pointer_size) { 166 return GetDexCacheResolvedMethods(pointer_size) == other_cache; 167 } 168 169 inline bool ArtMethod::HasSameDexCacheResolvedMethods(ArtMethod* other, size_t pointer_size) { 170 return GetDexCacheResolvedMethods(pointer_size) == 171 other->GetDexCacheResolvedMethods(pointer_size); 172 } 173 174 inline GcRoot<mirror::Class>* ArtMethod::GetDexCacheResolvedTypes(size_t pointer_size) { 175 return GetNativePointer<GcRoot<mirror::Class>*>(DexCacheResolvedTypesOffset(pointer_size), 176 pointer_size); 177 } 178 179 template <bool kWithCheck> 180 inline mirror::Class* ArtMethod::GetDexCacheResolvedType(uint32_t type_index, size_t ptr_size) { 181 if (kWithCheck) { 182 mirror::DexCache* dex_cache = 183 GetInterfaceMethodIfProxy(ptr_size)->GetDeclaringClass()->GetDexCache(); 184 if (UNLIKELY(type_index >= dex_cache->NumResolvedTypes())) { 185 ThrowArrayIndexOutOfBoundsException(type_index, dex_cache->NumResolvedTypes()); 186 return nullptr; 187 } 188 } 189 mirror::Class* klass = GetDexCacheResolvedTypes(ptr_size)[type_index].Read(); 190 return (klass != nullptr && !klass->IsErroneous()) ? klass : nullptr; 191 } 192 193 inline bool ArtMethod::HasDexCacheResolvedTypes(size_t pointer_size) { 194 return GetDexCacheResolvedTypes(pointer_size) != nullptr; 195 } 196 197 inline bool ArtMethod::HasSameDexCacheResolvedTypes(GcRoot<mirror::Class>* other_cache, 198 size_t pointer_size) { 199 return GetDexCacheResolvedTypes(pointer_size) == other_cache; 200 } 201 202 inline bool ArtMethod::HasSameDexCacheResolvedTypes(ArtMethod* other, size_t pointer_size) { 203 return GetDexCacheResolvedTypes(pointer_size) == other->GetDexCacheResolvedTypes(pointer_size); 204 } 205 206 inline mirror::Class* ArtMethod::GetClassFromTypeIndex(uint16_t type_idx, 207 bool resolve, 208 size_t ptr_size) { 209 mirror::Class* type = GetDexCacheResolvedType(type_idx, ptr_size); 210 if (type == nullptr && resolve) { 211 type = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, this); 212 CHECK(type != nullptr || Thread::Current()->IsExceptionPending()); 213 } 214 return type; 215 } 216 217 inline bool ArtMethod::CheckIncompatibleClassChange(InvokeType type) { 218 switch (type) { 219 case kStatic: 220 return !IsStatic(); 221 case kDirect: 222 return !IsDirect() || IsStatic(); 223 case kVirtual: { 224 // We have an error if we are direct or a non-default, non-miranda interface method. 225 mirror::Class* methods_class = GetDeclaringClass(); 226 return IsDirect() || (methods_class->IsInterface() && !IsDefault() && !IsMiranda()); 227 } 228 case kSuper: 229 // Constructors and static methods are called with invoke-direct. 230 return IsConstructor() || IsStatic(); 231 case kInterface: { 232 mirror::Class* methods_class = GetDeclaringClass(); 233 return IsDirect() || !(methods_class->IsInterface() || methods_class->IsObjectClass()); 234 } 235 default: 236 LOG(FATAL) << "Unreachable - invocation type: " << type; 237 UNREACHABLE(); 238 } 239 } 240 241 inline bool ArtMethod::IsRuntimeMethod() { 242 return dex_method_index_ == DexFile::kDexNoIndex; 243 } 244 245 inline bool ArtMethod::IsCalleeSaveMethod() { 246 if (!IsRuntimeMethod()) { 247 return false; 248 } 249 Runtime* runtime = Runtime::Current(); 250 bool result = false; 251 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 252 if (this == runtime->GetCalleeSaveMethod(Runtime::CalleeSaveType(i))) { 253 result = true; 254 break; 255 } 256 } 257 return result; 258 } 259 260 inline bool ArtMethod::IsResolutionMethod() { 261 bool result = this == Runtime::Current()->GetResolutionMethod(); 262 // Check that if we do think it is phony it looks like the resolution method. 263 DCHECK(!result || IsRuntimeMethod()); 264 return result; 265 } 266 267 inline bool ArtMethod::IsImtUnimplementedMethod() { 268 bool result = this == Runtime::Current()->GetImtUnimplementedMethod(); 269 // Check that if we do think it is phony it looks like the imt unimplemented method. 270 DCHECK(!result || IsRuntimeMethod()); 271 return result; 272 } 273 274 inline const DexFile* ArtMethod::GetDexFile() { 275 return GetDexCache()->GetDexFile(); 276 } 277 278 inline const char* ArtMethod::GetDeclaringClassDescriptor() { 279 uint32_t dex_method_idx = GetDexMethodIndex(); 280 if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) { 281 return "<runtime method>"; 282 } 283 DCHECK(!IsProxyMethod()); 284 const DexFile* dex_file = GetDexFile(); 285 return dex_file->GetMethodDeclaringClassDescriptor(dex_file->GetMethodId(dex_method_idx)); 286 } 287 288 inline const char* ArtMethod::GetShorty(uint32_t* out_length) { 289 DCHECK(!IsProxyMethod()); 290 const DexFile* dex_file = GetDexFile(); 291 return dex_file->GetMethodShorty(dex_file->GetMethodId(GetDexMethodIndex()), out_length); 292 } 293 294 inline const Signature ArtMethod::GetSignature() { 295 uint32_t dex_method_idx = GetDexMethodIndex(); 296 if (dex_method_idx != DexFile::kDexNoIndex) { 297 DCHECK(!IsProxyMethod()); 298 const DexFile* dex_file = GetDexFile(); 299 return dex_file->GetMethodSignature(dex_file->GetMethodId(dex_method_idx)); 300 } 301 return Signature::NoSignature(); 302 } 303 304 inline const char* ArtMethod::GetName() { 305 uint32_t dex_method_idx = GetDexMethodIndex(); 306 if (LIKELY(dex_method_idx != DexFile::kDexNoIndex)) { 307 DCHECK(!IsProxyMethod()); 308 const DexFile* dex_file = GetDexFile(); 309 return dex_file->GetMethodName(dex_file->GetMethodId(dex_method_idx)); 310 } 311 Runtime* const runtime = Runtime::Current(); 312 if (this == runtime->GetResolutionMethod()) { 313 return "<runtime internal resolution method>"; 314 } else if (this == runtime->GetImtConflictMethod()) { 315 return "<runtime internal imt conflict method>"; 316 } else if (this == runtime->GetCalleeSaveMethod(Runtime::kSaveAll)) { 317 return "<runtime internal callee-save all registers method>"; 318 } else if (this == runtime->GetCalleeSaveMethod(Runtime::kRefsOnly)) { 319 return "<runtime internal callee-save reference registers method>"; 320 } else if (this == runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs)) { 321 return "<runtime internal callee-save reference and argument registers method>"; 322 } else { 323 return "<unknown runtime internal method>"; 324 } 325 } 326 327 inline const DexFile::CodeItem* ArtMethod::GetCodeItem() { 328 return GetDeclaringClass()->GetDexFile().GetCodeItem(GetCodeItemOffset()); 329 } 330 331 inline bool ArtMethod::IsResolvedTypeIdx(uint16_t type_idx, size_t ptr_size) { 332 DCHECK(!IsProxyMethod()); 333 return GetDexCacheResolvedType(type_idx, ptr_size) != nullptr; 334 } 335 336 inline int32_t ArtMethod::GetLineNumFromDexPC(uint32_t dex_pc) { 337 DCHECK(!IsProxyMethod()); 338 if (dex_pc == DexFile::kDexNoIndex) { 339 return IsNative() ? -2 : -1; 340 } 341 return GetDexFile()->GetLineNumFromPC(this, dex_pc); 342 } 343 344 inline const DexFile::ProtoId& ArtMethod::GetPrototype() { 345 DCHECK(!IsProxyMethod()); 346 const DexFile* dex_file = GetDexFile(); 347 return dex_file->GetMethodPrototype(dex_file->GetMethodId(GetDexMethodIndex())); 348 } 349 350 inline const DexFile::TypeList* ArtMethod::GetParameterTypeList() { 351 DCHECK(!IsProxyMethod()); 352 const DexFile* dex_file = GetDexFile(); 353 const DexFile::ProtoId& proto = dex_file->GetMethodPrototype( 354 dex_file->GetMethodId(GetDexMethodIndex())); 355 return dex_file->GetProtoParameters(proto); 356 } 357 358 inline const char* ArtMethod::GetDeclaringClassSourceFile() { 359 DCHECK(!IsProxyMethod()); 360 return GetDeclaringClass()->GetSourceFile(); 361 } 362 363 inline uint16_t ArtMethod::GetClassDefIndex() { 364 DCHECK(!IsProxyMethod()); 365 return GetDeclaringClass()->GetDexClassDefIndex(); 366 } 367 368 inline const DexFile::ClassDef& ArtMethod::GetClassDef() { 369 DCHECK(!IsProxyMethod()); 370 return GetDexFile()->GetClassDef(GetClassDefIndex()); 371 } 372 373 inline const char* ArtMethod::GetReturnTypeDescriptor() { 374 DCHECK(!IsProxyMethod()); 375 const DexFile* dex_file = GetDexFile(); 376 const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex()); 377 const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id); 378 uint16_t return_type_idx = proto_id.return_type_idx_; 379 return dex_file->GetTypeDescriptor(dex_file->GetTypeId(return_type_idx)); 380 } 381 382 inline const char* ArtMethod::GetTypeDescriptorFromTypeIdx(uint16_t type_idx) { 383 DCHECK(!IsProxyMethod()); 384 const DexFile* dex_file = GetDexFile(); 385 return dex_file->GetTypeDescriptor(dex_file->GetTypeId(type_idx)); 386 } 387 388 inline mirror::ClassLoader* ArtMethod::GetClassLoader() { 389 DCHECK(!IsProxyMethod()); 390 return GetDeclaringClass()->GetClassLoader(); 391 } 392 393 inline mirror::DexCache* ArtMethod::GetDexCache() { 394 DCHECK(!IsProxyMethod()); 395 return GetDeclaringClass()->GetDexCache(); 396 } 397 398 inline bool ArtMethod::IsProxyMethod() { 399 return GetDeclaringClass()->IsProxyClass(); 400 } 401 402 inline ArtMethod* ArtMethod::GetInterfaceMethodIfProxy(size_t pointer_size) { 403 if (LIKELY(!IsProxyMethod())) { 404 return this; 405 } 406 mirror::Class* klass = GetDeclaringClass(); 407 ArtMethod* interface_method = mirror::DexCache::GetElementPtrSize( 408 GetDexCacheResolvedMethods(pointer_size), 409 GetDexMethodIndex(), 410 pointer_size); 411 DCHECK(interface_method != nullptr); 412 DCHECK_EQ(interface_method, 413 Runtime::Current()->GetClassLinker()->FindMethodForProxy(klass, this)); 414 return interface_method; 415 } 416 417 inline void ArtMethod::SetDexCacheResolvedMethods(ArtMethod** new_dex_cache_methods, 418 size_t ptr_size) { 419 SetNativePointer(DexCacheResolvedMethodsOffset(ptr_size), new_dex_cache_methods, ptr_size); 420 } 421 422 inline void ArtMethod::SetDexCacheResolvedTypes(GcRoot<mirror::Class>* new_dex_cache_types, 423 size_t ptr_size) { 424 SetNativePointer(DexCacheResolvedTypesOffset(ptr_size), new_dex_cache_types, ptr_size); 425 } 426 427 inline mirror::Class* ArtMethod::GetReturnType(bool resolve, size_t ptr_size) { 428 DCHECK(!IsProxyMethod()); 429 const DexFile* dex_file = GetDexFile(); 430 const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex()); 431 const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id); 432 uint16_t return_type_idx = proto_id.return_type_idx_; 433 mirror::Class* type = GetDexCacheResolvedType(return_type_idx, ptr_size); 434 if (type == nullptr && resolve) { 435 type = Runtime::Current()->GetClassLinker()->ResolveType(return_type_idx, this); 436 CHECK(type != nullptr || Thread::Current()->IsExceptionPending()); 437 } 438 return type; 439 } 440 441 template<typename RootVisitorType> 442 void ArtMethod::VisitRoots(RootVisitorType& visitor, size_t pointer_size) { 443 ArtMethod* interface_method = nullptr; 444 mirror::Class* klass = declaring_class_.Read(); 445 if (LIKELY(klass != nullptr)) { 446 if (UNLIKELY(klass->IsProxyClass())) { 447 // For normal methods, dex cache shortcuts will be visited through the declaring class. 448 // However, for proxies we need to keep the interface method alive, so we visit its roots. 449 interface_method = mirror::DexCache::GetElementPtrSize( 450 GetDexCacheResolvedMethods(pointer_size), 451 GetDexMethodIndex(), 452 pointer_size); 453 DCHECK(interface_method != nullptr); 454 DCHECK_EQ(interface_method, 455 Runtime::Current()->GetClassLinker()->FindMethodForProxy(klass, this)); 456 interface_method->VisitRoots(visitor, pointer_size); 457 } 458 visitor.VisitRoot(declaring_class_.AddressWithoutBarrier()); 459 // We know we don't have profiling information if the class hasn't been verified. Note 460 // that this check also ensures the IsNative call can be made, as IsNative expects a fully 461 // created class (and not a retired one). 462 if (klass->IsVerified()) { 463 // Runtime methods and native methods use the same field as the profiling info for 464 // storing their own data (jni entrypoint for native methods, and ImtConflictTable for 465 // some runtime methods). 466 if (!IsNative() && !IsRuntimeMethod()) { 467 ProfilingInfo* profiling_info = GetProfilingInfo(pointer_size); 468 if (profiling_info != nullptr) { 469 profiling_info->VisitRoots(visitor); 470 } 471 } 472 } 473 } 474 } 475 476 template <typename Visitor> 477 inline void ArtMethod::UpdateObjectsForImageRelocation(const Visitor& visitor, 478 size_t pointer_size) { 479 mirror::Class* old_class = GetDeclaringClassUnchecked<kWithoutReadBarrier>(); 480 mirror::Class* new_class = visitor(old_class); 481 if (old_class != new_class) { 482 SetDeclaringClass(new_class); 483 } 484 ArtMethod** old_methods = GetDexCacheResolvedMethods(pointer_size); 485 ArtMethod** new_methods = visitor(old_methods); 486 if (old_methods != new_methods) { 487 SetDexCacheResolvedMethods(new_methods, pointer_size); 488 } 489 GcRoot<mirror::Class>* old_types = GetDexCacheResolvedTypes(pointer_size); 490 GcRoot<mirror::Class>* new_types = visitor(old_types); 491 if (old_types != new_types) { 492 SetDexCacheResolvedTypes(new_types, pointer_size); 493 } 494 } 495 496 template <ReadBarrierOption kReadBarrierOption, typename Visitor> 497 inline void ArtMethod::UpdateEntrypoints(const Visitor& visitor, size_t pointer_size) { 498 if (IsNative<kReadBarrierOption>()) { 499 const void* old_native_code = GetEntryPointFromJniPtrSize(pointer_size); 500 const void* new_native_code = visitor(old_native_code); 501 if (old_native_code != new_native_code) { 502 SetEntryPointFromJniPtrSize(new_native_code, pointer_size); 503 } 504 } else { 505 DCHECK(GetEntryPointFromJniPtrSize(pointer_size) == nullptr); 506 } 507 const void* old_code = GetEntryPointFromQuickCompiledCodePtrSize(pointer_size); 508 const void* new_code = visitor(old_code); 509 if (old_code != new_code) { 510 SetEntryPointFromQuickCompiledCodePtrSize(new_code, pointer_size); 511 } 512 } 513 514 } // namespace art 515 516 #endif // ART_RUNTIME_ART_METHOD_INL_H_ 517