summaryrefslogtreecommitdiff
path: root/compiler/driver/compiler_driver-inl.h
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2015-06-15 18:52:54 +0100
committer Vladimir Marko <vmarko@google.com> 2015-06-18 12:44:51 +0100
commit07785bb98dc8bbe192970e0f4c2cafd338a8dc68 (patch)
treed12a20d7790fffc8648d7da6a7944595516c1d89 /compiler/driver/compiler_driver-inl.h
parent6ebf70ec61eff097e1bdddb1b887316389e34dde (diff)
ART: Fix reporting initialized classes by CompilerDriver.
Fix a bug where the CompilerDriver was erroneously reporting classes as initialized during AOT compilation when they were not guaranteed to be initialized at runtime. This fix prevents the Quick compiler from inlining calls to static methods in classes that are not guaranteed to be initialized, so that the runtime performs the initialization required for correctness. Bug: 21847756 Change-Id: I6fee5ef9c05c2e5190ab8a9fe61365d5119011c5
Diffstat (limited to 'compiler/driver/compiler_driver-inl.h')
-rw-r--r--compiler/driver/compiler_driver-inl.h25
1 files changed, 23 insertions, 2 deletions
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h
index b25e967609..e0c56fcc82 100644
--- a/compiler/driver/compiler_driver-inl.h
+++ b/compiler/driver/compiler_driver-inl.h
@@ -233,11 +233,32 @@ inline bool CompilerDriver::IsStaticFieldInReferrerClass(mirror::Class* referrer
return referrer_class == fields_class;
}
+inline bool CompilerDriver::CanAssumeClassIsInitialized(mirror::Class* klass) {
+ // Being loaded is a pre-requisite for being initialized but let's do the cheap check first.
+ //
+ // NOTE: When AOT compiling an app, we eagerly initialize app classes (and potentially their
+ // super classes in the boot image) but only those that have a trivial initialization, i.e.
+ // without <clinit>() or static values in the dex file for that class or any of its super
+ // classes. So while we could see the klass as initialized during AOT compilation and have
+ // it only loaded at runtime, the needed initialization would have to be trivial and
+ // unobservable from Java, so we may as well treat it as initialized.
+ if (!klass->IsInitialized()) {
+ return false;
+ }
+ return CanAssumeClassIsLoaded(klass);
+}
+
+inline bool CompilerDriver::CanReferrerAssumeClassIsInitialized(mirror::Class* referrer_class,
+ mirror::Class* klass) {
+ return (referrer_class != nullptr && referrer_class->IsSubClass(klass)) ||
+ CanAssumeClassIsInitialized(klass);
+}
+
inline bool CompilerDriver::IsStaticFieldsClassInitialized(mirror::Class* referrer_class,
ArtField* resolved_field) {
DCHECK(resolved_field->IsStatic());
mirror::Class* fields_class = resolved_field->GetDeclaringClass();
- return fields_class == referrer_class || fields_class->IsInitialized();
+ return CanReferrerAssumeClassIsInitialized(referrer_class, fields_class);
}
inline ArtMethod* CompilerDriver::ResolveMethod(
@@ -394,7 +415,7 @@ inline bool CompilerDriver::IsMethodsClassInitialized(mirror::Class* referrer_cl
return true;
}
mirror::Class* methods_class = resolved_method->GetDeclaringClass();
- return methods_class == referrer_class || methods_class->IsInitialized();
+ return CanReferrerAssumeClassIsInitialized(referrer_class, methods_class);
}
} // namespace art