Move TimingLogger creation to dex2oat

Change-Id: I4fdb6afd4ce2ac0d91c6c968893606d593b6ea18
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 6558f8a..b1b205e 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -335,7 +335,7 @@
 
 CompilerDriver::CompilerDriver(CompilerBackend compiler_backend, InstructionSet instruction_set,
                                bool image, DescriptorSet* image_classes,
-                               size_t thread_count, bool dump_stats, bool dump_timings)
+                               size_t thread_count, bool dump_stats)
     : compiler_backend_(compiler_backend),
       instruction_set_(instruction_set),
       freezing_constructor_lock_("freezing constructor lock"),
@@ -347,7 +347,6 @@
       start_ns_(0),
       stats_(new AOTCompilationStats),
       dump_stats_(dump_stats),
-      dump_timings_(dump_timings),
       compiler_library_(NULL),
       compiler_(NULL),
       compiler_context_(NULL),
@@ -495,20 +494,12 @@
 }
 
 void CompilerDriver::CompileAll(jobject class_loader,
-                                const std::vector<const DexFile*>& dex_files) {
+                                const std::vector<const DexFile*>& dex_files,
+                                TimingLogger& timings) {
   DCHECK(!Runtime::Current()->IsStarted());
-
   UniquePtr<ThreadPool> thread_pool(new ThreadPool(thread_count_));
-  TimingLogger timings("compiler", false);
-
   PreCompile(class_loader, dex_files, *thread_pool.get(), timings);
-
   Compile(class_loader, dex_files, *thread_pool.get(), timings);
-
-  if (dump_timings_ && timings.GetTotalNs() > MsToNs(1000)) {
-    LOG(INFO) << Dumpable<TimingLogger>(timings);
-  }
-
   if (dump_stats_) {
     stats_->Dump();
   }
@@ -537,7 +528,7 @@
   return klass->IsVerified();
 }
 
