1 /* 2 * Copyright (C) 2012 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_ENTRYPOINTS_ENTRYPOINT_UTILS_INL_H_ 18 #define ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_INL_H_ 19 20 #include "entrypoint_utils.h" 21 22 #include "art_method.h" 23 #include "class_linker-inl.h" 24 #include "common_throws.h" 25 #include "dex_file.h" 26 #include "entrypoints/quick/callee_save_frame.h" 27 #include "handle_scope-inl.h" 28 #include "indirect_reference_table.h" 29 #include "invoke_type.h" 30 #include "jni_internal.h" 31 #include "mirror/array.h" 32 #include "mirror/class-inl.h" 33 #include "mirror/object-inl.h" 34 #include "mirror/throwable.h" 35 #include "nth_caller_visitor.h" 36 #include "runtime.h" 37 #include "stack_map.h" 38 #include "thread.h" 39 40 namespace art { 41 42 template <bool kResolve = true> 43 inline ArtMethod* GetResolvedMethod(ArtMethod* outer_method, 44 const InlineInfo& inline_info, 45 const InlineInfoEncoding& encoding, 46 uint8_t inlining_depth) 47 SHARED_REQUIRES(Locks::mutator_lock_) { 48 uint32_t method_index = inline_info.GetMethodIndexAtDepth(encoding, inlining_depth); 49 InvokeType invoke_type = static_cast<InvokeType>( 50 inline_info.GetInvokeTypeAtDepth(encoding, inlining_depth)); 51 ArtMethod* caller = outer_method->GetDexCacheResolvedMethod(method_index, sizeof(void*)); 52 if (!caller->IsRuntimeMethod()) { 53 return caller; 54 } 55 if (!kResolve) { 56 return nullptr; 57 } 58 59 // The method in the dex cache can be the runtime method responsible for invoking 60 // the stub that will then update the dex cache. Therefore, we need to do the 61 // resolution ourselves. 62 63 // We first find the class loader of our caller. If it is the outer method, we can directly 64 // use its class loader. Otherwise, we also need to resolve our caller. 65 StackHandleScope<2> hs(Thread::Current()); 66 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 67 MutableHandle<mirror::ClassLoader> class_loader(hs.NewHandle<mirror::Class>(nullptr)); 68 Handle<mirror::DexCache> dex_cache(hs.NewHandle(outer_method->GetDexCache())); 69 if (inlining_depth == 0) { 70 class_loader.Assign(outer_method->GetClassLoader()); 71 } else { 72 caller = GetResolvedMethod<kResolve>(outer_method, 73 inline_info, 74 encoding, 75 inlining_depth - 1); 76 class_loader.Assign(caller->GetClassLoader()); 77 } 78 79 return class_linker->ResolveMethod<ClassLinker::kNoICCECheckForCache>( 80 *outer_method->GetDexFile(), method_index, dex_cache, class_loader, nullptr, invoke_type); 81 } 82 83 inline ArtMethod* GetCalleeSaveMethodCaller(Thread* self, Runtime::CalleeSaveType type) 84 SHARED_REQUIRES(Locks::mutator_lock_) { 85 return GetCalleeSaveMethodCaller( 86 self->GetManagedStack()->GetTopQuickFrame(), type, true /* do_caller_check */); 87 } 88 89 template <const bool kAccessCheck> 90 ALWAYS_INLINE 91 inline mirror::Class* CheckObjectAlloc(uint32_t type_idx, 92 ArtMethod* method, 93 Thread* self, bool* slow_path) { 94 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 95 size_t pointer_size = class_linker->GetImagePointerSize(); 96 mirror::Class* klass = method->GetDexCacheResolvedType<false>(type_idx, pointer_size); 97 if (UNLIKELY(klass == nullptr)) { 98 klass = class_linker->ResolveType(type_idx, method); 99 *slow_path = true; 100 if (klass == nullptr) { 101 DCHECK(self->IsExceptionPending()); 102 return nullptr; // Failure 103 } else { 104 DCHECK(!self->IsExceptionPending()); 105 } 106 } 107 if (kAccessCheck) { 108 if (UNLIKELY(!klass->IsInstantiable())) { 109 self->ThrowNewException("Ljava/lang/InstantiationError;", PrettyDescriptor(klass).c_str()); 110 *slow_path = true; 111 return nullptr; // Failure 112 } 113 mirror::Class* referrer = method->GetDeclaringClass(); 114 if (UNLIKELY(!referrer->CanAccess(klass))) { 115 ThrowIllegalAccessErrorClass(referrer, klass); 116 *slow_path = true; 117 return nullptr; // Failure 118 } 119 } 120 if (UNLIKELY(!klass->IsInitialized())) { 121 StackHandleScope<1> hs(self); 122 Handle<mirror::Class> h_klass(hs.NewHandle(klass)); 123 // EnsureInitialized (the class initializer) might cause a GC. 124 // may cause us to suspend meaning that another thread may try to 125 // change the allocator while we are stuck in the entrypoints of 126 // an old allocator. Also, the class initialization may fail. To 127 // handle these cases we mark the slow path boolean as true so 128 // that the caller knows to check the allocator type to see if it 129 // has changed and to null-check the return value in case the 130 // initialization fails. 131 *slow_path = true; 132 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) { 133 DCHECK(self->IsExceptionPending()); 134 return nullptr; // Failure 135 } else { 136 DCHECK(!self->IsExceptionPending()); 137 } 138 return h_klass.Get(); 139 } 140 return klass; 141 } 142 143 ALWAYS_INLINE 144 inline mirror::Class* CheckClassInitializedForObjectAlloc(mirror::Class* klass, 145 Thread* self, 146 bool* slow_path) { 147 if (UNLIKELY(!klass->IsInitialized())) { 148 StackHandleScope<1> hs(self); 149 Handle<mirror::Class> h_class(hs.NewHandle(klass)); 150 // EnsureInitialized (the class initializer) might cause a GC. 151 // may cause us to suspend meaning that another thread may try to 152 // change the allocator while we are stuck in the entrypoints of 153 // an old allocator. Also, the class initialization may fail. To 154 // handle these cases we mark the slow path boolean as true so 155 // that the caller knows to check the allocator type to see if it 156 // has changed and to null-check the return value in case the 157 // initialization fails. 158 *slow_path = true; 159 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) { 160 DCHECK(self->IsExceptionPending()); 161 return nullptr; // Failure 162 } 163 return h_class.Get(); 164 } 165 return klass; 166 } 167 168 // Given the context of a calling Method, use its DexCache to resolve a type to a Class. If it 169 // cannot be resolved, throw an error. If it can, use it to create an instance. 170 // When verification/compiler hasn't been able to verify access, optionally perform an access 171 // check. 172 template <bool kAccessCheck, bool kInstrumented> 173 ALWAYS_INLINE 174 inline mirror::Object* AllocObjectFromCode(uint32_t type_idx, 175 ArtMethod* method, 176 Thread* self, 177 gc::AllocatorType allocator_type) { 178 bool slow_path = false; 179 mirror::Class* klass = CheckObjectAlloc<kAccessCheck>(type_idx, method, self, &slow_path); 180 if (UNLIKELY(slow_path)) { 181 if (klass == nullptr) { 182 return nullptr; 183 } 184 // CheckObjectAlloc can cause thread suspension which means we may now be instrumented. 185 return klass->Alloc</*kInstrumented*/true>( 186 self, 187 Runtime::Current()->GetHeap()->GetCurrentAllocator()); 188 } 189 DCHECK(klass != nullptr); 190 return klass->Alloc<kInstrumented>(self, allocator_type); 191 } 192 193 // Given the context of a calling Method and a resolved class, create an instance. 194 template <bool kInstrumented> 195 ALWAYS_INLINE 196 inline mirror::Object* AllocObjectFromCodeResolved(mirror::Class* klass, 197 Thread* self, 198 gc::AllocatorType allocator_type) { 199 DCHECK(klass != nullptr); 200 bool slow_path = false; 201 klass = CheckClassInitializedForObjectAlloc(klass, self, &slow_path); 202 if (UNLIKELY(slow_path)) { 203 if (klass == nullptr) { 204 return nullptr; 205 } 206 gc::Heap* heap = Runtime::Current()->GetHeap(); 207 // Pass in false since the object cannot be finalizable. 208 // CheckClassInitializedForObjectAlloc can cause thread suspension which means we may now be 209 // instrumented. 210 return klass->Alloc</*kInstrumented*/true, false>(self, heap->GetCurrentAllocator()); 211 } 212 // Pass in false since the object cannot be finalizable. 213 return klass->Alloc<kInstrumented, false>(self, allocator_type); 214 } 215 216 // Given the context of a calling Method and an initialized class, create an instance. 217 template <bool kInstrumented> 218 ALWAYS_INLINE 219 inline mirror::Object* AllocObjectFromCodeInitialized(mirror::Class* klass, 220 Thread* self, 221 gc::AllocatorType allocator_type) { 222 DCHECK(klass != nullptr); 223 // Pass in false since the object cannot be finalizable. 224 return klass->Alloc<kInstrumented, false>(self, allocator_type); 225 } 226 227 228 template <bool kAccessCheck> 229 ALWAYS_INLINE 230 inline mirror::Class* CheckArrayAlloc(uint32_t type_idx, 231 int32_t component_count, 232 ArtMethod* method, 233 bool* slow_path) { 234 if (UNLIKELY(component_count < 0)) { 235 ThrowNegativeArraySizeException(component_count); 236 *slow_path = true; 237 return nullptr; // Failure 238 } 239 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 240 size_t pointer_size = class_linker->GetImagePointerSize(); 241 mirror::Class* klass = method->GetDexCacheResolvedType<false>(type_idx, pointer_size); 242 if (UNLIKELY(klass == nullptr)) { // Not in dex cache so try to resolve 243 klass = class_linker->ResolveType(type_idx, method); 244 *slow_path = true; 245 if (klass == nullptr) { // Error 246 DCHECK(Thread::Current()->IsExceptionPending()); 247 return nullptr; // Failure 248 } 249 CHECK(klass->IsArrayClass()) << PrettyClass(klass); 250 } 251 if (kAccessCheck) { 252 mirror::Class* referrer = method->GetDeclaringClass(); 253 if (UNLIKELY(!referrer->CanAccess(klass))) { 254 ThrowIllegalAccessErrorClass(referrer, klass); 255 *slow_path = true; 256 return nullptr; // Failure 257 } 258 } 259 return klass; 260 } 261 262 // Given the context of a calling Method, use its DexCache to resolve a type to an array Class. If 263 // it cannot be resolved, throw an error. If it can, use it to create an array. 264 // When verification/compiler hasn't been able to verify access, optionally perform an access 265 // check. 266 template <bool kAccessCheck, bool kInstrumented> 267 ALWAYS_INLINE 268 inline mirror::Array* AllocArrayFromCode(uint32_t type_idx, 269 int32_t component_count, 270 ArtMethod* method, 271 Thread* self, 272 gc::AllocatorType allocator_type) { 273 bool slow_path = false; 274 mirror::Class* klass = CheckArrayAlloc<kAccessCheck>(type_idx, component_count, method, 275 &slow_path); 276 if (UNLIKELY(slow_path)) { 277 if (klass == nullptr) { 278 return nullptr; 279 } 280 gc::Heap* heap = Runtime::Current()->GetHeap(); 281 // CheckArrayAlloc can cause thread suspension which means we may now be instrumented. 282 return mirror::Array::Alloc</*kInstrumented*/true>(self, 283 klass, 284 component_count, 285 klass->GetComponentSizeShift(), 286 heap->GetCurrentAllocator()); 287 } 288 return mirror::Array::Alloc<kInstrumented>(self, klass, component_count, 289 klass->GetComponentSizeShift(), allocator_type); 290 } 291 292 template <bool kAccessCheck, bool kInstrumented> 293 ALWAYS_INLINE 294 inline mirror::Array* AllocArrayFromCodeResolved(mirror::Class* klass, 295 int32_t component_count, 296 ArtMethod* method, 297 Thread* self, 298 gc::AllocatorType allocator_type) { 299 DCHECK(klass != nullptr); 300 if (UNLIKELY(component_count < 0)) { 301 ThrowNegativeArraySizeException(component_count); 302 return nullptr; // Failure 303 } 304 if (kAccessCheck) { 305 mirror::Class* referrer = method->GetDeclaringClass(); 306 if (UNLIKELY(!referrer->CanAccess(klass))) { 307 ThrowIllegalAccessErrorClass(referrer, klass); 308 return nullptr; // Failure 309 } 310 } 311 // No need to retry a slow-path allocation as the above code won't cause a GC or thread 312 // suspension. 313 return mirror::Array::Alloc<kInstrumented>(self, klass, component_count, 314 klass->GetComponentSizeShift(), allocator_type); 315 } 316 317 template<FindFieldType type, bool access_check> 318 inline ArtField* FindFieldFromCode(uint32_t field_idx, 319 ArtMethod* referrer, 320 Thread* self, 321 size_t expected_size) REQUIRES(!Roles::uninterruptible_) { 322 bool is_primitive; 323 bool is_set; 324 bool is_static; 325 switch (type) { 326 case InstanceObjectRead: is_primitive = false; is_set = false; is_static = false; break; 327 case InstanceObjectWrite: is_primitive = false; is_set = true; is_static = false; break; 328 case InstancePrimitiveRead: is_primitive = true; is_set = false; is_static = false; break; 329 case InstancePrimitiveWrite: is_primitive = true; is_set = true; is_static = false; break; 330 case StaticObjectRead: is_primitive = false; is_set = false; is_static = true; break; 331 case StaticObjectWrite: is_primitive = false; is_set = true; is_static = true; break; 332 case StaticPrimitiveRead: is_primitive = true; is_set = false; is_static = true; break; 333 case StaticPrimitiveWrite: // Keep GCC happy by having a default handler, fall-through. 334 default: is_primitive = true; is_set = true; is_static = true; break; 335 } 336 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 337 338 ArtField* resolved_field; 339 if (access_check) { 340 // Slow path: According to JLS 13.4.8, a linkage error may occur if a compile-time 341 // qualifying type of a field and the resolved run-time qualifying type of a field differed 342 // in their static-ness. 343 // 344 // In particular, don't assume the dex instruction already correctly knows if the 345 // real field is static or not. The resolution must not be aware of this. 346 ArtMethod* method = referrer->GetInterfaceMethodIfProxy(sizeof(void*)); 347 348 StackHandleScope<2> hs(self); 349 Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(method->GetDexCache())); 350 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(method->GetClassLoader())); 351 352 resolved_field = class_linker->ResolveFieldJLS(*method->GetDexFile(), 353 field_idx, 354 h_dex_cache, 355 h_class_loader); 356 } else { 357 // Fast path: Verifier already would've called ResolveFieldJLS and we wouldn't 358 // be executing here if there was a static/non-static mismatch. 359 resolved_field = class_linker->ResolveField(field_idx, referrer, is_static); 360 } 361 362 if (UNLIKELY(resolved_field == nullptr)) { 363 DCHECK(self->IsExceptionPending()); // Throw exception and unwind. 364 return nullptr; // Failure. 365 } 366 mirror::Class* fields_class = resolved_field->GetDeclaringClass(); 367 if (access_check) { 368 if (UNLIKELY(resolved_field->IsStatic() != is_static)) { 369 ThrowIncompatibleClassChangeErrorField(resolved_field, is_static, referrer); 370 return nullptr; 371 } 372 mirror::Class* referring_class = referrer->GetDeclaringClass(); 373 if (UNLIKELY(!referring_class->CheckResolvedFieldAccess(fields_class, resolved_field, 374 field_idx))) { 375 DCHECK(self->IsExceptionPending()); // Throw exception and unwind. 376 return nullptr; // Failure. 377 } 378 if (UNLIKELY(is_set && resolved_field->IsFinal() && (fields_class != referring_class))) { 379 ThrowIllegalAccessErrorFinalField(referrer, resolved_field); 380 return nullptr; // Failure. 381 } else { 382 if (UNLIKELY(resolved_field->IsPrimitiveType() != is_primitive || 383 resolved_field->FieldSize() != expected_size)) { 384 self->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;", 385 "Attempted read of %zd-bit %s on field '%s'", 386 expected_size * (32 / sizeof(int32_t)), 387 is_primitive ? "primitive" : "non-primitive", 388 PrettyField(resolved_field, true).c_str()); 389 return nullptr; // Failure. 390 } 391 } 392 } 393 if (!is_static) { 394 // instance fields must be being accessed on an initialized class 395 return resolved_field; 396 } else { 397 // If the class is initialized we're done. 398 if (LIKELY(fields_class->IsInitialized())) { 399 return resolved_field; 400 } else { 401 StackHandleScope<1> hs(self); 402 Handle<mirror::Class> h_class(hs.NewHandle(fields_class)); 403 if (LIKELY(class_linker->EnsureInitialized(self, h_class, true, true))) { 404 // Otherwise let's ensure the class is initialized before resolving the field. 405 return resolved_field; 406 } 407 DCHECK(self->IsExceptionPending()); // Throw exception and unwind 408 return nullptr; // Failure. 409 } 410 } 411 } 412 413 // Explicit template declarations of FindFieldFromCode for all field access types. 414 #define EXPLICIT_FIND_FIELD_FROM_CODE_TEMPLATE_DECL(_type, _access_check) \ 415 template SHARED_REQUIRES(Locks::mutator_lock_) ALWAYS_INLINE \ 416 ArtField* FindFieldFromCode<_type, _access_check>(uint32_t field_idx, \ 417 ArtMethod* referrer, \ 418 Thread* self, size_t expected_size) \ 419 420 #define EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(_type) \ 421 EXPLICIT_FIND_FIELD_FROM_CODE_TEMPLATE_DECL(_type, false); \ 422 EXPLICIT_FIND_FIELD_FROM_CODE_TEMPLATE_DECL(_type, true) 423 424 EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(InstanceObjectRead); 425 EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(InstanceObjectWrite); 426 EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(InstancePrimitiveRead); 427 EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(InstancePrimitiveWrite); 428 EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(StaticObjectRead); 429 EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(StaticObjectWrite); 430 EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(StaticPrimitiveRead); 431 EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(StaticPrimitiveWrite); 432 433 #undef EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL 434 #undef EXPLICIT_FIND_FIELD_FROM_CODE_TEMPLATE_DECL 435 436 template<InvokeType type, bool access_check> 437 inline ArtMethod* FindMethodFromCode(uint32_t method_idx, mirror::Object** this_object, 438 ArtMethod* referrer, Thread* self) { 439 ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); 440 ArtMethod* resolved_method = class_linker->GetResolvedMethod(method_idx, referrer); 441 if (resolved_method == nullptr) { 442 StackHandleScope<1> hs(self); 443 mirror::Object* null_this = nullptr; 444 HandleWrapper<mirror::Object> h_this( 445 hs.NewHandleWrapper(type == kStatic ? &null_this : this_object)); 446 constexpr ClassLinker::ResolveMode resolve_mode = 447 access_check ? ClassLinker::kForceICCECheck 448 : ClassLinker::kNoICCECheckForCache; 449 resolved_method = class_linker->ResolveMethod<resolve_mode>(self, method_idx, referrer, type); 450 } 451 if (UNLIKELY(resolved_method == nullptr)) { 452 DCHECK(self->IsExceptionPending()); // Throw exception and unwind. 453 return nullptr; // Failure. 454 } else if (UNLIKELY(*this_object == nullptr && type != kStatic)) { 455 if (UNLIKELY(resolved_method->GetDeclaringClass()->IsStringClass() && 456 resolved_method->IsConstructor())) { 457 // Hack for String init: 458 // 459 // We assume that the input of String.<init> in verified code is always 460 // an unitialized reference. If it is a null constant, it must have been 461 // optimized out by the compiler. Do not throw NullPointerException. 462 } else { 463 // Maintain interpreter-like semantics where NullPointerException is thrown 464 // after potential NoSuchMethodError from class linker. 465 ThrowNullPointerExceptionForMethodAccess(method_idx, type); 466 return nullptr; // Failure. 467 } 468 } else if (access_check) { 469 mirror::Class* methods_class = resolved_method->GetDeclaringClass(); 470 bool can_access_resolved_method = 471 referrer->GetDeclaringClass()->CheckResolvedMethodAccess<type>(methods_class, 472 resolved_method, 473 method_idx); 474 if (UNLIKELY(!can_access_resolved_method)) { 475 DCHECK(self->IsExceptionPending()); // Throw exception and unwind. 476 return nullptr; // Failure. 477 } 478 // Incompatible class change should have been handled in resolve method. 479 if (UNLIKELY(resolved_method->CheckIncompatibleClassChange(type))) { 480 ThrowIncompatibleClassChangeError(type, resolved_method->GetInvokeType(), resolved_method, 481 referrer); 482 return nullptr; // Failure. 483 } 484 } 485 switch (type) { 486 case kStatic: 487 case kDirect: 488 return resolved_method; 489 case kVirtual: { 490 mirror::Class* klass = (*this_object)->GetClass(); 491 uint16_t vtable_index = resolved_method->GetMethodIndex(); 492 if (access_check && 493 (!klass->HasVTable() || 494 vtable_index >= static_cast<uint32_t>(klass->GetVTableLength()))) { 495 // Behavior to agree with that of the verifier. 496 ThrowNoSuchMethodError(type, resolved_method->GetDeclaringClass(), 497 resolved_method->GetName(), resolved_method->GetSignature()); 498 return nullptr; // Failure. 499 } 500 DCHECK(klass->HasVTable()) << PrettyClass(klass); 501 return klass->GetVTableEntry(vtable_index, class_linker->GetImagePointerSize()); 502 } 503 case kSuper: { 504 // TODO This lookup is quite slow. 505 // NB This is actually quite tricky to do any other way. We cannot use GetDeclaringClass since 506 // that will actually not be what we want in some cases where there are miranda methods or 507 // defaults. What we actually need is a GetContainingClass that says which classes virtuals 508 // this method is coming from. 509 mirror::Class* referring_class = referrer->GetDeclaringClass(); 510 uint16_t method_type_idx = referring_class->GetDexFile().GetMethodId(method_idx).class_idx_; 511 mirror::Class* method_reference_class = class_linker->ResolveType(method_type_idx, referrer); 512 if (UNLIKELY(method_reference_class == nullptr)) { 513 // Bad type idx. 514 CHECK(self->IsExceptionPending()); 515 return nullptr; 516 } else if (!method_reference_class->IsInterface()) { 517 // It is not an interface. If the referring class is in the class hierarchy of the 518 // referenced class in the bytecode, we use its super class. Otherwise, we throw 519 // a NoSuchMethodError. 520 mirror::Class* super_class = nullptr; 521 if (method_reference_class->IsAssignableFrom(referring_class)) { 522 super_class = referring_class->GetSuperClass(); 523 } 524 uint16_t vtable_index = resolved_method->GetMethodIndex(); 525 if (access_check) { 526 // Check existence of super class. 527 if (super_class == nullptr || 528 !super_class->HasVTable() || 529 vtable_index >= static_cast<uint32_t>(super_class->GetVTableLength())) { 530 // Behavior to agree with that of the verifier. 531 ThrowNoSuchMethodError(type, resolved_method->GetDeclaringClass(), 532 resolved_method->GetName(), resolved_method->GetSignature()); 533 return nullptr; // Failure. 534 } 535 } 536 DCHECK(super_class != nullptr); 537 DCHECK(super_class->HasVTable()); 538 return super_class->GetVTableEntry(vtable_index, class_linker->GetImagePointerSize()); 539 } else { 540 // It is an interface. 541 if (access_check) { 542 if (!method_reference_class->IsAssignableFrom((*this_object)->GetClass())) { 543 ThrowIncompatibleClassChangeErrorClassForInterfaceSuper(resolved_method, 544 method_reference_class, 545 *this_object, 546 referrer); 547 return nullptr; // Failure. 548 } 549 } 550 // TODO We can do better than this for a (compiled) fastpath. 551 ArtMethod* result = method_reference_class->FindVirtualMethodForInterfaceSuper( 552 resolved_method, class_linker->GetImagePointerSize()); 553 // Throw an NSME if nullptr; 554 if (result == nullptr) { 555 ThrowNoSuchMethodError(type, resolved_method->GetDeclaringClass(), 556 resolved_method->GetName(), resolved_method->GetSignature()); 557 } 558 return result; 559 } 560 } 561 case kInterface: { 562 uint32_t imt_index = resolved_method->GetDexMethodIndex() % ImTable::kSize; 563 size_t pointer_size = class_linker->GetImagePointerSize(); 564 ArtMethod* imt_method = (*this_object)->GetClass()->GetImt(pointer_size)-> 565 Get(imt_index, pointer_size); 566 if (!imt_method->IsRuntimeMethod()) { 567 if (kIsDebugBuild) { 568 mirror::Class* klass = (*this_object)->GetClass(); 569 ArtMethod* method = klass->FindVirtualMethodForInterface( 570 resolved_method, class_linker->GetImagePointerSize()); 571 CHECK_EQ(imt_method, method) << PrettyMethod(resolved_method) << " / " << 572 PrettyMethod(imt_method) << " / " << PrettyMethod(method) << " / " << 573 PrettyClass(klass); 574 } 575 return imt_method; 576 } else { 577 ArtMethod* interface_method = (*this_object)->GetClass()->FindVirtualMethodForInterface( 578 resolved_method, class_linker->GetImagePointerSize()); 579 if (UNLIKELY(interface_method == nullptr)) { 580 ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(resolved_method, 581 *this_object, referrer); 582 return nullptr; // Failure. 583 } 584 return interface_method; 585 } 586 } 587 default: 588 LOG(FATAL) << "Unknown invoke type " << type; 589 return nullptr; // Failure. 590 } 591 } 592 593 // Explicit template declarations of FindMethodFromCode for all invoke types. 594 #define EXPLICIT_FIND_METHOD_FROM_CODE_TEMPLATE_DECL(_type, _access_check) \ 595 template SHARED_REQUIRES(Locks::mutator_lock_) ALWAYS_INLINE \ 596 ArtMethod* FindMethodFromCode<_type, _access_check>(uint32_t method_idx, \ 597 mirror::Object** this_object, \ 598 ArtMethod* referrer, \ 599 Thread* self) 600 #define EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(_type) \ 601 EXPLICIT_FIND_METHOD_FROM_CODE_TEMPLATE_DECL(_type, false); \ 602 EXPLICIT_FIND_METHOD_FROM_CODE_TEMPLATE_DECL(_type, true) 603 604 EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(kStatic); 605 EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(kDirect); 606 EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(kVirtual); 607 EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(kSuper); 608 EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(kInterface); 609 610 #undef EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL 611 #undef EXPLICIT_FIND_METHOD_FROM_CODE_TEMPLATE_DECL 612 613 // Fast path field resolution that can't initialize classes or throw exceptions. 614 inline ArtField* FindFieldFast(uint32_t field_idx, ArtMethod* referrer, FindFieldType type, 615 size_t expected_size) { 616 ArtField* resolved_field = 617 referrer->GetDeclaringClass()->GetDexCache()->GetResolvedField(field_idx, sizeof(void*)); 618 if (UNLIKELY(resolved_field == nullptr)) { 619 return nullptr; 620 } 621 // Check for incompatible class change. 622 bool is_primitive; 623 bool is_set; 624 bool is_static; 625 switch (type) { 626 case InstanceObjectRead: is_primitive = false; is_set = false; is_static = false; break; 627 case InstanceObjectWrite: is_primitive = false; is_set = true; is_static = false; break; 628 case InstancePrimitiveRead: is_primitive = true; is_set = false; is_static = false; break; 629 case InstancePrimitiveWrite: is_primitive = true; is_set = true; is_static = false; break; 630 case StaticObjectRead: is_primitive = false; is_set = false; is_static = true; break; 631 case StaticObjectWrite: is_primitive = false; is_set = true; is_static = true; break; 632 case StaticPrimitiveRead: is_primitive = true; is_set = false; is_static = true; break; 633 case StaticPrimitiveWrite: is_primitive = true; is_set = true; is_static = true; break; 634 default: 635 LOG(FATAL) << "UNREACHABLE"; 636 UNREACHABLE(); 637 } 638 if (UNLIKELY(resolved_field->IsStatic() != is_static)) { 639 // Incompatible class change. 640 return nullptr; 641 } 642 mirror::Class* fields_class = resolved_field->GetDeclaringClass(); 643 if (is_static) { 644 // Check class is initialized else fail so that we can contend to initialize the class with 645 // other threads that may be racing to do this. 646 if (UNLIKELY(!fields_class->IsInitialized())) { 647 return nullptr; 648 } 649 } 650 mirror::Class* referring_class = referrer->GetDeclaringClass(); 651 if (UNLIKELY(!referring_class->CanAccess(fields_class) || 652 !referring_class->CanAccessMember(fields_class, resolved_field->GetAccessFlags()) || 653 (is_set && resolved_field->IsFinal() && (fields_class != referring_class)))) { 654 // Illegal access. 655 return nullptr; 656 } 657 if (UNLIKELY(resolved_field->IsPrimitiveType() != is_primitive || 658 resolved_field->FieldSize() != expected_size)) { 659 return nullptr; 660 } 661 return resolved_field; 662 } 663 664 // Fast path method resolution that can't throw exceptions. 665 inline ArtMethod* FindMethodFast(uint32_t method_idx, mirror::Object* this_object, 666 ArtMethod* referrer, bool access_check, InvokeType type) { 667 if (UNLIKELY(this_object == nullptr && type != kStatic)) { 668 return nullptr; 669 } 670 mirror::Class* referring_class = referrer->GetDeclaringClass(); 671 ArtMethod* resolved_method = 672 referring_class->GetDexCache()->GetResolvedMethod(method_idx, sizeof(void*)); 673 if (UNLIKELY(resolved_method == nullptr)) { 674 return nullptr; 675 } 676 if (access_check) { 677 // Check for incompatible class change errors and access. 678 bool icce = resolved_method->CheckIncompatibleClassChange(type); 679 if (UNLIKELY(icce)) { 680 return nullptr; 681 } 682 mirror::Class* methods_class = resolved_method->GetDeclaringClass(); 683 if (UNLIKELY(!referring_class->CanAccess(methods_class) || 684 !referring_class->CanAccessMember(methods_class, 685 resolved_method->GetAccessFlags()))) { 686 // Potential illegal access, may need to refine the method's class. 687 return nullptr; 688 } 689 } 690 if (type == kInterface) { // Most common form of slow path dispatch. 691 return this_object->GetClass()->FindVirtualMethodForInterface(resolved_method, sizeof(void*)); 692 } else if (type == kStatic || type == kDirect) { 693 return resolved_method; 694 } else if (type == kSuper) { 695 // TODO This lookup is rather slow. 696 uint16_t method_type_idx = referring_class->GetDexFile().GetMethodId(method_idx).class_idx_; 697 mirror::Class* method_reference_class = 698 referring_class->GetDexCache()->GetResolvedType(method_type_idx); 699 if (method_reference_class == nullptr) { 700 // Need to do full type resolution... 701 return nullptr; 702 } else if (!method_reference_class->IsInterface()) { 703 // It is not an interface. If the referring class is in the class hierarchy of the 704 // referenced class in the bytecode, we use its super class. Otherwise, we cannot 705 // resolve the method. 706 if (!method_reference_class->IsAssignableFrom(referring_class)) { 707 return nullptr; 708 } 709 mirror::Class* super_class = referring_class->GetSuperClass(); 710 if (resolved_method->GetMethodIndex() >= super_class->GetVTableLength()) { 711 // The super class does not have the method. 712 return nullptr; 713 } 714 return super_class->GetVTableEntry(resolved_method->GetMethodIndex(), sizeof(void*)); 715 } else { 716 return method_reference_class->FindVirtualMethodForInterfaceSuper( 717 resolved_method, sizeof(void*)); 718 } 719 } else { 720 DCHECK(type == kVirtual); 721 return this_object->GetClass()->GetVTableEntry( 722 resolved_method->GetMethodIndex(), sizeof(void*)); 723 } 724 } 725 726 inline mirror::Class* ResolveVerifyAndClinit(uint32_t type_idx, ArtMethod* referrer, Thread* self, 727 bool can_run_clinit, bool verify_access) { 728 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 729 mirror::Class* klass = class_linker->ResolveType(type_idx, referrer); 730 if (UNLIKELY(klass == nullptr)) { 731 CHECK(self->IsExceptionPending()); 732 return nullptr; // Failure - Indicate to caller to deliver exception 733 } 734 // Perform access check if necessary. 735 mirror::Class* referring_class = referrer->GetDeclaringClass(); 736 if (verify_access && UNLIKELY(!referring_class->CanAccess(klass))) { 737 ThrowIllegalAccessErrorClass(referring_class, klass); 738 return nullptr; // Failure - Indicate to caller to deliver exception 739 } 740 // If we're just implementing const-class, we shouldn't call <clinit>. 741 if (!can_run_clinit) { 742 return klass; 743 } 744 // If we are the <clinit> of this class, just return our storage. 745 // 746 // Do not set the DexCache InitializedStaticStorage, since that implies <clinit> has finished 747 // running. 748 if (klass == referring_class && referrer->IsConstructor() && referrer->IsStatic()) { 749 return klass; 750 } 751 StackHandleScope<1> hs(self); 752 Handle<mirror::Class> h_class(hs.NewHandle(klass)); 753 if (!class_linker->EnsureInitialized(self, h_class, true, true)) { 754 CHECK(self->IsExceptionPending()); 755 return nullptr; // Failure - Indicate to caller to deliver exception 756 } 757 return h_class.Get(); 758 } 759 760 inline mirror::String* ResolveStringFromCode(ArtMethod* referrer, uint32_t string_idx) { 761 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 762 return class_linker->ResolveString(string_idx, referrer); 763 } 764 765 inline void UnlockJniSynchronizedMethod(jobject locked, Thread* self) { 766 // Save any pending exception over monitor exit call. 767 mirror::Throwable* saved_exception = nullptr; 768 if (UNLIKELY(self->IsExceptionPending())) { 769 saved_exception = self->GetException(); 770 self->ClearException(); 771 } 772 // Decode locked object and unlock, before popping local references. 773 self->DecodeJObject(locked)->MonitorExit(self); 774 if (UNLIKELY(self->IsExceptionPending())) { 775 LOG(FATAL) << "Synchronized JNI code returning with an exception:\n" 776 << saved_exception->Dump() 777 << "\nEncountered second exception during implicit MonitorExit:\n" 778 << self->GetException()->Dump(); 779 } 780 // Restore pending exception. 781 if (saved_exception != nullptr) { 782 self->SetException(saved_exception); 783 } 784 } 785 786 template <typename INT_TYPE, typename FLOAT_TYPE> 787 inline INT_TYPE art_float_to_integral(FLOAT_TYPE f) { 788 const INT_TYPE kMaxInt = static_cast<INT_TYPE>(std::numeric_limits<INT_TYPE>::max()); 789 const INT_TYPE kMinInt = static_cast<INT_TYPE>(std::numeric_limits<INT_TYPE>::min()); 790 const FLOAT_TYPE kMaxIntAsFloat = static_cast<FLOAT_TYPE>(kMaxInt); 791 const FLOAT_TYPE kMinIntAsFloat = static_cast<FLOAT_TYPE>(kMinInt); 792 if (LIKELY(f > kMinIntAsFloat)) { 793 if (LIKELY(f < kMaxIntAsFloat)) { 794 return static_cast<INT_TYPE>(f); 795 } else { 796 return kMaxInt; 797 } 798 } else { 799 return (f != f) ? 0 : kMinInt; // f != f implies NaN 800 } 801 } 802 803 } // namespace art 804 805 #endif // ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_INL_H_ 806