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,