No access check support.
This CL adds support to disable access check when a method is preverified (at
compilation time) and we know we don't need to do any access check.
The interpreter has now two modes of execution: with or without access check.
This is realized by using a template function.
A new runtime access flag kAccPreverified is added onto each method belonging
to a preverified class. If this flag is set, we enter the interpreter in "no
access check" mode. Otherwise, we enter the interpreter in "with access check"
mode.
Change-Id: Ic34163421d5b0aca3d1bce22ef7c095dcf465a18
diff --git a/src/class_linker.cc b/src/class_linker.cc
index c5c669e..6e32065 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -2247,7 +2247,6 @@
const DexFile& dex_file = *klass->GetDexCache()->GetDexFile();
mirror::Class::Status oat_file_class_status(mirror::Class::kStatusNotReady);
bool preverified = VerifyClassUsingOatFile(dex_file, klass, oat_file_class_status);
- verifier::MethodVerifier::FailureKind verifier_failure = verifier::MethodVerifier::kNoFailure;
if (oat_file_class_status == mirror::Class::kStatusError) {
LOG(WARNING) << "Skipping runtime verification of erroneous class " << PrettyDescriptor(klass)
<< " in " << klass->GetDexCache()->GetLocation()->ToModifiedUtf8();
@@ -2256,9 +2255,11 @@
klass->SetStatus(mirror::Class::kStatusError);
return;
}
+ verifier::MethodVerifier::FailureKind verifier_failure = verifier::MethodVerifier::kNoFailure;
std::string error_msg;
if (!preverified) {
- verifier_failure = verifier::MethodVerifier::VerifyClass(klass, error_msg, Runtime::Current()->IsCompiler());
+ verifier_failure = verifier::MethodVerifier::VerifyClass(klass, error_msg,
+ Runtime::Current()->IsCompiler());
}
if (preverified || verifier_failure != verifier::MethodVerifier::kHardFailure) {
if (!preverified && verifier_failure != verifier::MethodVerifier::kNoFailure) {
@@ -2290,6 +2291,15 @@
ThrowVerifyError(klass, "%s", error_msg.c_str());
klass->SetStatus(mirror::Class::kStatusError);
}
+ if (preverified || verifier_failure == verifier::MethodVerifier::kNoFailure) {
+ // Class is verified so we don't need to do any access check in its methods.
+ // Let the interpreter know it by setting the kAccPreverified flag onto each
+ // method.
+ // Note: we're going here during compilation and at runtime. When we set the
+ // kAccPreverified flag when compiling image classes, the flag is recorded
+ // in the image and is set when loading the image.
+ klass->SetPreverifiedFlagOnAllMethods();
+ }
}
bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class* klass,