Mark array classes as verification attempted

We now initialize all array classes in the compiler driver. This in
turn will ensure they are marked verified in the image. This
prevents dirty pages in the image since we would otherwise set the
flags in the zygote.

On BusinessCard:
Reduces shared dirty from 636k -> 432k for boot.art, and dirty pages
from 183 to 132.

(cherry picked from commit 3b674098bef6eaf7d3fb731878293ef715fe1080)

Change-Id: If3093e4e3242e4ee3ea120abe5be7db028290260
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index d29d528..be149af 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -2486,6 +2486,20 @@
   context.ForAll(0, dex_file.NumClassDefs(), &visitor, init_thread_count);
 }
 
+class InitializeArrayClassVisitor : public ClassVisitor {
+ public:
+  virtual bool operator()(mirror::Class* klass) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) {
+    if (klass->IsArrayClass()) {
+      StackHandleScope<1> hs(Thread::Current());
+      Runtime::Current()->GetClassLinker()->EnsureInitialized(hs.Self(),
+                                                              hs.NewHandle(klass),
+                                                              true,
+                                                              true);
+    }
+    return true;
+  }
+};
+
 void CompilerDriver::InitializeClasses(jobject class_loader,
                                        const std::vector<const DexFile*>& dex_files,
                                        TimingLogger* timings) {
@@ -2494,6 +2508,14 @@
     CHECK(dex_file != nullptr);
     InitializeClasses(class_loader, *dex_file, dex_files, timings);
   }
+  {
+    // Make sure that we call EnsureIntiailized on all the array classes to call
+    // SetVerificationAttempted so that the access flags are set. If we do not do this they get
+    // changed at runtime resulting in more dirty image pages.
+    ScopedObjectAccess soa(Thread::Current());
+    InitializeArrayClassVisitor visitor;
+    Runtime::Current()->GetClassLinker()->VisitClasses(&visitor);
+  }
   if (IsBootImage()) {
     // Prune garbage objects created during aborted transactions.
     Runtime::Current()->GetHeap()->CollectGarbage(true);