runtime: Add -Xverify:softfail and ART_TEST_INTERPRETER_ACCESS_CHECKS

Use ART_TEST_INTERPRETER_ACCESS_CHECKS=true to run all the tests through
the interpreter with access checks enabled. The normal interpreter tests
do not currently enable access checks, which means that a large part of
the interpreter codebase is untested.

The verifier will force every class into a soft fail mode if
-Xverify:softfail is used, thereby ensuring that if used along with the
interpreter (-Xint) that the interpret is always in access checks mode.

This is used alongside with --compile-filter=verify-at-runtime to
prevent the AOT compiler from putting down any code.

Change-Id: I35a10ed8c43d76fa96133cf01fdad497da387200
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 5798c04..8f7862a 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -3040,6 +3040,18 @@
     mirror::Class::SetStatus(klass, mirror::Class::kStatusVerifyingAtRuntime, self);
   }
 
+  // Skip verification if we are forcing a soft fail.
+  // This has to be before the normal verification enabled check,
+  // since technically verification is disabled in this mode.
+  if (UNLIKELY(Runtime::Current()->IsVerificationSoftFail())) {
+    // Force verification to be a 'soft failure'.
+    mirror::Class::SetStatus(klass, mirror::Class::kStatusVerified, self);
+    // As this is a fake verified status, make sure the methods are _not_ marked preverified
+    // later.
+    klass->SetPreverified();
+    return;
+  }
+
   // Skip verification if disabled.
   if (!Runtime::Current()->IsVerificationEnabled()) {
     mirror::Class::SetStatus(klass, mirror::Class::kStatusVerified, self);
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index d08af71..7772354 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -244,10 +244,11 @@
           .AppendValues()
           .IntoKey(M::ImageCompilerOptions)
       .Define("-Xverify:_")
-          .WithType<bool>()
-          .WithValueMap({{"none", false},
-                         {"remote", true},
-                         {"all", true}})
+          .WithType<verifier::VerifyMode>()
+          .WithValueMap({{"none",     verifier::VerifyMode::kNone},
+                         {"remote",   verifier::VerifyMode::kEnable},
+                         {"all",      verifier::VerifyMode::kEnable},
+                         {"softfail", verifier::VerifyMode::kSoftFail}})
           .IntoKey(M::Verify)
       .Define("-XX:NativeBridge=_")
           .WithType<std::string>()
@@ -686,7 +687,7 @@
   UsageMessage(stream, "  -esa\n");
   UsageMessage(stream, "  -dsa\n");
   UsageMessage(stream, "   (-enablesystemassertions, -disablesystemassertions)\n");
-  UsageMessage(stream, "  -Xverify:{none,remote,all}\n");
+  UsageMessage(stream, "  -Xverify:{none,remote,all,softfail}\n");
   UsageMessage(stream, "  -Xrs\n");
   UsageMessage(stream, "  -Xint:portable, -Xint:fast, -Xint:jit\n");
   UsageMessage(stream, "  -Xdexopt:{none,verified,all,full}\n");
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 3b0ca9e..c5aece5 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -185,7 +185,7 @@
       system_class_loader_(nullptr),
       dump_gc_performance_on_shutdown_(false),
       preinitialization_transaction_(nullptr),
-      verify_(false),
+      verify_(verifier::VerifyMode::kNone),
       allow_dex_file_fallback_(true),
       target_sdk_version_(0),
       implicit_null_checks_(false),
@@ -1757,4 +1757,12 @@
   imt_unimplemented_method_ = method;
 }
 
+bool Runtime::IsVerificationEnabled() const {
+  return verify_ == verifier::VerifyMode::kEnable;
+}
+
+bool Runtime::IsVerificationSoftFail() const {
+  return verify_ == verifier::VerifyMode::kSoftFail;
+}
+
 }  // namespace art
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 9ee96a3..806292f 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -64,6 +64,7 @@
 }  // namespace mirror
 namespace verifier {
   class MethodVerifier;
+  enum class VerifyMode : int8_t;
 }  // namespace verifier
 class ArenaPool;
 class ArtMethod;
@@ -500,9 +501,8 @@
     return !implicit_so_checks_;
   }
 
-  bool IsVerificationEnabled() const {
-    return verify_;
-  }
+  bool IsVerificationEnabled() const;
+  bool IsVerificationSoftFail() const;
 
   bool IsDexFileFallbackEnabled() const {
     return allow_dex_file_fallback_;
@@ -700,8 +700,8 @@
   // Transaction used for pre-initializing classes at compilation time.
   Transaction* preinitialization_transaction_;
 
-  // If false, verification is disabled. True by default.
-  bool verify_;
+  // If kNone, verification is disabled. kEnable by default.
+  verifier::VerifyMode verify_;
 
   // If true, the runtime may use dex files directly with the interpreter if an oat file is not
   // available/usable.
diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def
index dc4c0c7..9922c5f 100644
--- a/runtime/runtime_options.def
+++ b/runtime/runtime_options.def
@@ -106,7 +106,8 @@
                                           CompilerOptions)  // -Xcompiler-option ...
 RUNTIME_OPTIONS_KEY (std::vector<std::string>, \
                                           ImageCompilerOptions)  // -Ximage-compiler-option ...
-RUNTIME_OPTIONS_KEY (bool,                Verify,                         true)
+RUNTIME_OPTIONS_KEY (verifier::VerifyMode, \
+                                          Verify,                         verifier::VerifyMode::kEnable)
 RUNTIME_OPTIONS_KEY (std::string,         NativeBridge)
 RUNTIME_OPTIONS_KEY (unsigned int,        ZygoteMaxFailedBoots,           10)
 RUNTIME_OPTIONS_KEY (Unit,                NoDexFileFallback)
diff --git a/runtime/runtime_options.h b/runtime/runtime_options.h
index 7e59000..88ac00a 100644
--- a/runtime/runtime_options.h
+++ b/runtime/runtime_options.h
@@ -32,6 +32,7 @@
 #include "gc/space/large_object_space.h"
 #include "profiler_options.h"
 #include "arch/instruction_set.h"
+#include "verifier/verify_mode.h"
 #include <stdio.h>
 #include <stdarg.h>
 
diff --git a/runtime/verifier/verify_mode.h b/runtime/verifier/verify_mode.h
new file mode 100644
index 0000000..bea4378
--- /dev/null
+++ b/runtime/verifier/verify_mode.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_VERIFIER_VERIFY_MODE_H_
+#define ART_RUNTIME_VERIFIER_VERIFY_MODE_H_
+
+#include <stdint.h>
+
+namespace art {
+namespace verifier {
+
+// The mode that the verifier should run as.
+enum class VerifyMode : int8_t {
+  kNone,      // Everything is assumed verified.
+  kEnable,    // Standard verification, try pre-verifying at compile-time.
+  kSoftFail,  // Force a soft fail, punting to the interpreter with access checks.
+};
+
+}  // namespace verifier
+}  // namespace art
+
+#endif  // ART_RUNTIME_VERIFIER_VERIFY_MODE_H_