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 "jit/jit.h" 22 #include "jit/jit_code_cache.h" 23 #include "linear_alloc.h" 24 #include "mirror/class_loader.h" 25 #include "runtime.h" 26 #include "scoped_thread_state_change-inl.h" 27 #include "stack.h" 28 #include "thread.h" 29 #include "thread_list.h" 30 #include "thread_pool.h" 31 32 namespace art { 33 34 void ClassHierarchyAnalysis::AddDependency(ArtMethod* method, 35 ArtMethod* dependent_method, 36 OatQuickMethodHeader* dependent_header) { 37 const auto it = cha_dependency_map_.insert( 38 decltype(cha_dependency_map_)::value_type(method, ListOfDependentPairs())).first; 39 it->second.push_back({dependent_method, dependent_header}); 40 } 41 42 static const ClassHierarchyAnalysis::ListOfDependentPairs s_empty_vector; 43 44 const ClassHierarchyAnalysis::ListOfDependentPairs& ClassHierarchyAnalysis::GetDependents( 45 ArtMethod* method) { 46 auto it = cha_dependency_map_.find(method); 47 if (it != cha_dependency_map_.end()) { 48 return it->second; 49 } 50 return s_empty_vector; 51 } 52 53 void ClassHierarchyAnalysis::RemoveAllDependenciesFor(ArtMethod* method) { 54 cha_dependency_map_.erase(method); 55 } 56 57 void ClassHierarchyAnalysis::RemoveDependentsWithMethodHeaders( 58 const std::unordered_set<OatQuickMethodHeader*>& method_headers) { 59 // Iterate through all entries in the dependency map and remove any entry that 60 // contains one of those in method_headers. 61 for (auto map_it = cha_dependency_map_.begin(); map_it != cha_dependency_map_.end(); ) { 62 ListOfDependentPairs& dependents = map_it->second; 63 dependents.erase( 64 std::remove_if( 65 dependents.begin(), 66 dependents.end(), 67 [&method_headers](MethodAndMethodHeaderPair& dependent) { 68 return method_headers.find(dependent.second) != method_headers.end(); 69 }), 70 dependents.end()); 71 72 // Remove the map entry if there are no more dependents. 73 if (dependents.empty()) { 74 map_it = cha_dependency_map_.erase(map_it); 75 } else { 76 map_it++; 77 } 78 } 79 } 80 81 void ClassHierarchyAnalysis::ResetSingleImplementationInHierarchy(ObjPtr<mirror::Class> klass, 82 const LinearAlloc* alloc, 83 const PointerSize pointer_size) 84 const { 85 // Presumably called from some sort of class visitor, no null pointers expected. 86 DCHECK(klass != nullptr); 87 DCHECK(alloc != nullptr); 88 89 // Skip interfaces since they cannot provide SingleImplementations to work with. 90 if (klass->IsInterface()) { 91 return; 92 } 93 94 // This method is called while visiting classes in the class table of a class loader. 95 // That means, some 'klass'es can belong to other classloaders. Argument 'alloc' 96 // allows to explicitly indicate a classloader, which is going to be deleted. 97 // Filter out classes, that do not belong to it. 98 if (!alloc->ContainsUnsafe(klass->GetMethodsPtr())) { 99 return; 100 } 101 102 // CHA analysis is only applied to resolved classes. 103 if (!klass->IsResolved()) { 104 return; 105 } 106 107 ObjPtr<mirror::Class> super = klass->GetSuperClass<kDefaultVerifyFlags, kWithoutReadBarrier>(); 108 109 // Skip Object class and primitive classes. 110 if (super == nullptr) { 111 return; 112 } 113 114 // The class is going to be deleted. Iterate over the virtual methods of its superclasses to see 115 // if they have SingleImplementations methods defined by 'klass'. 116 // Skip all virtual methods that do not override methods from super class since they cannot be 117 // SingleImplementations for anything. 118 int32_t vtbl_size = super->GetVTableLength<kDefaultVerifyFlags, kWithoutReadBarrier>(); 119 ObjPtr<mirror::ClassLoader> loader = 120 klass->GetClassLoader<kDefaultVerifyFlags, kWithoutReadBarrier>(); 121 for (int vtbl_index = 0; vtbl_index < vtbl_size; ++vtbl_index) { 122 ArtMethod* method = 123 klass->GetVTableEntry<kDefaultVerifyFlags, kWithoutReadBarrier>(vtbl_index, pointer_size); 124 if (!alloc->ContainsUnsafe(method)) { 125 continue; 126 } 127 128 // Find all occurrences of virtual methods in parents' SingleImplementations fields 129 // and reset them. 130 // No need to reset SingleImplementations for the method itself (it will be cleared anyways), 131 // so start with a superclass and move up looking into a corresponding vtbl slot. 132 for (ObjPtr<mirror::Class> super_it = super; 133 super_it != nullptr && 134 super_it->GetVTableLength<kDefaultVerifyFlags, kWithoutReadBarrier>() > vtbl_index; 135 super_it = super_it->GetSuperClass<kDefaultVerifyFlags, kWithoutReadBarrier>()) { 136 // Skip superclasses that are also going to be unloaded. 137 ObjPtr<mirror::ClassLoader> super_loader = super_it-> 138 GetClassLoader<kDefaultVerifyFlags, kWithoutReadBarrier>(); 139 if (super_loader == loader) { 140 continue; 141 } 142 143 ArtMethod* super_method = super_it-> 144 GetVTableEntry<kDefaultVerifyFlags, kWithoutReadBarrier>(vtbl_index, pointer_size); 145 if (super_method->IsAbstract<kWithoutReadBarrier>() && 146 super_method->HasSingleImplementation<kWithoutReadBarrier>() && 147 super_method->GetSingleImplementation<kWithoutReadBarrier>(pointer_size) == method) { 148 // Do like there was no single implementation defined previously 149 // for this method of the superclass. 150 super_method->SetSingleImplementation<kWithoutReadBarrier>(nullptr, pointer_size); 151 } else { 152 // No related SingleImplementations could possibly be found any further. 153 DCHECK(!super_method->HasSingleImplementation<kWithoutReadBarrier>()); 154 break; 155 } 156 } 157 } 158 159 // Check all possible interface methods too. 160 ObjPtr<mirror::IfTable> iftable = klass->GetIfTable<kDefaultVerifyFlags, kWithoutReadBarrier>(); 161 const size_t ifcount = klass->GetIfTableCount<kDefaultVerifyFlags, kWithoutReadBarrier>(); 162 for (size_t i = 0; i < ifcount; ++i) { 163 ObjPtr<mirror::Class> interface = 164 iftable->GetInterface<kDefaultVerifyFlags, kWithoutReadBarrier>(i); 165 for (size_t j = 0, 166 count = iftable->GetMethodArrayCount<kDefaultVerifyFlags, kWithoutReadBarrier>(i); 167 j < count; 168 ++j) { 169 ArtMethod* method = interface->GetVirtualMethod(j, pointer_size); 170 if (method->HasSingleImplementation<kWithoutReadBarrier>() && 171 alloc->ContainsUnsafe( 172 method->GetSingleImplementation<kWithoutReadBarrier>(pointer_size)) && 173 !method->IsDefault<kWithoutReadBarrier>()) { 174 // Do like there was no single implementation defined previously for this method. 175 method->SetSingleImplementation<kWithoutReadBarrier>(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(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 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 = [](mirror::Class* failed, 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 nullptr /* excluded_method */); 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 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 // Same implementation. Since implementation_method may be a copy of a default 513 // method, we need to check the declaring class for equality. 514 return; 515 } 516 // Another implementation for interface_method. 517 invalidated_single_impl_methods.insert(interface_method); 518 } 519 520 void ClassHierarchyAnalysis::InitSingleImplementationFlag(Handle<mirror::Class> klass, 521 ArtMethod* method, 522 PointerSize pointer_size) { 523 DCHECK(method->IsCopied() || method->GetDeclaringClass() == klass.Get()); 524 if (klass->IsFinal() || method->IsFinal()) { 525 // Final classes or methods do not need CHA for devirtualization. 526 // This frees up modifier bits for intrinsics which currently are only 527 // used for static methods or methods of final classes. 528 return; 529 } 530 if (method->IsAbstract()) { 531 // single-implementation of abstract method shares the same field 532 // that's used for JNI function of native method. It's fine since a method 533 // cannot be both abstract and native. 534 DCHECK(!method->IsNative()) << "Abstract method cannot be native"; 535 536 if (method->GetDeclaringClass()->IsInstantiable()) { 537 // Rare case, but we do accept it (such as 800-smali/smali/b_26143249.smali). 538 // Do not attempt to devirtualize it. 539 method->SetHasSingleImplementation(false); 540 DCHECK(method->GetSingleImplementation(pointer_size) == nullptr); 541 } else { 542 // Abstract method starts with single-implementation flag set and null 543 // implementation method. 544 method->SetHasSingleImplementation(true); 545 DCHECK(method->GetSingleImplementation(pointer_size) == nullptr); 546 } 547 } else { 548 method->SetHasSingleImplementation(true); 549 // Single implementation of non-abstract method is itself. 550 DCHECK_EQ(method->GetSingleImplementation(pointer_size), method); 551 } 552 } 553 554 void ClassHierarchyAnalysis::UpdateAfterLoadingOf(Handle<mirror::Class> klass) { 555 PointerSize image_pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); 556 if (klass->IsInterface()) { 557 for (ArtMethod& method : klass->GetDeclaredVirtualMethods(image_pointer_size)) { 558 DCHECK(method.IsAbstract() || method.IsDefault()); 559 InitSingleImplementationFlag(klass, &method, image_pointer_size); 560 } 561 return; 562 } 563 564 mirror::Class* super_class = klass->GetSuperClass(); 565 if (super_class == nullptr) { 566 return; 567 } 568 569 // Keeps track of all methods whose single-implementation assumption 570 // is invalidated by linking `klass`. 571 std::unordered_set<ArtMethod*> invalidated_single_impl_methods; 572 573 // Do an entry-by-entry comparison of vtable contents with super's vtable. 574 for (int32_t i = 0; i < super_class->GetVTableLength(); ++i) { 575 ArtMethod* method = klass->GetVTableEntry(i, image_pointer_size); 576 ArtMethod* method_in_super = super_class->GetVTableEntry(i, image_pointer_size); 577 if (method == method_in_super) { 578 // vtable slot entry is inherited from super class. 579 if (method->IsAbstract() && klass->IsInstantiable()) { 580 // An instantiable class that inherits an abstract method is treated as 581 // supplying an implementation that throws AbstractMethodError. 582 CheckVirtualMethodSingleImplementationInfo(klass, 583 method, 584 method_in_super, 585 invalidated_single_impl_methods, 586 image_pointer_size); 587 } 588 continue; 589 } 590 InitSingleImplementationFlag(klass, method, image_pointer_size); 591 CheckVirtualMethodSingleImplementationInfo(klass, 592 method, 593 method_in_super, 594 invalidated_single_impl_methods, 595 image_pointer_size); 596 } 597 // For new virtual methods that don't override. 598 for (int32_t i = super_class->GetVTableLength(); i < klass->GetVTableLength(); ++i) { 599 ArtMethod* method = klass->GetVTableEntry(i, image_pointer_size); 600 InitSingleImplementationFlag(klass, method, image_pointer_size); 601 } 602 603 if (klass->IsInstantiable()) { 604 auto* iftable = klass->GetIfTable(); 605 const size_t ifcount = klass->GetIfTableCount(); 606 for (size_t i = 0; i < ifcount; ++i) { 607 mirror::Class* interface = iftable->GetInterface(i); 608 for (size_t j = 0, count = iftable->GetMethodArrayCount(i); j < count; ++j) { 609 ArtMethod* interface_method = interface->GetVirtualMethod(j, image_pointer_size); 610 mirror::PointerArray* method_array = iftable->GetMethodArray(i); 611 ArtMethod* implementation_method = 612 method_array->GetElementPtrSize<ArtMethod*>(j, image_pointer_size); 613 DCHECK(implementation_method != nullptr) << klass->PrettyClass(); 614 CheckInterfaceMethodSingleImplementationInfo(klass, 615 interface_method, 616 implementation_method, 617 invalidated_single_impl_methods, 618 image_pointer_size); 619 } 620 } 621 } 622 623 InvalidateSingleImplementationMethods(invalidated_single_impl_methods); 624 } 625 626 void ClassHierarchyAnalysis::InvalidateSingleImplementationMethods( 627 std::unordered_set<ArtMethod*>& invalidated_single_impl_methods) { 628 if (!invalidated_single_impl_methods.empty()) { 629 Runtime* const runtime = Runtime::Current(); 630 Thread *self = Thread::Current(); 631 // Method headers for compiled code to be invalidated. 632 std::unordered_set<OatQuickMethodHeader*> dependent_method_headers; 633 PointerSize image_pointer_size = 634 Runtime::Current()->GetClassLinker()->GetImagePointerSize(); 635 636 { 637 // We do this under cha_lock_. Committing code also grabs this lock to 638 // make sure the code is only committed when all single-implementation 639 // assumptions are still true. 640 MutexLock cha_mu(self, *Locks::cha_lock_); 641 // Invalidate compiled methods that assume some virtual calls have only 642 // single implementations. 643 for (ArtMethod* invalidated : invalidated_single_impl_methods) { 644 if (!invalidated->HasSingleImplementation()) { 645 // It might have been invalidated already when other class linking is 646 // going on. 647 continue; 648 } 649 invalidated->SetHasSingleImplementation(false); 650 if (invalidated->IsAbstract()) { 651 // Clear the single implementation method. 652 invalidated->SetSingleImplementation(nullptr, image_pointer_size); 653 } 654 655 if (runtime->IsAotCompiler()) { 656 // No need to invalidate any compiled code as the AotCompiler doesn't 657 // run any code. 658 continue; 659 } 660 661 // Invalidate all dependents. 662 for (const auto& dependent : GetDependents(invalidated)) { 663 ArtMethod* method = dependent.first;; 664 OatQuickMethodHeader* method_header = dependent.second; 665 VLOG(class_linker) << "CHA invalidated compiled code for " << method->PrettyMethod(); 666 DCHECK(runtime->UseJitCompilation()); 667 runtime->GetJit()->GetCodeCache()->InvalidateCompiledCodeFor( 668 method, method_header); 669 dependent_method_headers.insert(method_header); 670 } 671 RemoveAllDependenciesFor(invalidated); 672 } 673 } 674 675 if (dependent_method_headers.empty()) { 676 return; 677 } 678 // Deoptimze compiled code on stack that should have been invalidated. 679 CHACheckpoint checkpoint(dependent_method_headers); 680 size_t threads_running_checkpoint = runtime->GetThreadList()->RunCheckpoint(&checkpoint); 681 if (threads_running_checkpoint != 0) { 682 checkpoint.WaitForThreadsToRunThroughCheckpoint(threads_running_checkpoint); 683 } 684 } 685 } 686 687 void ClassHierarchyAnalysis::RemoveDependenciesForLinearAlloc(const LinearAlloc* linear_alloc) { 688 MutexLock mu(Thread::Current(), *Locks::cha_lock_); 689 for (auto it = cha_dependency_map_.begin(); it != cha_dependency_map_.end(); ) { 690 // Use unsafe to avoid locking since the allocator is going to be deleted. 691 if (linear_alloc->ContainsUnsafe(it->first)) { 692 // About to delete the ArtMethod, erase the entry from the map. 693 it = cha_dependency_map_.erase(it); 694 } else { 695 ++it; 696 } 697 } 698 } 699 700 } // namespace art 701