ART: Compiled-classes list for compiler-driver

Similar to the image-classes list, introduce a list of class names
that are to be compiled when creating a boot image. This defaults
to all classes.

Bug: 18336591

(cherry picked from commit 26318f722958ac1cba6a812026a1377f37c54941)

Change-Id: I95f69afdb500a9defb6795803d4040bbe67c5a01
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index aab94c0..08041e8 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -330,7 +330,8 @@
                                Compiler::Kind compiler_kind,
                                InstructionSet instruction_set,
                                const InstructionSetFeatures* instruction_set_features,
-                               bool image, std::set<std::string>* image_classes, size_t thread_count,
+                               bool image, std::set<std::string>* image_classes,
+                               std::set<std::string>* compiled_classes, size_t thread_count,
                                bool dump_stats, bool dump_passes, CumulativeLogger* timer,
                                const std::string& profile_file)
     : profile_present_(false), compiler_options_(compiler_options),
@@ -346,6 +347,7 @@
       non_relative_linker_patch_count_(0u),
       image_(image),
       image_classes_(image_classes),
+      classes_to_compile_(compiled_classes),
       thread_count_(thread_count),
       stats_(new AOTCompilationStats),
       dump_stats_(dump_stats),
@@ -570,7 +572,7 @@
                                                                class_def);
   }
   CompileMethod(code_item, access_flags, invoke_type, class_def_idx, method_idx, jclass_loader,
-                *dex_file, dex_to_dex_compilation_level);
+                *dex_file, dex_to_dex_compilation_level, true);
 
   self->GetJniEnv()->DeleteGlobalRef(jclass_loader);
 
@@ -613,6 +615,17 @@
   }
 }
 
+bool CompilerDriver::IsClassToCompile(const char* descriptor) const {
+  if (!IsImage()) {
+    return true;
+  } else {
+    if (classes_to_compile_ == nullptr) {
+      return true;
+    }
+    return classes_to_compile_->find(descriptor) != classes_to_compile_->end();
+  }
+}
+
 static void ResolveExceptionsForMethod(MutableMethodHelper* mh,
     std::set<std::pair<uint16_t, const DexFile*>>& exceptions_to_resolve)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -1916,6 +1929,10 @@
     it.Next();
   }
   CompilerDriver* driver = manager->GetCompiler();
+
+  bool compilation_enabled = driver->IsClassToCompile(
+      dex_file.StringByTypeIdx(class_def.class_idx_));
+
   // Compile direct methods
   int64_t previous_direct_method_idx = -1;
   while (it.HasNextDirectMethod()) {
@@ -1929,7 +1946,8 @@
     previous_direct_method_idx = method_idx;
     driver->CompileMethod(it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
                           it.GetMethodInvokeType(class_def), class_def_index,
-                          method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level);
+                          method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
+                          compilation_enabled);
     it.Next();
   }
   // Compile virtual methods
@@ -1945,7 +1963,8 @@
     previous_virtual_method_idx = method_idx;
     driver->CompileMethod(it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
                           it.GetMethodInvokeType(class_def), class_def_index,
-                          method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level);
+                          method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
+                          compilation_enabled);
     it.Next();
   }
   DCHECK(!it.HasNext());
@@ -1977,7 +1996,8 @@
                                    InvokeType invoke_type, uint16_t class_def_idx,
                                    uint32_t method_idx, jobject class_loader,
                                    const DexFile& dex_file,
-                                   DexToDexCompilationLevel dex_to_dex_compilation_level) {
+                                   DexToDexCompilationLevel dex_to_dex_compilation_level,
+                                   bool compilation_enabled) {
   CompiledMethod* compiled_method = nullptr;
   uint64_t start_ns = kTimeCompileMethod ? NanoTime() : 0;
 
@@ -1994,7 +2014,8 @@
     // Abstract methods don't have code.
   } else {
     MethodReference method_ref(&dex_file, method_idx);
-    bool compile = verification_results_->IsCandidateForCompilation(method_ref, access_flags);
+    bool compile = compilation_enabled &&
+                   verification_results_->IsCandidateForCompilation(method_ref, access_flags);
     if (compile) {
       // NOTE: if compiler declines to compile this method, it will return nullptr.
       compiled_method = compiler_->Compile(code_item, access_flags, invoke_type, class_def_idx,