diff options
author | Ian Rogers <irogers@google.com> | 2013-06-05 16:52:26 -0700 |
---|---|---|
committer | Ian Rogers <irogers@google.com> | 2013-06-05 23:57:52 -0700 |
commit | c9e463c8aa083a5ed20293f42363ebff93de5f84 (patch) | |
tree | 9664a0f909043f822437e804339c11eb77896db7 /src/compiler/driver/compiler_driver.cc | |
parent | a7005960d536cbfd7ba82d2fa52ee1865516435b (diff) | |
download | android_art-c9e463c8aa083a5ed20293f42363ebff93de5f84.tar.gz android_art-c9e463c8aa083a5ed20293f42363ebff93de5f84.tar.bz2 android_art-c9e463c8aa083a5ed20293f42363ebff93de5f84.zip |
Faster instance-of for final classes.
If a class is final and not and array we can generate a 1/0 based on class
equality.
Use a method's declaring class if it matches the instance-of class (common in
Java equals methods).
Don't do a class pointer comparison in the case of an abstract or interface
class, just go straight into the slow-path.
Fix performance bug where peep-hole verifier pass didn't merge into the
fall-through line if the next instruction wasn't interesting.
Change-Id: Idb47ec6acebfd25a344ed74adaacba02fafc7df2
Diffstat (limited to 'src/compiler/driver/compiler_driver.cc')
-rw-r--r-- | src/compiler/driver/compiler_driver.cc | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/src/compiler/driver/compiler_driver.cc b/src/compiler/driver/compiler_driver.cc index 3dddc751be..1b8f87d51f 100644 --- a/src/compiler/driver/compiler_driver.cc +++ b/src/compiler/driver/compiler_driver.cc @@ -577,7 +577,18 @@ bool CompilerDriver::CanAssumeStringIsPresentInDexCache(const DexFile& dex_file, } bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file, - uint32_t type_idx) { + uint32_t type_idx, + bool* type_known_final, bool* type_known_abstract, + bool* equals_referrers_class) { + if (type_known_final != NULL) { + *type_known_final = false; + } + if (type_known_abstract != NULL) { + *type_known_abstract = false; + } + if (equals_referrers_class != NULL) { + *equals_referrers_class = false; + } ScopedObjectAccess soa(Thread::Current()); mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); // Get type from dex cache assuming it was populated by the verifier @@ -587,6 +598,9 @@ bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const Dex return false; // Unknown class needs access checks. } const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); + if (equals_referrers_class != NULL) { + *equals_referrers_class = (method_id.class_idx_ == type_idx); + } mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); if (referrer_class == NULL) { stats_->TypeNeedsAccessCheck(); @@ -597,6 +611,12 @@ bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const Dex bool result = referrer_class->CanAccess(resolved_class); if (result) { stats_->TypeDoesntNeedAccessCheck(); + if (type_known_final != NULL) { + *type_known_final = resolved_class->IsFinal() && !resolved_class->IsArrayClass(); + } + if (type_known_abstract != NULL) { + *type_known_abstract = resolved_class->IsAbstract(); + } } else { stats_->TypeNeedsAccessCheck(); } |