-void CompilerDriver::CompileOne(const mirror::AbstractMethod* method) {
+void CompilerDriver::CompileOne(const mirror::AbstractMethod* method, TimingLogger& timings) {
   DCHECK(!Runtime::Current()->IsStarted());
   Thread* self = Thread::Current();
   jobject jclass_loader;
@@ -560,7 +551,6 @@
   dex_files.push_back(dex_file);
 
   UniquePtr<ThreadPool> thread_pool(new ThreadPool(1U));
-  TimingLogger timings("CompileOne", false);
   PreCompile(jclass_loader, dex_files, *thread_pool.get(), timings);
 
   uint32_t method_idx = method->GetDexMethodIndex();
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 902fda7..1799057 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -72,15 +72,16 @@
   // classes.
   explicit CompilerDriver(CompilerBackend compiler_backend, InstructionSet instruction_set,
                           bool image, DescriptorSet* image_classes,
-                          size_t thread_count, bool dump_stats, bool dump_timings);
+                          size_t thread_count, bool dump_stats);
 
   ~CompilerDriver();
 
-  void CompileAll(jobject class_loader, const std::vector<const DexFile*>& dex_files)
+  void CompileAll(jobject class_loader, const std::vector<const DexFile*>& dex_files,
+                  TimingLogger& timings)
       LOCKS_EXCLUDED(Locks::mutator_lock_);
 
   // Compile a single Method
-  void CompileOne(const mirror::AbstractMethod* method)
+  void CompileOne(const mirror::AbstractMethod* method, TimingLogger& timings)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   InstructionSet GetInstructionSet() const {
@@ -362,7 +363,6 @@
   UniquePtr<AOTCompilationStats> stats_;
 
   bool dump_stats_;
-  bool dump_timings_;
 
   typedef void (*CompilerCallbackFn)(CompilerDriver& driver);
   typedef MutexLock* (*CompilerMutexLockFn)(CompilerDriver& driver);
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index 6a160f7..78cacaf 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -36,7 +36,10 @@
 class CompilerDriverTest : public CommonTest {
  protected:
   void CompileAll(jobject class_loader) LOCKS_EXCLUDED(Locks::mutator_lock_) {
-    compiler_driver_->CompileAll(class_loader, Runtime::Current()->GetCompileTimeClassPath(class_loader));
+    TimingLogger timings("CompilerDriverTest::CompileAll", false);
+    compiler_driver_->CompileAll(class_loader,
+                                 Runtime::Current()->GetCompileTimeClassPath(class_loader),
+                                 timings);
     MakeAllExecutable(class_loader);
   }
 
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 75e1afe..995f6d4 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -83,8 +83,8 @@
   UsageError("      containing a classes.dex file to compile.");
   UsageError("      Example: --zip-fd=5");
   UsageError("");
-  UsageError("  --zip-location=<zip-location>: specifies a symbolic name for the file corresponding");
-  UsageError("      to the file descriptor specified by --zip-fd.");
+  UsageError("  --zip-location=<zip-location>: specifies a symbolic name for the file");
+  UsageError("      corresponding to the file descriptor specified by --zip-fd.");
   UsageError("      Example: --zip-location=/system/app/Calculator.apk");
   UsageError("");
   UsageError("  --oat-file=<file.oat>: specifies the oat output destination via a filename.");
@@ -148,8 +148,11 @@
 
 class Dex2Oat {
  public:
-  static bool Create(Dex2Oat** p_dex2oat, Runtime::Options& options, CompilerBackend compiler_backend,
-                     InstructionSet instruction_set, size_t thread_count)
+  static bool Create(Dex2Oat** p_dex2oat,
+                     Runtime::Options& options,
+                     CompilerBackend compiler_backend,
+                     InstructionSet instruction_set,
+                     size_t thread_count)
       SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) {
     if (!CreateRuntime(options, instruction_set)) {
       *p_dex2oat = NULL;
@@ -161,13 +164,15 @@
 
   ~Dex2Oat() {
     delete runtime_;
-    LOG(INFO) << "dex2oat took " << PrettyDuration(NanoTime() - start_ns_) << " (threads: " << thread_count_ << ")";
+    LOG(INFO) << "dex2oat took " << PrettyDuration(NanoTime() - start_ns_)
+              << " (threads: " << thread_count_ << ")";
   }
 
 
-  // Reads the class names (java.lang.Object) and returns as set of class descriptors (Ljava/lang/Object;)
+  // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;)
   CompilerDriver::DescriptorSet* ReadImageClassesFromFile(const char* image_classes_filename) {
-    UniquePtr<std::ifstream> image_classes_file(new std::ifstream(image_classes_filename, std::ifstream::in));
+    UniquePtr<std::ifstream> image_classes_file(new std::ifstream(image_classes_filename,
+                                                                  std::ifstream::in));
     if (image_classes_file.get() == NULL) {
       LOG(ERROR) << "Failed to open image classes file " << image_classes_filename;
       return NULL;
@@ -191,8 +196,9 @@
     return image_classes.release();
   }
 
-  // Reads the class names (java.lang.Object) and returns as set of class descriptors (Ljava/lang/Object;)
-  CompilerDriver::DescriptorSet* ReadImageClassesFromZip(const std::string& zip_filename, const char* image_classes_filename) {
+  // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;)
+  CompilerDriver::DescriptorSet* ReadImageClassesFromZip(const std::string& zip_filename,
+                                                         const char* image_classes_filename) {
     UniquePtr<ZipArchive> zip_archive(ZipArchive::Open(zip_filename));
     if (zip_archive.get() == NULL) {
       LOG(ERROR) << "Failed to open zip file " << zip_filename;
@@ -224,7 +230,7 @@
                                       bool image,
                                       UniquePtr<CompilerDriver::DescriptorSet>& image_classes,
                                       bool dump_stats,
-                                      bool dump_timings)
+                                      TimingLogger& timings)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     // SirtRef and ClassLoader creation needs to come after Runtime::Create
     jobject class_loader = NULL;
@@ -248,8 +254,7 @@
                                                         image,
                                                         image_classes.release(),
                                                         thread_count_,
-                                                        dump_stats,
-                                                        dump_timings));
+                                                        dump_stats));
 
     if (compiler_backend_ == kPortable) {
       driver->SetBitcodeFileName(bitcode_filename);
@@ -258,7 +263,8 @@
 
     Thread::Current()->TransitionFromRunnableToSuspended(kNative);
 
-    driver->CompileAll(class_loader, dex_files);
+    timings.AddSplit("dex2oat Setup");
+    driver->CompileAll(class_loader, dex_files, timings);
 
     Thread::Current()->TransitionFromSuspendedToRunnable();
 
@@ -294,11 +300,13 @@
       LOG(ERROR) << "Failed to create oat file " << oat_file->GetPath();
       return NULL;
     }
+    timings.AddSplit("dex2oat OatWriter");
 
     if (!driver->WriteElf(android_root, is_host, dex_files, oat_contents, oat_file)) {
       LOG(ERROR) << "Failed to write ELF file " << oat_file->GetPath();
       return NULL;
     }
+    timings.AddSplit("dex2oat ElfWriter");
 
     return driver.release();
   }
@@ -333,7 +341,9 @@
   }
 
  private:
-  explicit Dex2Oat(Runtime* runtime, CompilerBackend compiler_backend, InstructionSet instruction_set,
+  explicit Dex2Oat(Runtime* runtime,
+                   CompilerBackend compiler_backend,
+                   InstructionSet instruction_set,
                    size_t thread_count)
       : compiler_backend_(compiler_backend),
         instruction_set_(instruction_set),
@@ -365,7 +375,8 @@
 
   // Appends to dex_files any elements of class_path that it doesn't already
   // contain. This will open those dex files as necessary.
-  static void OpenClassPathFiles(const std::string& class_path, std::vector<const DexFile*>& dex_files) {
+  static void OpenClassPathFiles(const std::string& class_path,
+                                 std::vector<const DexFile*>& dex_files) {
     std::vector<std::string> parsed;
     Split(class_path, ':', parsed);
     // Take Locks::mutator_lock_ so that lock ordering on the ClassLinker::dex_lock_ is maintained.
@@ -384,7 +395,8 @@
   }
 
   // Returns true if dex_files has a dex with the named location.
-  static bool DexFilesContains(const std::vector<const DexFile*>& dex_files, const std::string& location) {
+  static bool DexFilesContains(const std::vector<const DexFile*>& dex_files,
+                               const std::string& location) {
     for (size_t i = 0; i < dex_files.size(); ++i) {
       if (dex_files[i]->GetLocation() == location) {
         return true;
@@ -564,6 +576,8 @@
 const unsigned int WatchDog::kWatchDogTimeoutSeconds;
 
 static int dex2oat(int argc, char** argv) {
+  TimingLogger timings("compiler", false);
+
   InitLogging(argv);
 
   // Skip over argv[0].
@@ -937,7 +951,7 @@
                                                                   image,
                                                                   image_classes,
                                                                   dump_stats,
-                                                                  dump_timings));
+                                                                  timings));
 
   if (compiler.get() == NULL) {
     LOG(ERROR) << "Failed to create oat file: " << oat_location;
@@ -959,7 +973,7 @@
   // | alloc spaces |
   // +--------------+
   //
-  // There are several constraints on the loading of the imag and boot.oat.
+  // There are several constraints on the loading of the image and boot.oat.
   //
   // 1. The image is expected to be loaded at an absolute address and
   // contains Objects with absolute pointers within the image.
@@ -977,7 +991,7 @@
   //
   // 1. We have already created that oat file above with
   // CreateOatFile. Originally this was just our own proprietary file
-  // but now it is contained within an ELF dynamic object (aka .so
+  // but now it is contained within an ELF dynamic object (aka an .so
   // file). The Compiler returned by CreateOatFile provides
   // PatchInformation for references to oat code and Methods that need
   // to be update once we know where the oat file will be located
@@ -1003,6 +1017,7 @@
                                                            oat_unstripped,
                                                            oat_location,
                                                            *compiler.get());
+    timings.AddSplit("dex2oat ImageWriter");
     Thread::Current()->TransitionFromSuspendedToRunnable();
     LOG(INFO) << "Image written successfully: " << image_filename;
     if (!image_creation_success) {
@@ -1011,9 +1026,13 @@
   }
 
   if (is_host) {
+    if (dump_timings && timings.GetTotalNs() > MsToNs(1000)) {
+      LOG(INFO) << Dumpable<TimingLogger>(timings);
+    }
     return EXIT_SUCCESS;
   }
 
+#if ART_USE_PORTABLE_COMPILER  // We currently only generate symbols on Portable
   // If we don't want to strip in place, copy from unstripped location to stripped location.
   // We need to strip after image creation because FixupElf needs to use .strtab.
   if (oat_unstripped != oat_stripped) {
@@ -1031,6 +1050,7 @@
       CHECK(write_ok);
     }
     oat_file.reset(out.release());
+    timings.AddSplit("dex2oat OatFile copy");
     LOG(INFO) << "Oat file copied successfully (stripped): " << oat_stripped;
   }
 
@@ -1038,12 +1058,19 @@
   off_t seek_actual = lseek(oat_file->Fd(), 0, SEEK_SET);
   CHECK_EQ(0, seek_actual);
   ElfStripper::Strip(oat_file.get());
+  timings.AddSplit("dex2oat ElfStripper");
 
   // We wrote the oat file successfully, and want to keep it.
   LOG(INFO) << "Oat file written successfully (stripped): " << oat_location;
+#endif // ART_USE_PORTABLE_COMPILER
+
+  if (dump_timings && timings.GetTotalNs() > MsToNs(1000)) {
+    LOG(INFO) << Dumpable<TimingLogger>(timings);
+  }
   return EXIT_SUCCESS;
 }
 
+
 } // namespace art
 
 int main(int argc, char** argv) {
diff --git a/runtime/common_test.h b/runtime/common_test.h
index 13626a5..09ad7fd 100644
--- a/runtime/common_test.h
+++ b/runtime/common_test.h
@@ -349,7 +349,7 @@
       class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
       compiler_driver_.reset(new CompilerDriver(compiler_backend, instruction_set,
                                                 true, new CompilerDriver::DescriptorSet,
-                                                2, true, true));
+                                                2, true));
     }
     // We typically don't generate an image in unit tests, disable this optimization by default.
     compiler_driver_->SetSupportBootImageFixup(false);
