verifier: do not infer an instruction will throw.
Turning a regular instruction into a throwing one has currently
undesirable consequences:
1) It leads to inconsistencies between the AOT verification and the
runtime verification.
2) It treats the following code dead and does not analyze it. We treat
this as an non-compilable method as it's a lot simpler for the
compiler to consider all code verified.
3) It prevents verification optimizations like doing one-pass
analysis over the code.
To be AOT / runtime consistent and follow RI behavior, stop considering
such instructions as throwing.
We make this API version dependent for app compatibility reasons.
Test: test.py
Bug: 28313047
Change-Id: I9c847043d1f431f642731a70f651c93ef22fdf86
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 2bd5845..acc17e1 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -4678,9 +4678,9 @@
<< preverified
<< "( " << oat_file_class_status << ")";
- // If the oat file says the class had an error, re-run the verifier. That way we will get a
- // precise error message. To ensure a rerun, test:
- // mirror::Class::IsErroneous(oat_file_class_status) => !preverified
+ // If the oat file says the class had an error, re-run the verifier. That way we will either:
+ // 1) Be successful at runtime, or
+ // 2) Get a precise error message.
DCHECK(!mirror::Class::IsErroneous(oat_file_class_status) || !preverified);
std::string error_msg;
@@ -4822,8 +4822,9 @@
// Check the class status with the vdex file.
const OatFile* oat_file = oat_dex_file->GetOatFile();
if (oat_file != nullptr) {
- oat_file_class_status = oat_file->GetVdexFile()->ComputeClassStatus(self, klass);
- if (oat_file_class_status >= ClassStatus::kVerifiedNeedsAccessChecks) {
+ ClassStatus vdex_status = oat_file->GetVdexFile()->ComputeClassStatus(self, klass);
+ if (vdex_status >= ClassStatus::kVerifiedNeedsAccessChecks) {
+ oat_file_class_status = vdex_status;
return true;
}
}
@@ -4838,8 +4839,8 @@
<< klass->PrettyClass() << " " << dex_file.GetLocation();
if (mirror::Class::IsErroneous(oat_file_class_status)) {
- // Compile time verification failed with a hard error. This is caused by invalid instructions
- // in the class. These errors are unrecoverable.
+ // Compile time verification failed with a hard error. We'll re-run
+ // verification, which might be successful at runtime.
return false;
}
if (oat_file_class_status == ClassStatus::kNotReady) {