Add -verbose:startup

Change-Id: I1ef70c2a9e559893541bbbf381b6893808602555
diff --git a/src/class_linker.cc b/src/class_linker.cc
index becd6d5..2aa9d7d 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -160,6 +160,11 @@
 
 void ClassLinker::Init(const std::vector<const DexFile*>& boot_class_path,
                        const std::vector<const DexFile*>& class_path) {
+  const Runtime* runtime = Runtime::Current();
+  if (runtime->IsVerboseStartup()) {
+    LOG(INFO) << "ClassLinker::InitFrom entering";
+  }
+
   CHECK(!init_done_);
 
   // java_lang_Class comes first, its needed for AllocClass
@@ -399,9 +404,17 @@
   StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
 
   FinishInit();
+
+  if (runtime->IsVerboseStartup()) {
+    LOG(INFO) << "ClassLinker::InitFrom exiting";
+  }
 }
 
 void ClassLinker::FinishInit() {
+  const Runtime* runtime = Runtime::Current();
+  if (runtime->IsVerboseStartup()) {
+    LOG(INFO) << "ClassLinker::FinishInit entering";
+  }
 
   // Let the heap know some key offsets into java.lang.ref instances
   // NB we hard code the field indexes here rather than using FindInstanceField
@@ -450,6 +463,10 @@
   // disable the slow paths in FindClass and CreatePrimitiveClass now
   // that Object, Class, and Object[] are setup
   init_done_ = true;
+
+  if (runtime->IsVerboseStartup()) {
+    LOG(INFO) << "ClassLinker::FinishInit exiting";
+  }
 }
 
 void ClassLinker::RunRootClinits() {
@@ -477,6 +494,10 @@
 
 void ClassLinker::InitFromImage(const std::vector<const DexFile*>& boot_class_path,
                                 const std::vector<const DexFile*>& class_path) {
+  const Runtime* runtime = Runtime::Current();
+  if (runtime->IsVerboseStartup()) {
+    LOG(INFO) << "ClassLinker::InitFromImage entering";
+  }
   CHECK(!init_done_);
 
   HeapBitmap* heap_bitmap = Heap::GetLiveBits();
@@ -548,6 +569,10 @@
   StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
 
   FinishInit();
+
+  if (runtime->IsVerboseStartup()) {
+    LOG(INFO) << "ClassLinker::InitFromImage exiting";
+  }
 }
 
 void ClassLinker::InitFromImageCallback(Object* obj, void* arg) {
diff --git a/src/heap.cc b/src/heap.cc
index 5e96a79..1b3daad 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -58,13 +58,18 @@
 void Heap::Init(size_t initial_size, size_t maximum_size,
                 const char* boot_image_file_name,
                 std::vector<const char*>& image_file_names) {
+  const Runtime* runtime = Runtime::Current();
+  if (runtime->IsVerboseStartup()) {
+    LOG(INFO) << "Heap::Init entering";
+  }
+
   Space* boot_space;
   byte* requested_base;
   if (boot_image_file_name == NULL) {
     boot_space = NULL;
     requested_base = NULL;
   } else {
-    boot_space = Space::Create(boot_image_file_name);
+    boot_space = Space::CreateFromImage(boot_image_file_name);
     if (boot_space == NULL) {
       LOG(FATAL) << "Failed to create space from " << boot_image_file_name;
     }
@@ -74,7 +79,7 @@
 
   std::vector<Space*> image_spaces;
   for (size_t i = 0; i < image_file_names.size(); i++) {
-    Space* space = Space::Create(image_file_names[i]);
+    Space* space = Space::CreateFromImage(image_file_names[i]);
     if (space == NULL) {
       LOG(FATAL) << "Failed to create space from " << image_file_names[i];
     }
@@ -134,6 +139,10 @@
   // but we can create the heap lock now. We don't create it earlier to
   // make it clear that you can't use locks during heap initialization.
   lock_ = new Mutex("Heap lock");
+
+  if (runtime->IsVerboseStartup()) {
+    LOG(INFO) << "Heap::Init exiting";
+  }
 }
 
 void Heap::Destroy() {
@@ -277,6 +286,10 @@
 }
 
 void Heap::RecordImageAllocations(Space* space) {
+  const Runtime* runtime = Runtime::Current();
+  if (runtime->IsVerboseStartup()) {
+    LOG(INFO) << "Heap::RecordImageAllocations entering";
+  }
   DCHECK(!Runtime::Current()->IsStarted());
   CHECK(space != NULL);
   CHECK(live_bitmap_ != NULL);
@@ -287,6 +300,9 @@
     live_bitmap_->Set(obj);
     current += RoundUp(obj->SizeOf(), kObjectAlignment);
   }
+  if (runtime->IsVerboseStartup()) {
+    LOG(INFO) << "Heap::RecordImageAllocations exiting";
+  }
 }
 
 Object* Heap::AllocateLocked(size_t size) {
diff --git a/src/runtime.cc b/src/runtime.cc
index eb5e498..a6977b2 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -24,7 +24,8 @@
 Runtime* Runtime::instance_ = NULL;
 
 Runtime::Runtime()
-    : default_stack_size_(Thread::kDefaultStackSize),
+    : verbose_startup_(false),
+      default_stack_size_(Thread::kDefaultStackSize),
       thread_list_(NULL),
       intern_table_(NULL),
       class_linker_(NULL),
@@ -359,6 +360,9 @@
 }
 
 void Runtime::Start() {
+  if (IsVerboseStartup()) {
+    LOG(INFO) << "Runtime::Start entering";
+  }
   InitNativeMethods();
 
   Thread::FinishStartup();
@@ -371,6 +375,10 @@
   started_ = true;
 
   StartDaemonThreads();
+
+  if (IsVerboseStartup()) {
+    LOG(INFO) << "Runtime::Start exiting";
+  }
 }
 
 void Runtime::StartDaemonThreads() {
@@ -397,6 +405,10 @@
     LOG(WARNING) << "Failed to parse options";
     return false;
   }
+  verbose_startup_ = options->IsVerbose("startup");
+  if (IsVerboseStartup()) {
+    LOG(INFO) << "Runtime::Init -verbose:startup enabled";
+  }
 
   boot_class_path_ = options->boot_class_path_string_;
   class_path_ = options->class_path_string_;
@@ -429,10 +441,16 @@
                                       intern_table_,
                                       Heap::GetBootSpace());
 
+  if (IsVerboseStartup()) {
+    LOG(INFO) << "Runtime::Init exiting";
+  }
   return true;
 }
 
 void Runtime::InitNativeMethods() {
+  if (IsVerboseStartup()) {
+    LOG(INFO) << "Runtime::InitNativeMethods entering";
+  }
   Thread* self = Thread::Current();
   JNIEnv* env = self->GetJniEnv();
 
@@ -450,6 +468,9 @@
   // Most JNI libraries can just use System.loadLibrary, but libcore can't because it's
   // the library that implements System.loadLibrary!
   LoadJniLibrary(instance_->GetJavaVM(), "javacore");
+  if (IsVerboseStartup()) {
+    LOG(INFO) << "Runtime::InitNativeMethods exiting";
+  }
 }
 
 void Runtime::RegisterRuntimeNativeMethods(JNIEnv* env) {
diff --git a/src/runtime.h b/src/runtime.h
index a6916ac..ca0496c 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -72,6 +72,10 @@
   // Creates and initializes a new runtime.
   static Runtime* Create(const Options& options, bool ignore_unrecognized);
 
+  bool IsVerboseStartup() const {
+    return verbose_startup_;
+  }
+
   // Starts a runtime, which may cause threads to be started and code to run.
   void Start();
 
@@ -195,6 +199,8 @@
   void RegisterRuntimeNativeMethods(JNIEnv*);
   void StartDaemonThreads();
 
+  bool verbose_startup_;
+
   std::string boot_class_path_;
   std::string class_path_;
   std::vector<std::string> properties_;
diff --git a/src/space.cc b/src/space.cc
index 57983d5..9efe599 100644
--- a/src/space.cc
+++ b/src/space.cc
@@ -24,10 +24,10 @@
   }
 }
 