@@ -473,7 +473,8 @@
 
   void CompileMethod(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     CHECK(method != NULL);
-    compiler_driver_->CompileOne(method);
+    TimingLogger timings("CommonTest::CompileMethod", false);
+    compiler_driver_->CompileOne(method, timings);
     MakeExecutable(method);
   }
 
diff --git a/runtime/image_test.cc b/runtime/image_test.cc
index ee50118..11218ad 100644
--- a/runtime/image_test.cc
+++ b/runtime/image_test.cc
@@ -45,7 +45,8 @@
     {
       jobject class_loader = NULL;
       ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-      compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath());
+      TimingLogger timings("ImageTest::WriteRead", false);
+      compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath(), timings);
 
       ScopedObjectAccess soa(Thread::Current());
       VectorOutputStream output_stream(tmp_elf.GetFilename(), oat_contents);
diff --git a/runtime/oat_test.cc b/runtime/oat_test.cc
index 7f24564..9a6bc19 100644
--- a/runtime/oat_test.cc
+++ b/runtime/oat_test.cc
@@ -74,10 +74,11 @@
 #else
   CompilerBackend compiler_backend = kQuick;
 #endif
-  compiler_driver_.reset(new CompilerDriver(compiler_backend, kThumb2, false, NULL, 2, true, true));
+  compiler_driver_.reset(new CompilerDriver(compiler_backend, kThumb2, false, NULL, 2, true));
   jobject class_loader = NULL;
   if (compile) {
-    compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath());
+    TimingLogger timings("OatTest::WriteRead", false);
+    compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath(), timings);
   }
 
   ScopedObjectAccess soa(Thread::Current());
@@ -99,7 +100,8 @@
   ASSERT_TRUE(success_elf);
 
   if (compile) {  // OatWriter strips the code, regenerate to compare
-    compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath());
+    TimingLogger timings("CommonTest::WriteRead", false);
+    compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath(), timings);
   }
   UniquePtr<OatFile> oat_file(OatFile::Open(tmp.GetFilename(), tmp.GetFilename(), NULL, false));
   ASSERT_TRUE(oat_file.get() != NULL);