Sharpen virtual calls to final methods.
Also remove unused instance resolution stub.
Change-Id: I2abb988d107e98ac0148fb81464b22622a468382
diff --git a/src/compiler.cc b/src/compiler.cc
index 51354aa..98d8fac 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -86,7 +86,8 @@
strings_in_dex_cache_(0), strings_not_in_dex_cache_(0),
resolved_types_(0), unresolved_types_(0),
resolved_instance_fields_(0), unresolved_instance_fields_(0),
- resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0) {
+ resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0),
+ virtual_made_direct_(0) {
for (size_t i = 0; i < kMaxInvokeType; i++) {
resolved_methods_[i] = 0;
unresolved_methods_[i] = 0;
@@ -108,6 +109,8 @@
oss << "resolved " << static_cast<InvokeType>(i) << " methods";
DumpStat(resolved_methods_[i], unresolved_methods_[i], oss.str().c_str());
}
+ DumpStat(virtual_made_direct_, resolved_methods_[kVirtual] + unresolved_methods_[kVirtual],
+ "made direct from virtual");
}
// Allow lossy statistics in non-debug builds
@@ -184,6 +187,10 @@
unresolved_methods_[type]++;
}
+ void VirtualMadeDirect() {
+ STATS_LOCK();
+ virtual_made_direct_++;
+ }
private:
Mutex stats_lock_;
@@ -205,6 +212,7 @@
size_t resolved_methods_[kMaxInvokeType + 1];
size_t unresolved_methods_[kMaxInvokeType + 1];
+ size_t virtual_made_direct_;
DISALLOW_COPY_AND_ASSIGN(AOTCompilationStats);;
};
@@ -566,7 +574,7 @@
return false; // Incomplete knowledge needs slow path.
}
-bool Compiler::ComputeInvokeInfo(uint32_t method_idx, OatCompilationUnit* mUnit, InvokeType type,
+bool Compiler::ComputeInvokeInfo(uint32_t method_idx, OatCompilationUnit* mUnit, InvokeType& type,
int& vtable_idx) {
vtable_idx = -1;
Method* resolved_method = ComputeReferrerMethod(mUnit, method_idx);
@@ -591,7 +599,16 @@
referrer_class->CanAccessMember(methods_class,
resolved_method->GetAccessFlags())) {
vtable_idx = resolved_method->GetMethodIndex();
- if (type != kSuper) {
+ if (type == kVirtual && (resolved_method->IsFinal() || methods_class->IsFinal())) {
+ stats_->ResolvedMethod(kVirtual);
+ // Sharpen a virtual call into a direct call. The method_idx is into referrer's
+ // dex cache, check that this resolved method is where we expect it.
+ CHECK(referrer_class->GetDexCache()->GetResolvedMethod(method_idx) == resolved_method)
+ << PrettyMethod(resolved_method);
+ type = kDirect;
+ stats_->VirtualMadeDirect();
+ return true;
+ } else if (type != kSuper) {
// nothing left to do for static/direct/virtual/interface dispatch
stats_->ResolvedMethod(type);
return true;