-Space* Space::Create(const char* image_file_name) {
+Space* Space::CreateFromImage(const char* image_file_name) {
   CHECK(image_file_name != NULL);
   UniquePtr<Space> space(new Space());
-  bool success = space->Init(image_file_name);
+  bool success = space->InitFromImage(image_file_name);
   if (!success) {
     return NULL;
   } else {
@@ -58,6 +58,13 @@
 }
 
 bool Space::Init(size_t initial_size, size_t maximum_size, byte* requested_base) {
+  const Runtime* runtime = Runtime::Current();
+  if (runtime->IsVerboseStartup()) {
+    LOG(INFO) << "Space::Init entering"
+              << " initial_size=" << initial_size
+              << " maximum_size=" << maximum_size
+              << " requested_base=" << reinterpret_cast<void*>(requested_base);
+  }
   if (!(initial_size <= maximum_size)) {
     LOG(WARNING) << "Failed to create space with initial size > maximum size ("
                  << initial_size << ">" << maximum_size << ")";
@@ -77,6 +84,9 @@
     LOG(WARNING) << "Failed to create mspace for space";
     return false;
   }
+  if (runtime->IsVerboseStartup()) {
+    LOG(INFO) << "Space::Init exiting";
+  }
   return true;
 }
 
@@ -87,7 +97,12 @@
 }
 
 
-bool Space::Init(const char* image_file_name) {
+bool Space::InitFromImage(const char* image_file_name) {
+  const Runtime* runtime = Runtime::Current();
+  if (runtime->IsVerboseStartup()) {
+    LOG(INFO) << "Space::InitFromImage entering"
+              << " image_file_name=" << image_file_name;
+  }
   UniquePtr<File> file(OS::OpenFile(image_file_name, false));
   if (file.get() == NULL) {
     LOG(WARNING) << "Failed to open " << image_file_name;
@@ -121,6 +136,9 @@
   Runtime::Current()->SetCalleeSaveMethod(down_cast<Method*>(callee_save_method));
 
   Init(map.release());
+  if (runtime->IsVerboseStartup()) {
+    LOG(INFO) << "Space::InitFromImage exiting";
+  }
   return true;
 }
 
diff --git a/src/space.h b/src/space.h
index e95d2b0..1536c27 100644
--- a/src/space.h
+++ b/src/space.h
@@ -23,7 +23,7 @@
   static Space* Create(size_t initial_size, size_t maximum_size, byte* requested_base);
 
   // create a Space from an image file. cannot be used for future allocation or collected.
-  static Space* Create(const char* image);
+  static Space* CreateFromImage(const char* image);
 
   ~Space();
 
@@ -78,7 +78,7 @@
   void Init(MemMap* map);
 
   // Initializes the space from an image file
-  bool Init(const char* image_file_name);
+  bool InitFromImage(const char* image_file_name);
 
   void* CreateMallocSpace(void* base, size_t initial_size, size_t maximum_size);