• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
AddDependency(ArtMethod * method,ArtMethod * dependent_method,OatQuickMethodHeader * dependent_header)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 
GetDependents(ArtMethod * method)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 
RemoveAllDependenciesFor(ArtMethod * method)53 void ClassHierarchyAnalysis::RemoveAllDependenciesFor(ArtMethod* method) {
54   cha_dependency_map_.erase(method);
55 }
56 
RemoveDependentsWithMethodHeaders(const std::unordered_set<OatQuickMethodHeader * > & method_headers)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 
ResetSingleImplementationInHierarchy(ObjPtr<mirror::Class> klass,const LinearAlloc * alloc,const PointerSize pointer_size) const81 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:
CHAStackVisitor(Thread * thread_in,Context * context,const std::unordered_set<OatQuickMethodHeader * > & method_headers)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 
VisitFrame()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:
SetShouldDeoptimizeFlag()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:
CHACheckpoint(const std::unordered_set<OatQuickMethodHeader * > & method_headers)251   explicit CHACheckpoint(const std::unordered_set<OatQuickMethodHeader*>& method_headers)
252       : barrier_(0),
253         method_headers_(method_headers) {}
254 
Run(Thread * thread)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 
WaitForThreadsToRunThroughCheckpoint(size_t threads_running_checkpoint)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 
VerifyNonSingleImplementation(mirror::Class * verify_class,uint16_t verify_index,ArtMethod * excluded_method)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 
CheckVirtualMethodSingleImplementationInfo(Handle<mirror::Class> klass,ArtMethod * virtual_method,ArtMethod * method_in_super,std::unordered_set<ArtMethod * > & invalidated_single_impl_methods,PointerSize pointer_size)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 
CheckInterfaceMethodSingleImplementationInfo(Handle<mirror::Class> klass,ArtMethod * interface_method,ArtMethod * implementation_method,std::unordered_set<ArtMethod * > & invalidated_single_impl_methods,PointerSize pointer_size)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 
InitSingleImplementationFlag(Handle<mirror::Class> klass,ArtMethod * method,PointerSize pointer_size)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 
UpdateAfterLoadingOf(Handle<mirror::Class> klass)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 
InvalidateSingleImplementationMethods(std::unordered_set<ArtMethod * > & invalidated_single_impl_methods)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 
RemoveDependenciesForLinearAlloc(const LinearAlloc * linear_alloc)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