blob: de4aebed36719013540c2a648a180ab52d0e142f [file] [log] [blame]
Mingyao Yang063fc772016-08-02 11:02:54 -07001/*
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
Andreas Gampe90b936d2017-01-31 08:58:55 -080019#include "art_method-inl.h"
Andreas Gampe170331f2017-12-07 18:41:03 -080020#include "base/logging.h" // For VLOG
Mingyao Yang063fc772016-08-02 11:02:54 -070021#include "jit/jit.h"
22#include "jit/jit_code_cache.h"
Mathieu Chartiercf79cf52017-07-21 11:17:57 -070023#include "linear_alloc.h"
Alexey Grebenkinbe4c2bd2018-02-01 19:09:59 +030024#include "mirror/class_loader.h"
Mingyao Yang063fc772016-08-02 11:02:54 -070025#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
32namespace art {
33
34void ClassHierarchyAnalysis::AddDependency(ArtMethod* method,
35 ArtMethod* dependent_method,
36 OatQuickMethodHeader* dependent_header) {
Mingyao Yangcc104502017-05-24 17:13:03 -070037 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});
Mingyao Yang063fc772016-08-02 11:02:54 -070040}
41
Mingyao Yangcc104502017-05-24 17:13:03 -070042static const ClassHierarchyAnalysis::ListOfDependentPairs s_empty_vector;
43
44const ClassHierarchyAnalysis::ListOfDependentPairs& ClassHierarchyAnalysis::GetDependents(
45 ArtMethod* method) {
Mingyao Yang063fc772016-08-02 11:02:54 -070046 auto it = cha_dependency_map_.find(method);
47 if (it != cha_dependency_map_.end()) {
Mingyao Yang063fc772016-08-02 11:02:54 -070048 return it->second;
49 }
Mingyao Yangcc104502017-05-24 17:13:03 -070050 return s_empty_vector;
Mingyao Yang063fc772016-08-02 11:02:54 -070051}
52
Mingyao Yangcc104502017-05-24 17:13:03 -070053void ClassHierarchyAnalysis::RemoveAllDependenciesFor(ArtMethod* method) {
54 cha_dependency_map_.erase(method);
Mingyao Yang063fc772016-08-02 11:02:54 -070055}
56
57void 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(); ) {
Mingyao Yangcc104502017-05-24 17:13:03 -070062 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
Mingyao Yang063fc772016-08-02 11:02:54 -070072 // Remove the map entry if there are no more dependents.
Mingyao Yangcc104502017-05-24 17:13:03 -070073 if (dependents.empty()) {
Mingyao Yang063fc772016-08-02 11:02:54 -070074 map_it = cha_dependency_map_.erase(map_it);
Mingyao Yang063fc772016-08-02 11:02:54 -070075 } else {
76 map_it++;
77 }
78 }
79}
80
Alexey Grebenkinbe4c2bd2018-02-01 19:09:59 +030081void 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);
Vladimir Markoc945e0d2018-07-18 17:26:45 +0100145 if (super_method->IsAbstract() &&
Alexey Grebenkinbe4c2bd2018-02-01 19:09:59 +0300146 super_method->HasSingleImplementation<kWithoutReadBarrier>() &&
Vladimir Markoc945e0d2018-07-18 17:26:45 +0100147 super_method->GetSingleImplementation(pointer_size) == method) {
Alexey Grebenkinbe4c2bd2018-02-01 19:09:59 +0300148 // Do like there was no single implementation defined previously
149 // for this method of the superclass.
Vladimir Markoc945e0d2018-07-18 17:26:45 +0100150 super_method->SetSingleImplementation(nullptr, pointer_size);
Alexey Grebenkinbe4c2bd2018-02-01 19:09:59 +0300151 } 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>() &&
Vladimir Markoc945e0d2018-07-18 17:26:45 +0100171 alloc->ContainsUnsafe(method->GetSingleImplementation(pointer_size)) &&
172 !method->IsDefault()) {
Alexey Grebenkinbe4c2bd2018-02-01 19:09:59 +0300173 // Do like there was no single implementation defined previously for this method.
Vladimir Markoc945e0d2018-07-18 17:26:45 +0100174 method->SetSingleImplementation(nullptr, pointer_size);
Alexey Grebenkinbe4c2bd2018-02-01 19:09:59 +0300175 }
176 }
177 }
178}
179
Mingyao Yang063fc772016-08-02 11:02:54 -0700180// This stack visitor walks the stack and for compiled code with certain method
181// headers, sets the should_deoptimize flag on stack to 1.
182// TODO: also set the register value to 1 when should_deoptimize is allocated in
183// a register.
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100184class CHAStackVisitor final : public StackVisitor {
Mingyao Yang063fc772016-08-02 11:02:54 -0700185 public:
186 CHAStackVisitor(Thread* thread_in,
187 Context* context,
188 const std::unordered_set<OatQuickMethodHeader*>& method_headers)
189 : StackVisitor(thread_in, context, StackVisitor::StackWalkKind::kSkipInlinedFrames),
190 method_headers_(method_headers) {
191 }
192
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100193 bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
Mingyao Yang063fc772016-08-02 11:02:54 -0700194 ArtMethod* method = GetMethod();
Mingyao Yang7b9a83f2016-12-13 12:28:31 -0800195 // Avoid types of methods that do not have an oat quick method header.
196 if (method == nullptr ||
197 method->IsRuntimeMethod() ||
198 method->IsNative() ||
199 method->IsProxyMethod()) {
Mingyao Yang063fc772016-08-02 11:02:54 -0700200 return true;
201 }
202 if (GetCurrentQuickFrame() == nullptr) {
203 // Not compiled code.
204 return true;
205 }
206 // Method may have multiple versions of compiled code. Check
207 // the method header to see if it has should_deoptimize flag.
208 const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader();
Mingyao Yang7b9a83f2016-12-13 12:28:31 -0800209 DCHECK(method_header != nullptr);
Mingyao Yang063fc772016-08-02 11:02:54 -0700210 if (!method_header->HasShouldDeoptimizeFlag()) {
211 // This compiled version doesn't have should_deoptimize flag. Skip.
212 return true;
213 }
214 auto it = std::find(method_headers_.begin(), method_headers_.end(), method_header);
215 if (it == method_headers_.end()) {
216 // Not in the list of method headers that should be deoptimized.
217 return true;
218 }
219
220 // The compiled code on stack is not valid anymore. Need to deoptimize.
221 SetShouldDeoptimizeFlag();
222
223 return true;
224 }
225
226 private:
227 void SetShouldDeoptimizeFlag() REQUIRES_SHARED(Locks::mutator_lock_) {
228 QuickMethodFrameInfo frame_info = GetCurrentQuickFrameInfo();
229 size_t frame_size = frame_info.FrameSizeInBytes();
230 uint8_t* sp = reinterpret_cast<uint8_t*>(GetCurrentQuickFrame());
231 size_t core_spill_size = POPCOUNT(frame_info.CoreSpillMask()) *
232 GetBytesPerGprSpillLocation(kRuntimeISA);
233 size_t fpu_spill_size = POPCOUNT(frame_info.FpSpillMask()) *
234 GetBytesPerFprSpillLocation(kRuntimeISA);
235 size_t offset = frame_size - core_spill_size - fpu_spill_size - kShouldDeoptimizeFlagSize;
236 uint8_t* should_deoptimize_addr = sp + offset;
237 // Set deoptimization flag to 1.
238 DCHECK(*should_deoptimize_addr == 0 || *should_deoptimize_addr == 1);
239 *should_deoptimize_addr = 1;
240 }
241
242 // Set of method headers for compiled code that should be deoptimized.
243 const std::unordered_set<OatQuickMethodHeader*>& method_headers_;
244
245 DISALLOW_COPY_AND_ASSIGN(CHAStackVisitor);
246};
247
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100248class CHACheckpoint final : public Closure {
Mingyao Yang063fc772016-08-02 11:02:54 -0700249 public:
250 explicit CHACheckpoint(const std::unordered_set<OatQuickMethodHeader*>& method_headers)
251 : barrier_(0),
252 method_headers_(method_headers) {}
253
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100254 void Run(Thread* thread) override {
Mingyao Yang063fc772016-08-02 11:02:54 -0700255 // Note thread and self may not be equal if thread was already suspended at
256 // the point of the request.
257 Thread* self = Thread::Current();
258 ScopedObjectAccess soa(self);
259 CHAStackVisitor visitor(thread, nullptr, method_headers_);
260 visitor.WalkStack();
261 barrier_.Pass(self);
262 }
263
264 void WaitForThreadsToRunThroughCheckpoint(size_t threads_running_checkpoint) {
265 Thread* self = Thread::Current();
266 ScopedThreadStateChange tsc(self, kWaitingForCheckPointsToRun);
267 barrier_.Increment(self, threads_running_checkpoint);
268 }
269
270 private:
271 // The barrier to be passed through and for the requestor to wait upon.
272 Barrier barrier_;
273 // List of method headers for invalidated compiled code.
274 const std::unordered_set<OatQuickMethodHeader*>& method_headers_;
275
276 DISALLOW_COPY_AND_ASSIGN(CHACheckpoint);
277};
278
Andreas Gampe582d96a2017-07-24 13:51:47 -0700279
Andreas Gampe98104992018-10-16 12:49:47 -0700280static void VerifyNonSingleImplementation(ObjPtr<mirror::Class> verify_class,
Andreas Gampe582d96a2017-07-24 13:51:47 -0700281 uint16_t verify_index,
282 ArtMethod* excluded_method)
283 REQUIRES_SHARED(Locks::mutator_lock_) {
284 if (!kIsDebugBuild) {
285 return;
286 }
287
Mingyao Yang063fc772016-08-02 11:02:54 -0700288 // Grab cha_lock_ to make sure all single-implementation updates are seen.
Andreas Gampe582d96a2017-07-24 13:51:47 -0700289 MutexLock cha_mu(Thread::Current(), *Locks::cha_lock_);
290
Mingyao Yang063fc772016-08-02 11:02:54 -0700291 PointerSize image_pointer_size =
292 Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Andreas Gampe582d96a2017-07-24 13:51:47 -0700293
Andreas Gampe98104992018-10-16 12:49:47 -0700294 ObjPtr<mirror::Class> input_verify_class = verify_class;
Andreas Gampe582d96a2017-07-24 13:51:47 -0700295
Mingyao Yang063fc772016-08-02 11:02:54 -0700296 while (verify_class != nullptr) {
297 if (verify_index >= verify_class->GetVTableLength()) {
298 return;
299 }
300 ArtMethod* verify_method = verify_class->GetVTableEntry(verify_index, image_pointer_size);
Mingyao Yange8fcd012017-01-20 10:43:30 -0800301 if (verify_method != excluded_method) {
Andreas Gampe98104992018-10-16 12:49:47 -0700302 auto construct_parent_chain = [](ObjPtr<mirror::Class> failed, ObjPtr<mirror::Class> in)
Andreas Gampe582d96a2017-07-24 13:51:47 -0700303 REQUIRES_SHARED(Locks::mutator_lock_) {
304 std::string tmp = in->PrettyClass();
305 while (in != failed) {
306 in = in->GetSuperClass();
307 tmp = tmp + "->" + in->PrettyClass();
308 }
309 return tmp;
310 };
Mingyao Yange8fcd012017-01-20 10:43:30 -0800311 DCHECK(!verify_method->HasSingleImplementation())
312 << "class: " << verify_class->PrettyClass()
Mingyao Yang37c8e5c2017-02-10 11:25:05 -0800313 << " verify_method: " << verify_method->PrettyMethod(true)
Andreas Gampe582d96a2017-07-24 13:51:47 -0700314 << " (" << construct_parent_chain(verify_class, input_verify_class) << ")"
315 << " excluded_method: " << ArtMethod::PrettyMethod(excluded_method);
Mingyao Yange8fcd012017-01-20 10:43:30 -0800316 if (verify_method->IsAbstract()) {
317 DCHECK(verify_method->GetSingleImplementation(image_pointer_size) == nullptr);
318 }
319 }
Mingyao Yang063fc772016-08-02 11:02:54 -0700320 verify_class = verify_class->GetSuperClass();
321 }
322}
323
Nicolas Geoffray18ea1c92017-03-27 08:00:18 +0000324void ClassHierarchyAnalysis::CheckVirtualMethodSingleImplementationInfo(
Mingyao Yang063fc772016-08-02 11:02:54 -0700325 Handle<mirror::Class> klass,
326 ArtMethod* virtual_method,
327 ArtMethod* method_in_super,
Mingyao Yange8fcd012017-01-20 10:43:30 -0800328 std::unordered_set<ArtMethod*>& invalidated_single_impl_methods,
329 PointerSize pointer_size) {
Mingyao Yang063fc772016-08-02 11:02:54 -0700330 // TODO: if klass is not instantiable, virtual_method isn't invocable yet so
331 // even if it overrides, it doesn't invalidate single-implementation
332 // assumption.
333
Mingyao Yange8fcd012017-01-20 10:43:30 -0800334 DCHECK((virtual_method != method_in_super) || virtual_method->IsAbstract());
Mingyao Yang063fc772016-08-02 11:02:54 -0700335 DCHECK(method_in_super->GetDeclaringClass()->IsResolved()) << "class isn't resolved";
336 // If virtual_method doesn't come from a default interface method, it should
337 // be supplied by klass.
Mingyao Yange8fcd012017-01-20 10:43:30 -0800338 DCHECK(virtual_method == method_in_super ||
339 virtual_method->IsCopied() ||
Mingyao Yang063fc772016-08-02 11:02:54 -0700340 virtual_method->GetDeclaringClass() == klass.Get());
341
Mingyao Yange8fcd012017-01-20 10:43:30 -0800342 // To make updating single-implementation flags simple, we always maintain the following
343 // invariant:
344 // Say all virtual methods in the same vtable slot, starting from the bottom child class
345 // to super classes, is a sequence of unique methods m3, m2, m1, ... (after removing duplicate
346 // methods for inherited methods).
347 // For example for the following class hierarchy,
348 // class A { void m() { ... } }
349 // class B extends A { void m() { ... } }
350 // class C extends B {}
351 // class D extends C { void m() { ... } }
352 // the sequence is D.m(), B.m(), A.m().
353 // The single-implementation status for that sequence of methods begin with one or two true's,
354 // then become all falses. The only case where two true's are possible is for one abstract
355 // method m and one non-abstract method mImpl that overrides method m.
356 // With the invariant, when linking in a new class, we only need to at most update one or
357 // two methods in the sequence for their single-implementation status, in order to maintain
358 // the invariant.
359
Mingyao Yang063fc772016-08-02 11:02:54 -0700360 if (!method_in_super->HasSingleImplementation()) {
361 // method_in_super already has multiple implementations. All methods in the
362 // same vtable slots in its super classes should have
363 // non-single-implementation already.
Andreas Gampe582d96a2017-07-24 13:51:47 -0700364 VerifyNonSingleImplementation(klass->GetSuperClass()->GetSuperClass(),
365 method_in_super->GetMethodIndex(),
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700366 /* excluded_method= */ nullptr);
Mingyao Yang063fc772016-08-02 11:02:54 -0700367 return;
368 }
369
Mingyao Yange8fcd012017-01-20 10:43:30 -0800370 uint16_t method_index = method_in_super->GetMethodIndex();
371 if (method_in_super->IsAbstract()) {
Andreas Gampe582d96a2017-07-24 13:51:47 -0700372 // An abstract method should have made all methods in the same vtable
373 // slot above it in the class hierarchy having non-single-implementation.
374 VerifyNonSingleImplementation(klass->GetSuperClass()->GetSuperClass(),
375 method_index,
376 method_in_super);
Mingyao Yange8fcd012017-01-20 10:43:30 -0800377
378 if (virtual_method->IsAbstract()) {
379 // SUPER: abstract, VIRTUAL: abstract.
380 if (method_in_super == virtual_method) {
381 DCHECK(klass->IsInstantiable());
382 // An instantiable subclass hasn't provided a concrete implementation of
383 // the abstract method. Invoking method_in_super may throw AbstractMethodError.
384 // This is an uncommon case, so we simply treat method_in_super as not
385 // having single-implementation.
386 invalidated_single_impl_methods.insert(method_in_super);
387 return;
388 } else {
389 // One abstract method overrides another abstract method. This is an uncommon
390 // case. We simply treat method_in_super as not having single-implementation.
391 invalidated_single_impl_methods.insert(method_in_super);
392 return;
393 }
394 } else {
395 // SUPER: abstract, VIRTUAL: non-abstract.
396 // A non-abstract method overrides an abstract method.
397 if (method_in_super->GetSingleImplementation(pointer_size) == nullptr) {
398 // Abstract method_in_super has no implementation yet.
Nicolas Geoffray18ea1c92017-03-27 08:00:18 +0000399 // We need to grab cha_lock_ since there may be multiple class linking
400 // going on that can check/modify the single-implementation flag/method
401 // of method_in_super.
Mingyao Yange8fcd012017-01-20 10:43:30 -0800402 MutexLock cha_mu(Thread::Current(), *Locks::cha_lock_);
403 if (!method_in_super->HasSingleImplementation()) {
404 return;
405 }
406 if (method_in_super->GetSingleImplementation(pointer_size) == nullptr) {
407 // virtual_method becomes the first implementation for method_in_super.
408 method_in_super->SetSingleImplementation(virtual_method, pointer_size);
409 // Keep method_in_super's single-implementation status.
410 return;
411 }
412 // Fall through to invalidate method_in_super's single-implementation status.
413 }
414 // Abstract method_in_super already got one implementation.
415 // Invalidate method_in_super's single-implementation status.
416 invalidated_single_impl_methods.insert(method_in_super);
417 return;
418 }
419 } else {
420 if (virtual_method->IsAbstract()) {
421 // SUPER: non-abstract, VIRTUAL: abstract.
422 // An abstract method overrides a non-abstract method. This is an uncommon
423 // case, we simply treat both methods as not having single-implementation.
424 invalidated_single_impl_methods.insert(virtual_method);
425 // Fall-through to handle invalidating method_in_super of its
426 // single-implementation status.
427 }
428
429 // SUPER: non-abstract, VIRTUAL: non-abstract/abstract(fall-through from previous if).
430 // Invalidate method_in_super's single-implementation status.
431 invalidated_single_impl_methods.insert(method_in_super);
432
433 // method_in_super might be the single-implementation of another abstract method,
434 // which should be also invalidated of its single-implementation status.
Andreas Gampe98104992018-10-16 12:49:47 -0700435 ObjPtr<mirror::Class> super_super = klass->GetSuperClass()->GetSuperClass();
Mingyao Yange8fcd012017-01-20 10:43:30 -0800436 while (super_super != nullptr &&
437 method_index < super_super->GetVTableLength()) {
438 ArtMethod* method_in_super_super = super_super->GetVTableEntry(method_index, pointer_size);
439 if (method_in_super_super != method_in_super) {
440 if (method_in_super_super->IsAbstract()) {
441 if (method_in_super_super->HasSingleImplementation()) {
442 // Invalidate method_in_super's single-implementation status.
443 invalidated_single_impl_methods.insert(method_in_super_super);
444 // No need to further traverse up the class hierarchy since if there
445 // are cases that one abstract method overrides another method, we
446 // should have made that method having non-single-implementation already.
447 } else {
448 // method_in_super_super is already non-single-implementation.
449 // No need to further traverse up the class hierarchy.
450 }
451 } else {
452 DCHECK(!method_in_super_super->HasSingleImplementation());
453 // No need to further traverse up the class hierarchy since two non-abstract
454 // methods (method_in_super and method_in_super_super) should have set all
455 // other methods (abstract or not) in the vtable slot to be non-single-implementation.
456 }
457
Andreas Gampe582d96a2017-07-24 13:51:47 -0700458 VerifyNonSingleImplementation(super_super->GetSuperClass(),
459 method_index,
460 method_in_super_super);
Mingyao Yange8fcd012017-01-20 10:43:30 -0800461 // No need to go any further.
462 return;
463 } else {
464 super_super = super_super->GetSuperClass();
465 }
466 }
467 }
Mingyao Yang063fc772016-08-02 11:02:54 -0700468}
469
Nicolas Geoffray18ea1c92017-03-27 08:00:18 +0000470void ClassHierarchyAnalysis::CheckInterfaceMethodSingleImplementationInfo(
471 Handle<mirror::Class> klass,
472 ArtMethod* interface_method,
473 ArtMethod* implementation_method,
474 std::unordered_set<ArtMethod*>& invalidated_single_impl_methods,
475 PointerSize pointer_size) {
476 DCHECK(klass->IsInstantiable());
477 DCHECK(interface_method->IsAbstract() || interface_method->IsDefault());
478
479 if (!interface_method->HasSingleImplementation()) {
480 return;
481 }
482
483 if (implementation_method->IsAbstract()) {
484 // An instantiable class doesn't supply an implementation for
485 // interface_method. Invoking the interface method on the class will throw
486 // AbstractMethodError. This is an uncommon case, so we simply treat
487 // interface_method as not having single-implementation.
488 invalidated_single_impl_methods.insert(interface_method);
489 return;
490 }
491
492 // We need to grab cha_lock_ since there may be multiple class linking going
493 // on that can check/modify the single-implementation flag/method of
494 // interface_method.
495 MutexLock cha_mu(Thread::Current(), *Locks::cha_lock_);
496 // Do this check again after we grab cha_lock_.
497 if (!interface_method->HasSingleImplementation()) {
498 return;
499 }
500
501 ArtMethod* single_impl = interface_method->GetSingleImplementation(pointer_size);
502 if (single_impl == nullptr) {
503 // implementation_method becomes the first implementation for
504 // interface_method.
505 interface_method->SetSingleImplementation(implementation_method, pointer_size);
506 // Keep interface_method's single-implementation status.
507 return;
508 }
509 DCHECK(!single_impl->IsAbstract());
Nicolas Geoffray7aca9d52018-09-07 11:13:33 +0100510 if ((single_impl->GetDeclaringClass() == implementation_method->GetDeclaringClass()) &&
511 !implementation_method->IsDefaultConflicting()) {
Nicolas Geoffray18ea1c92017-03-27 08:00:18 +0000512 // 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
Mingyao Yang063fc772016-08-02 11:02:54 -0700520void ClassHierarchyAnalysis::InitSingleImplementationFlag(Handle<mirror::Class> klass,
Mingyao Yange8fcd012017-01-20 10:43:30 -0800521 ArtMethod* method,
522 PointerSize pointer_size) {
Mingyao Yang063fc772016-08-02 11:02:54 -0700523 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 }
Mingyao Yang37c8e5c2017-02-10 11:25:05 -0800530 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
Mingyao Yange8fcd012017-01-20 10:43:30 -0800536 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);
Nicolas Geoffray18ea1c92017-03-27 08:00:18 +0000540 DCHECK(method->GetSingleImplementation(pointer_size) == nullptr);
Mingyao Yange8fcd012017-01-20 10:43:30 -0800541 } 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 }
Nicolas Geoffray7aca9d52018-09-07 11:13:33 +0100547 // Default conflicting methods cannot be treated with single implementations,
548 // as we need to call them (and not inline them) in case of ICCE.
549 // See class_linker.cc:EnsureThrowsInvocationError.
550 } else if (!method->IsDefaultConflicting()) {
Mingyao Yang063fc772016-08-02 11:02:54 -0700551 method->SetHasSingleImplementation(true);
Mingyao Yange8fcd012017-01-20 10:43:30 -0800552 // Single implementation of non-abstract method is itself.
553 DCHECK_EQ(method->GetSingleImplementation(pointer_size), method);
Mingyao Yang063fc772016-08-02 11:02:54 -0700554 }
555}
556
557void ClassHierarchyAnalysis::UpdateAfterLoadingOf(Handle<mirror::Class> klass) {
Nicolas Geoffray18ea1c92017-03-27 08:00:18 +0000558 PointerSize image_pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Mingyao Yang063fc772016-08-02 11:02:54 -0700559 if (klass->IsInterface()) {
Nicolas Geoffray18ea1c92017-03-27 08:00:18 +0000560 for (ArtMethod& method : klass->GetDeclaredVirtualMethods(image_pointer_size)) {
561 DCHECK(method.IsAbstract() || method.IsDefault());
562 InitSingleImplementationFlag(klass, &method, image_pointer_size);
563 }
Mingyao Yang063fc772016-08-02 11:02:54 -0700564 return;
565 }
Nicolas Geoffray18ea1c92017-03-27 08:00:18 +0000566
Andreas Gampe98104992018-10-16 12:49:47 -0700567 ObjPtr<mirror::Class> super_class = klass->GetSuperClass();
Mingyao Yang063fc772016-08-02 11:02:54 -0700568 if (super_class == nullptr) {
569 return;
570 }
571
572 // Keeps track of all methods whose single-implementation assumption
573 // is invalidated by linking `klass`.
574 std::unordered_set<ArtMethod*> invalidated_single_impl_methods;
575
Mingyao Yang063fc772016-08-02 11:02:54 -0700576 // Do an entry-by-entry comparison of vtable contents with super's vtable.
577 for (int32_t i = 0; i < super_class->GetVTableLength(); ++i) {
578 ArtMethod* method = klass->GetVTableEntry(i, image_pointer_size);
579 ArtMethod* method_in_super = super_class->GetVTableEntry(i, image_pointer_size);
580 if (method == method_in_super) {
581 // vtable slot entry is inherited from super class.
Mingyao Yange8fcd012017-01-20 10:43:30 -0800582 if (method->IsAbstract() && klass->IsInstantiable()) {
583 // An instantiable class that inherits an abstract method is treated as
584 // supplying an implementation that throws AbstractMethodError.
Nicolas Geoffray18ea1c92017-03-27 08:00:18 +0000585 CheckVirtualMethodSingleImplementationInfo(klass,
586 method,
587 method_in_super,
588 invalidated_single_impl_methods,
589 image_pointer_size);
Mingyao Yange8fcd012017-01-20 10:43:30 -0800590 }
Mingyao Yang063fc772016-08-02 11:02:54 -0700591 continue;
592 }
Mingyao Yange8fcd012017-01-20 10:43:30 -0800593 InitSingleImplementationFlag(klass, method, image_pointer_size);
Nicolas Geoffray18ea1c92017-03-27 08:00:18 +0000594 CheckVirtualMethodSingleImplementationInfo(klass,
595 method,
596 method_in_super,
597 invalidated_single_impl_methods,
598 image_pointer_size);
Mingyao Yang063fc772016-08-02 11:02:54 -0700599 }
Mingyao Yang063fc772016-08-02 11:02:54 -0700600 // For new virtual methods that don't override.
601 for (int32_t i = super_class->GetVTableLength(); i < klass->GetVTableLength(); ++i) {
602 ArtMethod* method = klass->GetVTableEntry(i, image_pointer_size);
Mingyao Yange8fcd012017-01-20 10:43:30 -0800603 InitSingleImplementationFlag(klass, method, image_pointer_size);
Mingyao Yang063fc772016-08-02 11:02:54 -0700604 }
605
Nicolas Geoffray18ea1c92017-03-27 08:00:18 +0000606 if (klass->IsInstantiable()) {
607 auto* iftable = klass->GetIfTable();
608 const size_t ifcount = klass->GetIfTableCount();
609 for (size_t i = 0; i < ifcount; ++i) {
610 mirror::Class* interface = iftable->GetInterface(i);
611 for (size_t j = 0, count = iftable->GetMethodArrayCount(i); j < count; ++j) {
612 ArtMethod* interface_method = interface->GetVirtualMethod(j, image_pointer_size);
613 mirror::PointerArray* method_array = iftable->GetMethodArray(i);
614 ArtMethod* implementation_method =
615 method_array->GetElementPtrSize<ArtMethod*>(j, image_pointer_size);
616 DCHECK(implementation_method != nullptr) << klass->PrettyClass();
617 CheckInterfaceMethodSingleImplementationInfo(klass,
618 interface_method,
619 implementation_method,
620 invalidated_single_impl_methods,
621 image_pointer_size);
622 }
623 }
624 }
625
626 InvalidateSingleImplementationMethods(invalidated_single_impl_methods);
627}
628
629void ClassHierarchyAnalysis::InvalidateSingleImplementationMethods(
630 std::unordered_set<ArtMethod*>& invalidated_single_impl_methods) {
Mingyao Yang063fc772016-08-02 11:02:54 -0700631 if (!invalidated_single_impl_methods.empty()) {
Nicolas Geoffray18ea1c92017-03-27 08:00:18 +0000632 Runtime* const runtime = Runtime::Current();
Mingyao Yang063fc772016-08-02 11:02:54 -0700633 Thread *self = Thread::Current();
634 // Method headers for compiled code to be invalidated.
635 std::unordered_set<OatQuickMethodHeader*> dependent_method_headers;
Nicolas Geoffray18ea1c92017-03-27 08:00:18 +0000636 PointerSize image_pointer_size =
637 Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Mingyao Yang063fc772016-08-02 11:02:54 -0700638
639 {
640 // We do this under cha_lock_. Committing code also grabs this lock to
641 // make sure the code is only committed when all single-implementation
642 // assumptions are still true.
Alex Light33b7b5d2018-08-07 19:13:51 +0000643 std::vector<std::pair<ArtMethod*, OatQuickMethodHeader*>> headers;
644 {
645 MutexLock cha_mu(self, *Locks::cha_lock_);
646 // Invalidate compiled methods that assume some virtual calls have only
647 // single implementations.
648 for (ArtMethod* invalidated : invalidated_single_impl_methods) {
649 if (!invalidated->HasSingleImplementation()) {
650 // It might have been invalidated already when other class linking is
651 // going on.
652 continue;
653 }
654 invalidated->SetHasSingleImplementation(false);
655 if (invalidated->IsAbstract()) {
656 // Clear the single implementation method.
657 invalidated->SetSingleImplementation(nullptr, image_pointer_size);
658 }
Alex Light8dde74e2018-08-07 19:11:05 +0000659
Alex Light33b7b5d2018-08-07 19:13:51 +0000660 if (runtime->IsAotCompiler()) {
661 // No need to invalidate any compiled code as the AotCompiler doesn't
662 // run any code.
663 continue;
664 }
Alex Light8dde74e2018-08-07 19:11:05 +0000665
Alex Light33b7b5d2018-08-07 19:13:51 +0000666 // Invalidate all dependents.
667 for (const auto& dependent : GetDependents(invalidated)) {
668 ArtMethod* method = dependent.first;;
669 OatQuickMethodHeader* method_header = dependent.second;
670 VLOG(class_linker) << "CHA invalidated compiled code for " << method->PrettyMethod();
671 DCHECK(runtime->UseJitCompilation());
672 // We need to call JitCodeCache::InvalidateCompiledCodeFor but we cannot do it here
673 // since it would run into problems with lock-ordering. We don't want to re-order the
674 // locks since that would make code-commit racy.
675 headers.push_back({method, method_header});
676 dependent_method_headers.insert(method_header);
677 }
678 RemoveAllDependenciesFor(invalidated);
Alex Light8dde74e2018-08-07 19:11:05 +0000679 }
Alex Light33b7b5d2018-08-07 19:13:51 +0000680 }
681 // Since we are still loading the class that invalidated the code it's fine we have this after
682 // getting rid of the dependency. Any calls would need to be with the old version (since the
683 // new one isn't loaded yet) which still works fine. We will deoptimize just after this to
684 // ensure everything gets the new state.
685 jit::Jit* jit = Runtime::Current()->GetJit();
686 if (jit != nullptr) {
687 jit::JitCodeCache* code_cache = jit->GetCodeCache();
688 for (const auto& pair : headers) {
689 code_cache->InvalidateCompiledCodeFor(pair.first, pair.second);
690 }
Mingyao Yang063fc772016-08-02 11:02:54 -0700691 }
692 }
693
694 if (dependent_method_headers.empty()) {
695 return;
696 }
697 // Deoptimze compiled code on stack that should have been invalidated.
698 CHACheckpoint checkpoint(dependent_method_headers);
699 size_t threads_running_checkpoint = runtime->GetThreadList()->RunCheckpoint(&checkpoint);
700 if (threads_running_checkpoint != 0) {
701 checkpoint.WaitForThreadsToRunThroughCheckpoint(threads_running_checkpoint);
702 }
703 }
704}
705
Mathieu Chartiercf79cf52017-07-21 11:17:57 -0700706void ClassHierarchyAnalysis::RemoveDependenciesForLinearAlloc(const LinearAlloc* linear_alloc) {
707 MutexLock mu(Thread::Current(), *Locks::cha_lock_);
708 for (auto it = cha_dependency_map_.begin(); it != cha_dependency_map_.end(); ) {
709 // Use unsafe to avoid locking since the allocator is going to be deleted.
710 if (linear_alloc->ContainsUnsafe(it->first)) {
711 // About to delete the ArtMethod, erase the entry from the map.
712 it = cha_dependency_map_.erase(it);
713 } else {
714 ++it;
715 }
716 }
717}
718
Mingyao Yang063fc772016-08-02 11:02:54 -0700719} // namespace art