Home | History | Annotate | Download | only in runtime
      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