Avoid creating verification_results_ unnecessarily

For compiler filters that don't quicken or compile, avoid creating
the verification results. This avoids creating some arrays that
were using a few MB of RAM in some cases.

For a large app verify compile:
Maximum resident set size (kbytes): 258948 -> 254300

Bug: 63467744
Test: test-art-host

Change-Id: I1d0536b2a6a5c301396641371915394cf4c0e5f3
diff --git a/compiler/dex/quick_compiler_callbacks.cc b/compiler/dex/quick_compiler_callbacks.cc
index 932eb51..b1006b2 100644
--- a/compiler/dex/quick_compiler_callbacks.cc
+++ b/compiler/dex/quick_compiler_callbacks.cc
@@ -22,11 +22,15 @@
 namespace art {
 
 void QuickCompilerCallbacks::MethodVerified(verifier::MethodVerifier* verifier) {
-  verification_results_->ProcessVerifiedMethod(verifier);
+  if (verification_results_ != nullptr) {
+    verification_results_->ProcessVerifiedMethod(verifier);
+  }
 }
 
 void QuickCompilerCallbacks::ClassRejected(ClassReference ref) {
-  verification_results_->AddRejectedClass(ref);
+  if (verification_results_ != nullptr) {
+    verification_results_->AddRejectedClass(ref);
+  }
 }
 
 }  // namespace art
diff --git a/compiler/dex/quick_compiler_callbacks.h b/compiler/dex/quick_compiler_callbacks.h
index db0fdaa..2100522 100644
--- a/compiler/dex/quick_compiler_callbacks.h
+++ b/compiler/dex/quick_compiler_callbacks.h
@@ -30,9 +30,7 @@
                            CompilerCallbacks::CallbackMode mode)
         : CompilerCallbacks(mode),
           verification_results_(verification_results),
-          verifier_deps_(nullptr) {
-      CHECK(verification_results != nullptr);
-    }
+          verifier_deps_(nullptr) {}
 
     ~QuickCompilerCallbacks() { }
 
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index c04e45d..00a852f 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -514,8 +514,9 @@
     // TODO: Refactor the compilation to avoid having to distinguish the two passes
     // here. That should be done on a higher level. http://b/29089975
     if (driver->GetCurrentDexToDexMethods()->IsBitSet(method_idx)) {
-      const VerifiedMethod* verified_method =
-          driver->GetVerificationResults()->GetVerifiedMethod(method_ref);
+      VerificationResults* results = driver->GetVerificationResults();
+      DCHECK(results != nullptr);
+      const VerifiedMethod* verified_method = results->GetVerifiedMethod(method_ref);
       // Do not optimize if a VerifiedMethod is missing. SafeCast elision,
       // for example, relies on it.
       compiled_method = optimizer::ArtCompileDEX(
@@ -576,12 +577,12 @@
   } else if ((access_flags & kAccAbstract) != 0) {
     // Abstract methods don't have code.
   } else {
-    const VerifiedMethod* verified_method =
-        driver->GetVerificationResults()->GetVerifiedMethod(method_ref);
+    VerificationResults* results = driver->GetVerificationResults();
+    DCHECK(results != nullptr);
+    const VerifiedMethod* verified_method = results->GetVerifiedMethod(method_ref);
     bool compile = compilation_enabled &&
         // Basic checks, e.g., not <clinit>.
-        driver->GetVerificationResults()
-            ->IsCandidateForCompilation(method_ref, access_flags) &&
+        results->IsCandidateForCompilation(method_ref, access_flags) &&
         // Did not fail to create VerifiedMethod metadata.
         verified_method != nullptr &&
         // Do not have failures that should punt to the interpreter.
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 7aef785..54b3520 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -800,7 +800,8 @@
     mirror::Class::Status status;
     bool found = writer_->compiler_driver_->GetCompiledClass(class_ref, &status);
     if (!found) {
-      if (writer_->compiler_driver_->GetVerificationResults()->IsClassRejected(class_ref)) {
+      VerificationResults* results = writer_->compiler_driver_->GetVerificationResults();
+      if (results != nullptr && results->IsClassRejected(class_ref)) {
         // The oat class status is used only for verification of resolved classes,
         // so use kStatusErrorResolved whether the class was resolved or unresolved
         // during compile-time verification.
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 746a940..113bdb5 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -1516,7 +1516,10 @@
       return dex2oat::ReturnCode::kOther;
     }
 
-    verification_results_.reset(new VerificationResults(compiler_options_.get()));
+    if (CompilerFilter::IsAnyCompilationEnabled(compiler_options_->GetCompilerFilter())) {
+      // Only modes with compilation require verification results.
+      verification_results_.reset(new VerificationResults(compiler_options_.get()));
+    }
     callbacks_.reset(new QuickCompilerCallbacks(
         verification_results_.get(),
         IsBootImage() ?
@@ -1732,7 +1735,11 @@
       }
       // Pre-register dex files so that we can access verification results without locks during
       // compilation and verification.
-      verification_results_->AddDexFile(dex_file);
+      if (verification_results_ != nullptr) {
+        // Verification results are only required for modes that have any compilation. Avoid
+        // adding the dex files if possible to prevent allocating large arrays.
+        verification_results_->AddDexFile(dex_file);
+      }
     }
 
     return dex2oat::ReturnCode::kNoFailure;