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
AddDependency(ArtMethod * method,ArtMethod * dependent_method,OatQuickMethodHeader * dependent_header)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
GetDependents(ArtMethod * method)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
RemoveAllDependenciesFor(ArtMethod * method)54 void ClassHierarchyAnalysis::RemoveAllDependenciesFor(ArtMethod* method) {
55 cha_dependency_map_.erase(method);
56 }
57
RemoveDependentsWithMethodHeaders(const std::unordered_set<OatQuickMethodHeader * > & method_headers)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
ResetSingleImplementationInHierarchy(ObjPtr<mirror::Class> klass,const LinearAlloc * alloc,const PointerSize pointer_size) const82 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:
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(ObjPtr<mirror::Class> verify_class,uint16_t verify_index,ArtMethod * excluded_method)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
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 /* 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
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 !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
InitSingleImplementationFlag(Handle<mirror::Class> klass,ArtMethod * method,PointerSize pointer_size)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
UpdateAfterLoadingOf(Handle<mirror::Class> klass)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
InvalidateSingleImplementationMethods(std::unordered_set<ArtMethod * > & invalidated_single_impl_methods)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
RemoveDependenciesForLinearAlloc(const LinearAlloc * linear_alloc)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