summaryrefslogtreecommitdiffstats
path: root/src/compiler/driver/compiler_driver.cc
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2013-06-05 16:52:26 -0700
committerIan Rogers <irogers@google.com>2013-06-05 23:57:52 -0700
commitc9e463c8aa083a5ed20293f42363ebff93de5f84 (patch)
tree9664a0f909043f822437e804339c11eb77896db7 /src/compiler/driver/compiler_driver.cc
parenta7005960d536cbfd7ba82d2fa52ee1865516435b (diff)
downloadandroid_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.cc22
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();
}