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/runtime_support.cc b/src/runtime_support.cc
index 9242c87..f6225ed 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -142,7 +142,8 @@
 }
 
 mirror::Field* FindFieldFromCode(uint32_t field_idx, const mirror::AbstractMethod* referrer,
-                                 Thread* self, FindFieldType type, size_t expected_size) {
+                                 Thread* self, FindFieldType type, size_t expected_size,
+                                 bool access_check) {
   bool is_primitive;
   bool is_set;
   bool is_static;
@@ -162,12 +163,13 @@
   if (UNLIKELY(resolved_field == NULL)) {
     DCHECK(self->IsExceptionPending());  // Throw exception and unwind.
     return NULL;  // Failure.
-  } else {
+  }
+  mirror::Class* fields_class = resolved_field->GetDeclaringClass();
+  if (access_check) {
     if (UNLIKELY(resolved_field->IsStatic() != is_static)) {
       ThrowIncompatibleClassChangeErrorField(resolved_field, is_static, referrer);
       return NULL;
     }
-    mirror::Class* fields_class = resolved_field->GetDeclaringClass();
     mirror::Class* referring_class = referrer->GetDeclaringClass();
     if (UNLIKELY(!referring_class->CanAccess(fields_class) ||
                  !referring_class->CanAccessMember(fields_class,
@@ -203,23 +205,24 @@
                                  is_primitive ? "primitive" : "non-primitive",
                                  PrettyField(resolved_field, true).c_str());
         return NULL;  // failure
-      } else if (!is_static) {
-        // instance fields must be being accessed on an initialized class
-        return resolved_field;
-      } else {
-        // If the class is initialized we're done.
-        if (fields_class->IsInitialized()) {
-          return resolved_field;
-        } else if (Runtime::Current()->GetClassLinker()->EnsureInitialized(fields_class, true, true)) {
-          // Otherwise let's ensure the class is initialized before resolving the field.
-          return resolved_field;
-        } else {
-          DCHECK(self->IsExceptionPending());  // Throw exception and unwind
-          return NULL;  // failure
-        }
       }
     }
   }
+  if (!is_static) {
+    // instance fields must be being accessed on an initialized class
+    return resolved_field;
+  } else {
+    // If the class is initialized we're done.
+    if (fields_class->IsInitialized()) {
+      return resolved_field;
+    } else if (Runtime::Current()->GetClassLinker()->EnsureInitialized(fields_class, true, true)) {
+      // Otherwise let's ensure the class is initialized before resolving the field.
+      return resolved_field;
+    } else {
+      DCHECK(self->IsExceptionPending());  // Throw exception and unwind
+      return NULL;  // failure
+    }
+  }
 }
 
 // Slow path method resolution