1 /* 2 * Copyright (C) 2016 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 #include "cha.h" 18 19 #include "art_method-inl.h" 20 #include "base/logging.h" // For VLOG 21 #include "base/mutex.h" 22 #include "jit/jit.h" 23 #include "jit/jit_code_cache.h" 24 #include "linear_alloc.h" 25 #include "mirror/class_loader.h" 26 #include "runtime.h" 27 #include "scoped_thread_state_change-inl.h" 28 #include "stack.h" 29 #include "thread.h" 30 #include "thread_list.h" 31 #include "thread_pool.h" 32 33 namespace art { 34 35 void ClassHierarchyAnalysis::AddDependency(ArtMethod* method, 36 ArtMethod* dependent_method, 37 OatQuickMethodHeader* dependent_header) { 38 const auto it = cha_dependency_map_.insert( 39 decltype(cha_dependency_map_)::value_type(method, ListOfDependentPairs())).first; 40 it->second.push_back({dependent_method, dependent_header}); 41 } 42 43 static const ClassHierarchyAnalysis::ListOfDependentPairs s_empty_vector; 44 45 const ClassHierarchyAnalysis::ListOfDependentPairs& ClassHierarchyAnalysis::GetDependents( 46 ArtMethod* method) { 47 auto it = cha_dependency_map_.find(method); 48 if (it != cha_dependency_map_.end()) { 49 return it->second; 50 } 51 return s_empty_vector; 52 } 53 54 void ClassHierarchyAnalysis::RemoveAllDependenciesFor(ArtMethod* method) { 55 cha_dependency_map_.erase(method); 56 } 57 58 void ClassHierarchyAnalysis::RemoveDependentsWithMethodHeaders( 59 const std::unordered_set<OatQuickMethodHeader*>& method_headers) { 60 // Iterate through all entries in the dependency map and remove any entry that 61 // contains one of those in method_headers. 62 for (auto map_it = cha_dependency_map_.begin(); map_it != cha_dependency_map_.end(); ) { 63 ListOfDependentPairs& dependents = map_it->second; 64 dependents.erase( 65 std::remove_if( 66 dependents.begin(), 67 dependents.end(), 68 [&method_headers](MethodAndMethodHeaderPair& dependent) { 69 return method_headers.find(dependent.second) != method_headers.end(); 70 }), 71 dependents.end()); 72 73 // Remove the map entry if there are no more dependents. 74 if (dependents.empty()) { 75 map_it = cha_dependency_map_.erase(map_it); 76 } else { 77 map_it++; 78 } 79 } 80 } 81 82 void ClassHierarchyAnalysis::ResetSingleImplementationInHierarchy(ObjPtr<mirror::Class> klass, 83 const LinearAlloc* alloc, 84 const PointerSize pointer_size) 85 const { 86 // Presumably called from some sort of class visitor, no null pointers expected. 87 DCHECK(klass != nullptr); 88 DCHECK(alloc != nullptr); 89 90 // Skip interfaces since they cannot provide SingleImplementations to work with. 91 if (klass->IsInterface()) { 92 return; 93 } 94 95 // This method is called while visiting classes in the class table of a class loader. 96 // That means, some 'klass'es can belong to other classloaders. Argument 'alloc' 97 // allows to explicitly indicate a classloader, which is going to be deleted. 98 // Filter out classes, that do not belong to it. 99 if (!alloc->ContainsUnsafe(klass->GetMethodsPtr())) { 100 return; 101 } 102 103 // CHA analysis is only applied to resolved classes. 104 if (!klass->IsResolved()) { 105 return; 106 } 107 108 ObjPtr<mirror::Class> super = klass->GetSuperClass<kDefaultVerifyFlags, kWithoutReadBarrier>(); 109 110 // Skip Object class and primitive classes. 111 if (super == nullptr) { 112 return; 113 } 114 115 // The class is going to be deleted. Iterate over the virtual methods of its superclasses to see 116 // if they have SingleImplementations methods defined by 'klass'. 117 // Skip all virtual methods that do not override methods from super class since they cannot be 118 // SingleImplementations for anything. 119 int32_t vtbl_size = super->GetVTableLength<kDefaultVerifyFlags>(); 120 ObjPtr<mirror::ClassLoader> loader = 121 klass->GetClassLoader<kDefaultVerifyFlags, kWithoutReadBarrier>(); 122 for (int vtbl_index = 0; vtbl_index < vtbl_size; ++vtbl_index) { 123 ArtMethod* method = 124 klass->GetVTableEntry<kDefaultVerifyFlags, kWithoutReadBarrier>(vtbl_index, pointer_size); 125 if (!alloc->ContainsUnsafe(method)) { 126 continue; 127 } 128 129 // Find all occurrences of virtual methods in parents' SingleImplementations fields 130 // and reset them. 131 // No need to reset SingleImplementations for the method itself (it will be cleared anyways), 132 // so start with a superclass and move up looking into a corresponding vtbl slot. 133 for (ObjPtr<mirror::Class> super_it = super; 134 super_it != nullptr && 135 super_it->GetVTableLength<kDefaultVerifyFlags>() > vtbl_index; 136 super_it = super_it->GetSuperClass<kDefaultVerifyFlags, kWithoutReadBarrier>()) { 137 // Skip superclasses that are also going to be unloaded. 138 ObjPtr<mirror::ClassLoader> super_loader = super_it-> 139 GetClassLoader<kDefaultVerifyFlags, kWithoutReadBarrier>(); 140 if (super_loader == loader) { 141 continue; 142 } 143 144 ArtMethod* super_method = super_it-> 145 GetVTableEntry<kDefaultVerifyFlags, kWithoutReadBarrier>(vtbl_index, pointer_size); 146 if (super_method->IsAbstract() && 147 super_method->HasSingleImplementation<kWithoutReadBarrier>() && 148 super_method->GetSingleImplementation(pointer_size) == method) { 149 // Do like there was no single implementation defined previously 150 // for this method of the superclass. 151 super_method->SetSingleImplementation(nullptr, pointer_size); 152 } else { 153 // No related SingleImplementations could possibly be found any further. 154 DCHECK(!super_method->HasSingleImplementation<kWithoutReadBarrier>()); 155 break; 156 } 157 } 158 } 159 160 // Check all possible interface methods too. 161 ObjPtr<mirror::IfTable> iftable = klass->GetIfTable<kDefaultVerifyFlags, kWithoutReadBarrier>(); 162 const size_t ifcount = klass->GetIfTableCount<kDefaultVerifyFlags>(); 163 for (size_t i = 0; i < ifcount; ++i) { 164 ObjPtr<mirror::Class> interface = 165 iftable->GetInterface<kDefaultVerifyFlags, kWithoutReadBarrier>(i); 166 for (size_t j = 0, 167 count = iftable->GetMethodArrayCount<kDefaultVerifyFlags, kWithoutReadBarrier>(i); 168 j < count; 169 ++j) { 170 ArtMethod* method = interface->GetVirtualMethod(j, pointer_size); 171 if (method->HasSingleImplementation<kWithoutReadBarrier>() && 172 alloc->ContainsUnsafe(method->GetSingleImplementation(pointer_size)) && 173 !method->IsDefault()) { 174 // Do like there was no single implementation defined previously for this method. 175 method->SetSingleImplementation(nullptr, pointer_size); 176 } 177 } 178 } 179 } 180 181 // This stack visitor walks the stack and for compiled code with certain method 182 // headers, sets the should_deoptimize flag on stack to 1. 183 // TODO: also set the register value to 1 when should_deoptimize is allocated in 184 // a register. 185 class CHAStackVisitor final : public StackVisitor { 186 public: 187 CHAStackVisitor(Thread* thread_in, 188 Context* context, 189 const std::unordered_set<OatQuickMethodHeader*>& method_headers) 190 : StackVisitor(thread_in, context, StackVisitor::StackWalkKind::kSkipInlinedFrames), 191 method_headers_(method_headers) { 192 } 193 194 bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) { 195 ArtMethod* method = GetMethod(); 196 // Avoid types of methods that do not have an oat quick method header. 197 if (method == nullptr || 198 method->IsRuntimeMethod() || 199 method->IsNative() || 200 method->IsProxyMethod()) { 201 return true; 202 } 203 if (GetCurrentQuickFrame() == nullptr) { 204 // Not compiled code. 205 return true; 206 } 207 // Method may have multiple versions of compiled code. Check 208 // the method header to see if it has should_deoptimize flag. 209 const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader(); 210 DCHECK(method_header != nullptr); 211 if (!method_header->HasShouldDeoptimizeFlag()) { 212 // This compiled version doesn't have should_deoptimize flag. Skip. 213 return true; 214 } 215 auto it = std::find(method_headers_.begin(), method_headers_.end(), method_header); 216 if (it == method_headers_.end()) { 217 // Not in the list of method headers that should be deoptimized. 218 return true; 219 } 220 221 // The compiled code on stack is not valid anymore. Need to deoptimize. 222 SetShouldDeoptimizeFlag(); 223 224 return true; 225 } 226 227 private: 228 void SetShouldDeoptimizeFlag() REQUIRES_SHARED(Locks::mutator_lock_) { 229 QuickMethodFrameInfo frame_info = GetCurrentQuickFrameInfo(); 230 size_t frame_size = frame_info.FrameSizeInBytes(); 231 uint8_t* sp = reinterpret_cast<uint8_t*>(GetCurrentQuickFrame()); 232 size_t core_spill_size = POPCOUNT(frame_info.CoreSpillMask()) * 233 GetBytesPerGprSpillLocation(kRuntimeISA); 234 size_t fpu_spill_size = POPCOUNT(frame_info.FpSpillMask()) * 235 GetBytesPerFprSpillLocation(kRuntimeISA); 236 size_t offset = frame_size - core_spill_size - fpu_spill_size - kShouldDeoptimizeFlagSize; 237 uint8_t* should_deoptimize_addr = sp + offset; 238 // Set deoptimization flag to 1. 239 DCHECK(*should_deoptimize_addr == 0 || *should_deoptimize_addr == 1); 240 *should_deoptimize_addr = 1; 241 } 242 243 // Set of method headers for compiled code that should be deoptimized. 244 const std::unordered_set<OatQuickMethodHeader*>& method_headers_; 245 246 DISALLOW_COPY_AND_ASSIGN(CHAStackVisitor); 247 }; 248 249 class CHACheckpoint final : public Closure { 250 public: 251 explicit CHACheckpoint(const std::unordered_set<OatQuickMethodHeader*>& method_headers) 252 : barrier_(0), 253 method_headers_(method_headers) {} 254 255 void Run(Thread* thread) override { 256 // Note thread and self may not be equal if thread was already suspended at 257 // the point of the request. 258 Thread* self = Thread::Current(); 259 ScopedObjectAccess soa(self); 260 CHAStackVisitor visitor(thread, nullptr, method_headers_); 261 visitor.WalkStack(); 262 barrier_.Pass(self); 263 } 264 265 void WaitForThreadsToRunThroughCheckpoint(size_t threads_running_checkpoint) { 266 Thread* self = Thread::Current(); 267 ScopedThreadStateChange tsc(self, kWaitingForCheckPointsToRun); 268 barrier_.Increment(self, threads_running_checkpoint); 269 } 270 271 private: 272 // The barrier to be passed through and for the requestor to wait upon. 273 Barrier barrier_; 274 // List of method headers for invalidated compiled code. 275 const std::unordered_set<OatQuickMethodHeader*>& method_headers_; 276 277 DISALLOW_COPY_AND_ASSIGN(CHACheckpoint); 278 }; 279 280 281 static void VerifyNonSingleImplementation(ObjPtr<mirror::Class> verify_class, 282 uint16_t verify_index, 283 ArtMethod* excluded_method) 284 REQUIRES_SHARED(Locks::mutator_lock_) { 285 if (!kIsDebugBuild) { 286 return; 287 } 288 289 // Grab cha_lock_ to make sure all single-implementation updates are seen. 290 MutexLock cha_mu(Thread::Current(), *Locks::cha_lock_); 291 292 PointerSize image_pointer_size = 293 Runtime::Current()->GetClassLinker()->GetImagePointerSize(); 294 295 ObjPtr<mirror::Class> input_verify_class = verify_class; 296 297 while (verify_class != nullptr) { 298 if (verify_index >= verify_class->GetVTableLength()) { 299 return; 300 } 301 ArtMethod* verify_method = verify_class->GetVTableEntry(verify_index, image_pointer_size); 302 if (verify_method != excluded_method) { 303 auto construct_parent_chain = [](ObjPtr<mirror::Class> failed, ObjPtr<mirror::Class> in) 304 REQUIRES_SHARED(Locks::mutator_lock_) { 305 std::string tmp = in->PrettyClass(); 306 while (in != failed) { 307 in = in->GetSuperClass(); 308 tmp = tmp + "->" + in->PrettyClass(); 309 } 310 return tmp; 311 }; 312 DCHECK(!verify_method->HasSingleImplementation()) 313 << "class: " << verify_class->PrettyClass() 314 << " verify_method: " << verify_method->PrettyMethod(true) 315 << " (" << construct_parent_chain(verify_class, input_verify_class) << ")" 316 << " excluded_method: " << ArtMethod::PrettyMethod(excluded_method); 317 if (verify_method->IsAbstract()) { 318 DCHECK(verify_method->GetSingleImplementation(image_pointer_size) == nullptr); 319 } 320 } 321 verify_class = verify_class->GetSuperClass(); 322 } 323 } 324 325 void ClassHierarchyAnalysis::CheckVirtualMethodSingleImplementationInfo( 326 Handle<mirror::Class> klass, 327 ArtMethod* virtual_method, 328 ArtMethod* method_in_super, 329 std::unordered_set<ArtMethod*>& invalidated_single_impl_methods, 330 PointerSize pointer_size) { 331 // TODO: if klass is not instantiable, virtual_method isn't invocable yet so 332 // even if it overrides, it doesn't invalidate single-implementation 333 // assumption. 334 335 DCHECK((virtual_method != method_in_super) || virtual_method->IsAbstract()); 336 DCHECK(method_in_super->GetDeclaringClass()->IsResolved()) << "class isn't resolved"; 337 // If virtual_method doesn't come from a default interface method, it should 338 // be supplied by klass. 339 DCHECK(virtual_method == method_in_super || 340 virtual_method->IsCopied() || 341 virtual_method->GetDeclaringClass() == klass.Get()); 342 343 // To make updating single-implementation flags simple, we always maintain the following 344 // invariant: 345 // Say all virtual methods in the same vtable slot, starting from the bottom child class 346 // to super classes, is a sequence of unique methods m3, m2, m1, ... (after removing duplicate 347 // methods for inherited methods). 348 // For example for the following class hierarchy, 349 // class A { void m() { ... } } 350 // class B extends A { void m() { ... } } 351 // class C extends B {} 352 // class D extends C { void m() { ... } } 353 // the sequence is D.m(), B.m(), A.m(). 354 // The single-implementation status for that sequence of methods begin with one or two true's, 355 // then become all falses. The only case where two true's are possible is for one abstract 356 // method m and one non-abstract method mImpl that overrides method m. 357 // With the invariant, when linking in a new class, we only need to at most update one or 358 // two methods in the sequence for their single-implementation status, in order to maintain 359 // the invariant. 360 361 if (!method_in_super->HasSingleImplementation()) { 362 // method_in_super already has multiple implementations. All methods in the 363 // same vtable slots in its super classes should have 364 // non-single-implementation already. 365 VerifyNonSingleImplementation(klass->GetSuperClass()->GetSuperClass(), 366 method_in_super->GetMethodIndex(), 367 /* excluded_method= */ nullptr); 368 return; 369 } 370 371 uint16_t method_index = method_in_super->GetMethodIndex(); 372 if (method_in_super->IsAbstract()) { 373 // An abstract method should have made all methods in the same vtable 374 // slot above it in the class hierarchy having non-single-implementation. 375 VerifyNonSingleImplementation(klass->GetSuperClass()->GetSuperClass(), 376 method_index, 377 method_in_super); 378 379 if (virtual_method->IsAbstract()) { 380 // SUPER: abstract, VIRTUAL: abstract. 381 if (method_in_super == virtual_method) { 382 DCHECK(klass->IsInstantiable()); 383 // An instantiable subclass hasn't provided a concrete implementation of 384 // the abstract method. Invoking method_in_super may throw AbstractMethodError. 385 // This is an uncommon case, so we simply treat method_in_super as not 386 // having single-implementation. 387 invalidated_single_impl_methods.insert(method_in_super); 388 return; 389 } else { 390 // One abstract method overrides another abstract method. This is an uncommon 391 // case. We simply treat method_in_super as not having single-implementation. 392 invalidated_single_impl_methods.insert(method_in_super); 393 return; 394 } 395 } else { 396 // SUPER: abstract, VIRTUAL: non-abstract. 397 // A non-abstract method overrides an abstract method. 398 if (method_in_super->GetSingleImplementation(pointer_size) == nullptr) { 399 // Abstract method_in_super has no implementation yet. 400 // We need to grab cha_lock_ since there may be multiple class linking 401 // going on that can check/modify the single-implementation flag/method 402 // of method_in_super. 403 MutexLock cha_mu(Thread::Current(), *Locks::cha_lock_); 404 if (!method_in_super->HasSingleImplementation()) { 405 return; 406 } 407 if (method_in_super->GetSingleImplementation(pointer_size) == nullptr) { 408 // virtual_method becomes the first implementation for method_in_super. 409 method_in_super->SetSingleImplementation(virtual_method, pointer_size); 410 // Keep method_in_super's single-implementation status. 411 return; 412 } 413 // Fall through to invalidate method_in_super's single-implementation status. 414 } 415 // Abstract method_in_super already got one implementation. 416 // Invalidate method_in_super's single-implementation status. 417 invalidated_single_impl_methods.insert(method_in_super); 418 return; 419 } 420 } else { 421 if (virtual_method->IsAbstract()) { 422 // SUPER: non-abstract, VIRTUAL: abstract. 423 // An abstract method overrides a non-abstract method. This is an uncommon 424 // case, we simply treat both methods as not having single-implementation. 425 invalidated_single_impl_methods.insert(virtual_method); 426 // Fall-through to handle invalidating method_in_super of its 427 // single-implementation status. 428 } 429 430 // SUPER: non-abstract, VIRTUAL: non-abstract/abstract(fall-through from previous if). 431 // Invalidate method_in_super's single-implementation status. 432 invalidated_single_impl_methods.insert(method_in_super); 433 434 // method_in_super might be the single-implementation of another abstract method, 435 // which should be also invalidated of its single-implementation status. 436 ObjPtr<mirror::Class> super_super = klass->GetSuperClass()->GetSuperClass(); 437 while (super_super != nullptr && 438 method_index < super_super->GetVTableLength()) { 439 ArtMethod* method_in_super_super = super_super->GetVTableEntry(method_index, pointer_size); 440 if (method_in_super_super != method_in_super) { 441 if (method_in_super_super->IsAbstract()) { 442 if (method_in_super_super->HasSingleImplementation()) { 443 // Invalidate method_in_super's single-implementation status. 444 invalidated_single_impl_methods.insert(method_in_super_super); 445 // No need to further traverse up the class hierarchy since if there 446 // are cases that one abstract method overrides another method, we 447 // should have made that method having non-single-implementation already. 448 } else { 449 // method_in_super_super is already non-single-implementation. 450 // No need to further traverse up the class hierarchy. 451 } 452 } else { 453 DCHECK(!method_in_super_super->HasSingleImplementation()); 454 // No need to further traverse up the class hierarchy since two non-abstract 455 // methods (method_in_super and method_in_super_super) should have set all 456 // other methods (abstract or not) in the vtable slot to be non-single-implementation. 457 } 458 459 VerifyNonSingleImplementation(super_super->GetSuperClass(), 460 method_index, 461 method_in_super_super); 462 // No need to go any further. 463 return; 464 } else { 465 super_super = super_super->GetSuperClass(); 466 } 467 } 468 } 469 } 470 471 void ClassHierarchyAnalysis::CheckInterfaceMethodSingleImplementationInfo( 472 Handle<mirror::Class> klass, 473 ArtMethod* interface_method, 474 ArtMethod* implementation_method, 475 std::unordered_set<ArtMethod*>& invalidated_single_impl_methods, 476 PointerSize pointer_size) { 477 DCHECK(klass->IsInstantiable()); 478 DCHECK(interface_method->IsAbstract() || interface_method->IsDefault()); 479 480 if (!interface_method->HasSingleImplementation()) { 481 return; 482 } 483 484 if (implementation_method->IsAbstract()) { 485 // An instantiable class doesn't supply an implementation for 486 // interface_method. Invoking the interface method on the class will throw 487 // AbstractMethodError. This is an uncommon case, so we simply treat 488 // interface_method as not having single-implementation. 489 invalidated_single_impl_methods.insert(interface_method); 490 return; 491 } 492 493 // We need to grab cha_lock_ since there may be multiple class linking going 494 // on that can check/modify the single-implementation flag/method of 495 // interface_method. 496 MutexLock cha_mu(Thread::Current(), *Locks::cha_lock_); 497 // Do this check again after we grab cha_lock_. 498 if (!interface_method->HasSingleImplementation()) { 499 return; 500 } 501 502 ArtMethod* single_impl = interface_method->GetSingleImplementation(pointer_size); 503 if (single_impl == nullptr) { 504 // implementation_method becomes the first implementation for 505 // interface_method. 506 interface_method->SetSingleImplementation(implementation_method, pointer_size); 507 // Keep interface_method's single-implementation status. 508 return; 509 } 510 DCHECK(!single_impl->IsAbstract()); 511 if ((single_impl->GetDeclaringClass() == implementation_method->GetDeclaringClass()) && 512 !implementation_method->IsDefaultConflicting()) { 513 // Same implementation. Since implementation_method may be a copy of a default 514 // method, we need to check the declaring class for equality. 515 return; 516 } 517 // Another implementation for interface_method. 518 invalidated_single_impl_methods.insert(interface_method); 519 } 520 521 void ClassHierarchyAnalysis::InitSingleImplementationFlag(Handle<mirror::Class> klass, 522 ArtMethod* method, 523 PointerSize pointer_size) { 524 DCHECK(method->IsCopied() || method->GetDeclaringClass() == klass.Get()); 525 if (klass->IsFinal() || method->IsFinal()) { 526 // Final classes or methods do not need CHA for devirtualization. 527 // This frees up modifier bits for intrinsics which currently are only 528 // used for static methods or methods of final classes. 529 return; 530 } 531 if (method->IsAbstract()) { 532 // single-implementation of abstract method shares the same field 533 // that's used for JNI function of native method. It's fine since a method 534 // cannot be both abstract and native. 535 DCHECK(!method->IsNative()) << "Abstract method cannot be native"; 536 537 if (method->GetDeclaringClass()->IsInstantiable()) { 538 // Rare case, but we do accept it (such as 800-smali/smali/b_26143249.smali). 539 // Do not attempt to devirtualize it. 540 method->SetHasSingleImplementation(false); 541 DCHECK(method->GetSingleImplementation(pointer_size) == nullptr); 542 } else { 543 // Abstract method starts with single-implementation flag set and null 544 // implementation method. 545 method->SetHasSingleImplementation(true); 546 DCHECK(method->GetSingleImplementation(pointer_size) == nullptr); 547 } 548 // Default conflicting methods cannot be treated with single implementations, 549 // as we need to call them (and not inline them) in case of ICCE. 550 // See class_linker.cc:EnsureThrowsInvocationError. 551 } else if (!method->IsDefaultConflicting()) { 552 method->SetHasSingleImplementation(true); 553 // Single implementation of non-abstract method is itself. 554 DCHECK_EQ(method->GetSingleImplementation(pointer_size), method); 555 } 556 } 557 558 void ClassHierarchyAnalysis::UpdateAfterLoadingOf(Handle<mirror::Class> klass) { 559 PointerSize image_pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); 560 if (klass->IsInterface()) { 561 for (ArtMethod& method : klass->GetDeclaredVirtualMethods(image_pointer_size)) { 562 DCHECK(method.IsAbstract() || method.IsDefault()); 563 InitSingleImplementationFlag(klass, &method, image_pointer_size); 564 } 565 return; 566 } 567 568 ObjPtr<mirror::Class> super_class = klass->GetSuperClass(); 569 if (super_class == nullptr) { 570 return; 571 } 572 573 // Keeps track of all methods whose single-implementation assumption 574 // is invalidated by linking `klass`. 575 std::unordered_set<ArtMethod*> invalidated_single_impl_methods; 576 577 // Do an entry-by-entry comparison of vtable contents with super's vtable. 578 for (int32_t i = 0; i < super_class->GetVTableLength(); ++i) { 579 ArtMethod* method = klass->GetVTableEntry(i, image_pointer_size); 580 ArtMethod* method_in_super = super_class->GetVTableEntry(i, image_pointer_size); 581 if (method == method_in_super) { 582 // vtable slot entry is inherited from super class. 583 if (method->IsAbstract() && klass->IsInstantiable()) { 584 // An instantiable class that inherits an abstract method is treated as 585 // supplying an implementation that throws AbstractMethodError. 586 CheckVirtualMethodSingleImplementationInfo(klass, 587 method, 588 method_in_super, 589 invalidated_single_impl_methods, 590 image_pointer_size); 591 } 592 continue; 593 } 594 InitSingleImplementationFlag(klass, method, image_pointer_size); 595 CheckVirtualMethodSingleImplementationInfo(klass, 596 method, 597 method_in_super, 598 invalidated_single_impl_methods, 599 image_pointer_size); 600 } 601 // For new virtual methods that don't override. 602 for (int32_t i = super_class->GetVTableLength(); i < klass->GetVTableLength(); ++i) { 603 ArtMethod* method = klass->GetVTableEntry(i, image_pointer_size); 604 InitSingleImplementationFlag(klass, method, image_pointer_size); 605 } 606 607 if (klass->IsInstantiable()) { 608 ObjPtr<mirror::IfTable> iftable = klass->GetIfTable(); 609 const size_t ifcount = klass->GetIfTableCount(); 610 for (size_t i = 0; i < ifcount; ++i) { 611 ObjPtr<mirror::Class> interface = iftable->GetInterface(i); 612 for (size_t j = 0, count = iftable->GetMethodArrayCount(i); j < count; ++j) { 613 ArtMethod* interface_method = interface->GetVirtualMethod(j, image_pointer_size); 614 ObjPtr<mirror::PointerArray> method_array = iftable->GetMethodArray(i); 615 ArtMethod* implementation_method = 616 method_array->GetElementPtrSize<ArtMethod*>(j, image_pointer_size); 617 DCHECK(implementation_method != nullptr) << klass->PrettyClass(); 618 CheckInterfaceMethodSingleImplementationInfo(klass, 619 interface_method, 620 implementation_method, 621 invalidated_single_impl_methods, 622 image_pointer_size); 623 } 624 } 625 } 626 627 InvalidateSingleImplementationMethods(invalidated_single_impl_methods); 628 } 629 630 void ClassHierarchyAnalysis::InvalidateSingleImplementationMethods( 631 std::unordered_set<ArtMethod*>& invalidated_single_impl_methods) { 632 if (!invalidated_single_impl_methods.empty()) { 633 Runtime* const runtime = Runtime::Current(); 634 Thread *self = Thread::Current(); 635 // Method headers for compiled code to be invalidated. 636 std::unordered_set<OatQuickMethodHeader*> dependent_method_headers; 637 PointerSize image_pointer_size = 638 Runtime::Current()->GetClassLinker()->GetImagePointerSize(); 639 640 { 641 // We do this under cha_lock_. Committing code also grabs this lock to 642 // make sure the code is only committed when all single-implementation 643 // assumptions are still true. 644 std::vector<std::pair<ArtMethod*, OatQuickMethodHeader*>> headers; 645 { 646 MutexLock cha_mu(self, *Locks::cha_lock_); 647 // Invalidate compiled methods that assume some virtual calls have only 648 // single implementations. 649 for (ArtMethod* invalidated : invalidated_single_impl_methods) { 650 if (!invalidated->HasSingleImplementation()) { 651 // It might have been invalidated already when other class linking is 652 // going on. 653 continue; 654 } 655 invalidated->SetHasSingleImplementation(false); 656 if (invalidated->IsAbstract()) { 657 // Clear the single implementation method. 658 invalidated->SetSingleImplementation(nullptr, image_pointer_size); 659 } 660 661 if (runtime->IsAotCompiler()) { 662 // No need to invalidate any compiled code as the AotCompiler doesn't 663 // run any code. 664 continue; 665 } 666 667 // Invalidate all dependents. 668 for (const auto& dependent : GetDependents(invalidated)) { 669 ArtMethod* method = dependent.first;; 670 OatQuickMethodHeader* method_header = dependent.second; 671 VLOG(class_linker) << "CHA invalidated compiled code for " << method->PrettyMethod(); 672 DCHECK(runtime->UseJitCompilation()); 673 // We need to call JitCodeCache::InvalidateCompiledCodeFor but we cannot do it here 674 // since it would run into problems with lock-ordering. We don't want to re-order the 675 // locks since that would make code-commit racy. 676 headers.push_back({method, method_header}); 677 dependent_method_headers.insert(method_header); 678 } 679 RemoveAllDependenciesFor(invalidated); 680 } 681 } 682 // Since we are still loading the class that invalidated the code it's fine we have this after 683 // getting rid of the dependency. Any calls would need to be with the old version (since the 684 // new one isn't loaded yet) which still works fine. We will deoptimize just after this to 685 // ensure everything gets the new state. 686 jit::Jit* jit = Runtime::Current()->GetJit(); 687 if (jit != nullptr) { 688 jit::JitCodeCache* code_cache = jit->GetCodeCache(); 689 for (const auto& pair : headers) { 690 code_cache->InvalidateCompiledCodeFor(pair.first, pair.second); 691 } 692 } 693 } 694 695 if (dependent_method_headers.empty()) { 696 return; 697 } 698 // Deoptimze compiled code on stack that should have been invalidated. 699 CHACheckpoint checkpoint(dependent_method_headers); 700 size_t threads_running_checkpoint = runtime->GetThreadList()->RunCheckpoint(&checkpoint); 701 if (threads_running_checkpoint != 0) { 702 checkpoint.WaitForThreadsToRunThroughCheckpoint(threads_running_checkpoint); 703 } 704 } 705 } 706 707 void ClassHierarchyAnalysis::RemoveDependenciesForLinearAlloc(const LinearAlloc* linear_alloc) { 708 MutexLock mu(Thread::Current(), *Locks::cha_lock_); 709 for (auto it = cha_dependency_map_.begin(); it != cha_dependency_map_.end(); ) { 710 // Use unsafe to avoid locking since the allocator is going to be deleted. 711 if (linear_alloc->ContainsUnsafe(it->first)) { 712 // About to delete the ArtMethod, erase the entry from the map. 713 it = cha_dependency_map_.erase(it); 714 } else { 715 ++it; 716 } 717 } 718 } 719 720 } // namespace art 721