am 379e2f59: Clean up unnecessary files after build-only. Bug: 9482191

* commit '379e2f5996b38d9f67b9c334c232cb315a5390ad':
  Clean up unnecessary files after build-only. Bug: 9482191
diff --git a/compiler/dex/portable/mir_to_gbc.cc b/compiler/dex/portable/mir_to_gbc.cc
index 90cec75..7831cf6 100644
--- a/compiler/dex/portable/mir_to_gbc.cc
+++ b/compiler/dex/portable/mir_to_gbc.cc
@@ -1972,7 +1972,7 @@
 
     ::llvm::OwningPtr< ::llvm::tool_output_file> out_file(
         new ::llvm::tool_output_file(fname.c_str(), errmsg,
-                                   ::llvm::sys::fs::F_Binary));
+                                   ::llvm::raw_fd_ostream::F_Binary));
 
     if (!errmsg.empty()) {
       LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 7b83e40..bf541c6 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -582,10 +582,11 @@
 
 bool CompilerDriver::IsImageClass(const char* descriptor) const {
   DCHECK(descriptor != NULL);
-  if (image_classes_.get() == NULL) {
+  if (!IsImage()) {
     return true;
+  } else {
+    return image_classes_->find(descriptor) != image_classes_->end();
   }
-  return image_classes_->find(descriptor) != image_classes_->end();
 }
 
 static void ResolveExceptionsForMethod(MethodHelper* mh,
@@ -655,7 +656,7 @@
 // Make a list of descriptors for classes to include in the image
 void CompilerDriver::LoadImageClasses(base::TimingLogger& timings)
       LOCKS_EXCLUDED(Locks::mutator_lock_) {
-  if (image_classes_.get() == NULL) {
+  if (!IsImage()) {
     return;
   }
 
@@ -669,7 +670,7 @@
     SirtRef<mirror::Class> klass(self, class_linker->FindSystemClass(descriptor.c_str()));
     if (klass.get() == NULL) {
       image_classes_->erase(it++);
-      LOG(WARNING) << "Failed to find class " << descriptor;
+      VLOG(compiler) << "Failed to find class " << descriptor;
       Thread::Current()->ClearException();
     } else {
       ++it;
@@ -742,21 +743,19 @@
 }
 
 void CompilerDriver::UpdateImageClasses(base::TimingLogger& timings) {
-  if (image_classes_.get() == NULL) {
-    return;
+  if (IsImage()) {
+    timings.NewSplit("UpdateImageClasses");
+
+    // Update image_classes_ with classes for objects created by <clinit> methods.
+    Thread* self = Thread::Current();
+    const char* old_cause = self->StartAssertNoThreadSuspension("ImageWriter");
+    gc::Heap* heap = Runtime::Current()->GetHeap();
+    // TODO: Image spaces only?
+    WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
+    heap->FlushAllocStack();
+    heap->GetLiveBitmap()->Walk(FindClinitImageClassesCallback, this);
+    self->EndAssertNoThreadSuspension(old_cause);
   }
-
-  timings.NewSplit("UpdateImageClasses");
-
-  // Update image_classes_ with classes for objects created by <clinit> methods.
-  Thread* self = Thread::Current();
-  const char* old_cause = self->StartAssertNoThreadSuspension("ImageWriter");
-  gc::Heap* heap = Runtime::Current()->GetHeap();
-  // TODO: Image spaces only?
-  WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
-  heap->FlushAllocStack();
-  heap->GetLiveBitmap()->Walk(FindClinitImageClassesCallback, this);
-  self->EndAssertNoThreadSuspension(old_cause);
 }
 
 void CompilerDriver::RecordClassStatus(ClassReference ref, CompiledClass* compiled_class) {
@@ -1417,30 +1416,27 @@
 // classes found in the boot classpath. Since at runtime we will
 // select the class from the boot classpath, do not attempt to resolve
 // or compile it now.
-static bool SkipClass(mirror::ClassLoader* class_loader,
-                      const DexFile& dex_file,
-                      const DexFile::ClassDef& class_def)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+static bool SkipClass(ClassLinker* class_linker, jobject class_loader, const DexFile& dex_file,
+                      const DexFile::ClassDef& class_def) {
   if (class_loader == NULL) {
     return false;
   }
   const char* descriptor = dex_file.GetClassDescriptor(class_def);
-  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-  mirror::Class* klass = class_linker->FindClass(descriptor, NULL);
-  if (klass == NULL) {
-    Thread* self = Thread::Current();
-    CHECK(self->IsExceptionPending());
-    self->ClearException();
-    return false;
-  }
-  return true;
+  return class_linker->IsInBootClassPath(descriptor);
 }
 
-static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manager, size_t class_def_index)
+static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manager,
+                                         size_t class_def_index)
     LOCKS_EXCLUDED(Locks::mutator_lock_) {
-  ScopedObjectAccess soa(Thread::Current());
-  mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader());
+  Thread* self = Thread::Current();
+  jobject jclass_loader = manager->GetClassLoader();
   const DexFile& dex_file = *manager->GetDexFile();
+  ClassLinker* class_linker = manager->GetClassLinker();
+
+  // If an instance field is final then we need to have a barrier on the return, static final
+  // fields are assigned within the lock held for class initialization. Conservatively assume
+  // constructor barriers are always required.
+  bool requires_constructor_barrier = true;
 
   // Method and Field are the worst. We can't resolve without either
   // context from the code use (to disambiguate virtual vs direct
@@ -1450,72 +1446,89 @@
   // definitions, since many of them many never be referenced by
   // generated code.
   const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
-  if (SkipClass(class_loader, dex_file, class_def)) {
-    return;
-  }
+  if (!SkipClass(class_linker, jclass_loader, dex_file, class_def)) {
+    // Note the class_data pointer advances through the headers,
+    // static fields, instance fields, direct methods, and virtual
+    // methods.
+    const byte* class_data = dex_file.GetClassData(class_def);
+    if (class_data == NULL) {
+      // Empty class such as a marker interface.
+      requires_constructor_barrier = false;
+    } else {
+      ScopedObjectAccess soa(self);
+      mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(jclass_loader);
+      mirror::DexCache* dex_cache = class_linker->FindDexCache(dex_file);
 
-  // Note the class_data pointer advances through the headers,
-  // static fields, instance fields, direct methods, and virtual
-  // methods.
-  const byte* class_data = dex_file.GetClassData(class_def);
-  if (class_data == NULL) {
-    // empty class such as a marker interface
-    return;
-  }
-  Thread* self = Thread::Current();
-  ClassLinker* class_linker = manager->GetClassLinker();
-  mirror::DexCache* dex_cache = class_linker->FindDexCache(dex_file);
-  ClassDataItemIterator it(dex_file, class_data);
-  while (it.HasNextStaticField()) {
-    mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
-                                                      class_loader, true);
-    if (field == NULL) {
-      CHECK(self->IsExceptionPending());
-      self->ClearException();
-    }
-    it.Next();
-  }
-  // If an instance field is final then we need to have a barrier on the return, static final
-  // fields are assigned within the lock held for class initialization.
-  bool requires_constructor_barrier = false;
-  while (it.HasNextInstanceField()) {
-    if ((it.GetMemberAccessFlags() & kAccFinal) != 0) {
-      requires_constructor_barrier = true;
-    }
+      // Resolve the class.
+      mirror::Class* klass = class_linker->ResolveType(dex_file, class_def.class_idx_, dex_cache,
+                                                       class_loader);
 
-    mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
-                                                      class_loader, false);
-    if (field == NULL) {
-      CHECK(self->IsExceptionPending());
-      self->ClearException();
+      bool resolve_fields_and_methods;
+      if (klass == NULL) {
+        // Class couldn't be resolved, for example, super-class is in a different dex file. Don't
+        // attempt to resolve methods and fields when there is no declaring class.
+        CHECK(soa.Self()->IsExceptionPending());
+        Thread::Current()->ClearException();
+        resolve_fields_and_methods = false;
+      } else {
+        resolve_fields_and_methods = manager->GetCompiler()->IsImage();
+      }
+      ClassDataItemIterator it(dex_file, class_data);
+      while (it.HasNextStaticField()) {
+        if (resolve_fields_and_methods) {
+          mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
+                                                               dex_cache, class_loader, true);
+          if (field == NULL) {
+            CHECK(soa.Self()->IsExceptionPending());
+            soa.Self()->ClearException();
+          }
+        }
+        it.Next();
+      }
+      // We require a constructor barrier if there are final instance fields.
+      requires_constructor_barrier = false;
+      while (it.HasNextInstanceField()) {
+        if ((it.GetMemberAccessFlags() & kAccFinal) != 0) {
+          requires_constructor_barrier = true;
+        }
+        if (resolve_fields_and_methods) {
+          mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
+                                                               dex_cache, class_loader, false);
+          if (field == NULL) {
+            CHECK(soa.Self()->IsExceptionPending());
+            soa.Self()->ClearException();
+          }
+        }
+        it.Next();
+      }
+      if (resolve_fields_and_methods) {
+        while (it.HasNextDirectMethod()) {
+          mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
+                                                                  dex_cache, class_loader, NULL,
+                                                                  it.GetMethodInvokeType(class_def));
+          if (method == NULL) {
+            CHECK(soa.Self()->IsExceptionPending());
+            soa.Self()->ClearException();
+          }
+          it.Next();
+        }
+        while (it.HasNextVirtualMethod()) {
+          mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
+                                                                  dex_cache, class_loader, NULL,
+                                                                  it.GetMethodInvokeType(class_def));
+          if (method == NULL) {
+            CHECK(soa.Self()->IsExceptionPending());
+            soa.Self()->ClearException();
+          }
+          it.Next();
+        }
+        DCHECK(!it.HasNext());
+      }
     }
-    it.Next();
   }
   if (requires_constructor_barrier) {
-    manager->GetCompiler()->AddRequiresConstructorBarrier(soa.Self(), manager->GetDexFile(),
-                                                          class_def_index);
+    manager->GetCompiler()->AddRequiresConstructorBarrier(self, &dex_file, class_def_index);
   }
-  while (it.HasNextDirectMethod()) {
-    mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
-                                                                 dex_cache, class_loader, NULL,
-                                                                 it.GetMethodInvokeType(class_def));
-    if (method == NULL) {
-      CHECK(self->IsExceptionPending());
-      self->ClearException();
-    }
-    it.Next();
-  }
-  while (it.HasNextVirtualMethod()) {
-    mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
-                                                                 dex_cache, class_loader, NULL,
-                                                                 it.GetMethodInvokeType(class_def));
-    if (method == NULL) {
-      CHECK(self->IsExceptionPending());
-      self->ClearException();
-    }
-    it.Next();
-  }
-  DCHECK(!it.HasNext());
 }
 
 static void ResolveType(const ParallelCompilationManager* manager, size_t type_idx)
@@ -1541,10 +1554,16 @@
   // TODO: we could resolve strings here, although the string table is largely filled with class
   //       and method names.
 
-  timings.NewSplit(strdup(("Resolve " + dex_file.GetLocation() + " Types").c_str()));
   ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, thread_pool);
-  context.ForAll(0, dex_file.NumTypeIds(), ResolveType, thread_count_);
+  if (IsImage()) {
+    // For images we resolve all types, such as array, whereas for applications just those with
+    // classdefs are resolved by ResolveClassFieldsAndMethods.
+    // TODO: strdup memory leak.
+    timings.NewSplit(strdup(("Resolve " + dex_file.GetLocation() + " Types").c_str()));
+    context.ForAll(0, dex_file.NumTypeIds(), ResolveType, thread_count_);
+  }
 
+  // TODO: strdup memory leak.
   timings.NewSplit(strdup(("Resolve " + dex_file.GetLocation() + " MethodsAndFields").c_str()));
   context.ForAll(0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_);
 }
@@ -1567,7 +1586,8 @@
   mirror::Class* klass =
       manager->GetClassLinker()->FindClass(descriptor,
                                            soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader()));
-  if (klass == NULL) {    CHECK(soa.Self()->IsExceptionPending());
+  if (klass == NULL) {
+    CHECK(soa.Self()->IsExceptionPending());
     soa.Self()->ClearException();
 
     /*
@@ -1587,25 +1607,25 @@
                  << PrettyDescriptor(manager->GetDexFile()->GetClassDescriptor(class_def))
                  << " because: " << error_msg;
     }
-    return;
+  } else {
+    CHECK(klass->IsResolved()) << PrettyClass(klass);
+    manager->GetClassLinker()->VerifyClass(klass);
+
+    if (klass->IsErroneous()) {
+      // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
+      CHECK(soa.Self()->IsExceptionPending());
+      soa.Self()->ClearException();
+    }
+
+    CHECK(klass->IsCompileTimeVerified() || klass->IsErroneous())
+        << PrettyDescriptor(klass) << ": state=" << klass->GetStatus();
   }
-  CHECK(klass->IsResolved()) << PrettyClass(klass);
-  manager->GetClassLinker()->VerifyClass(klass);
-
-  if (klass->IsErroneous()) {
-    // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
-    CHECK(soa.Self()->IsExceptionPending());
-    soa.Self()->ClearException();
-  }
-
-
-  CHECK(klass->IsCompileTimeVerified() || klass->IsErroneous())
-      << PrettyDescriptor(klass) << ": state=" << klass->GetStatus();
   soa.Self()->AssertNoPendingException();
 }
 
 void CompilerDriver::VerifyDexFile(jobject class_loader, const DexFile& dex_file,
                                    ThreadPool& thread_pool, base::TimingLogger& timings) {
+  // TODO: strdup memory leak.
   timings.NewSplit(strdup(("Verify " + dex_file.GetLocation()).c_str()));
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, thread_pool);
@@ -2033,23 +2053,20 @@
   mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader());
   const char* descriptor = manager->GetDexFile()->GetClassDescriptor(class_def);
   mirror::Class* klass = manager->GetClassLinker()->FindClass(descriptor, class_loader);
-  bool compiling_boot = Runtime::Current()->GetHeap()->GetContinuousSpaces().size() == 1;
-  bool can_init_static_fields = compiling_boot &&
-      manager->GetCompiler()->IsImageClass(descriptor);
   if (klass != NULL) {
-    // We don't want class initialization occurring on multiple threads due to deadlock problems.
-    // For example, a parent class is initialized (holding its lock) that refers to a sub-class
-    // in its static/class initializer causing it to try to acquire the sub-class' lock. While
-    // on a second thread the sub-class is initialized (holding its lock) after first initializing
-    // its parents, whose locks are acquired. This leads to a parent-to-child and a child-to-parent
-    // lock ordering and consequent potential deadlock.
-    // We need to use an ObjectLock due to potential suspension in the interpreting code. Rather
-    // than use a special Object for the purpose we use the Class of java.lang.Class.
-    ObjectLock lock1(soa.Self(), klass->GetClass());
-    // The lock required to initialize the class.
-    ObjectLock lock2(soa.Self(), klass);
     // Only try to initialize classes that were successfully verified.
     if (klass->IsVerified()) {
+      // We don't want class initialization occurring on multiple threads due to deadlock problems.
+      // For example, a parent class is initialized (holding its lock) that refers to a sub-class
+      // in its static/class initializer causing it to try to acquire the sub-class' lock. While
+      // on a second thread the sub-class is initialized (holding its lock) after first initializing
+      // its parents, whose locks are acquired. This leads to a parent-to-child and a child-to-parent
+      // lock ordering and consequent potential deadlock.
+      // We need to use an ObjectLock due to potential suspension in the interpreting code. Rather
+      // than use a special Object for the purpose we use the Class of java.lang.Class.
+      ObjectLock lock(soa.Self(), klass->GetClass());
+      bool can_init_static_fields = manager->GetCompiler()->IsImage() &&
+          manager->GetCompiler()->IsImageClass(descriptor);
       manager->GetClassLinker()->EnsureInitialized(klass, false, can_init_static_fields);
       if (soa.Self()->IsExceptionPending()) {
         soa.Self()->GetException(NULL)->Dump();
@@ -2070,6 +2087,7 @@
             VLOG(compiler) << "Initializing: " << descriptor;
             if (StringPiece(descriptor) == "Ljava/lang/Void;") {
               // Hand initialize j.l.Void to avoid Dex file operations in un-started runtime.
+              ObjectLock lock(soa.Self(), klass);
               mirror::ObjectArray<mirror::ArtField>* fields = klass->GetSFields();
               CHECK_EQ(fields->GetLength(), 1);
               fields->Get(0)->SetObj(klass, manager->GetClassLinker()->FindPrimitiveClass('V'));
@@ -2103,11 +2121,15 @@
 
 void CompilerDriver::InitializeClasses(jobject jni_class_loader, const DexFile& dex_file,
                                        ThreadPool& thread_pool, base::TimingLogger& timings) {
+  // TODO: strdup memory leak.
   timings.NewSplit(strdup(("InitializeNoClinit " + dex_file.GetLocation()).c_str()));
 #ifndef NDEBUG
-  for (size_t i = 0; i < arraysize(class_initializer_black_list); ++i) {
-    const char* descriptor = class_initializer_black_list[i];
-    CHECK(IsValidDescriptor(descriptor)) << descriptor;
+  // Sanity check blacklist descriptors.
+  if (IsImage()) {
+    for (size_t i = 0; i < arraysize(class_initializer_black_list); ++i) {
+      const char* descriptor = class_initializer_black_list[i];
+      CHECK(IsValidDescriptor(descriptor)) << descriptor;
+    }
   }
 #endif
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
@@ -2139,12 +2161,9 @@
   jobject jclass_loader = manager->GetClassLoader();
   const DexFile& dex_file = *manager->GetDexFile();
   const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
-  {
-    ScopedObjectAccess soa(Thread::Current());
-    mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(jclass_loader);
-    if (SkipClass(class_loader, dex_file, class_def)) {
-      return;
-    }
+  ClassLinker* class_linker = manager->GetClassLinker();
+  if (SkipClass(class_linker, jclass_loader, dex_file, class_def)) {
+    return;
   }
   ClassReference ref(&dex_file, class_def_index);
   // Skip compiling classes with generic verifier failures since they will still fail at runtime
@@ -2172,6 +2191,7 @@
   while (it.HasNextInstanceField()) {
     it.Next();
   }
+  CompilerDriver* driver = manager->GetCompiler();
   // Compile direct methods
   int64_t previous_direct_method_idx = -1;
   while (it.HasNextDirectMethod()) {
@@ -2183,9 +2203,9 @@
       continue;
     }
     previous_direct_method_idx = method_idx;
-    manager->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
-                                          it.GetMethodInvokeType(class_def), class_def_index,
-                                          method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level);
+    driver->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
+                          it.GetMethodInvokeType(class_def), class_def_index,
+                          method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level);
     it.Next();
   }
   // Compile virtual methods
@@ -2199,9 +2219,9 @@
       continue;
     }
     previous_virtual_method_idx = method_idx;
-    manager->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
-                                          it.GetMethodInvokeType(class_def), class_def_index,
-                                          method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level);
+    driver->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
+                          it.GetMethodInvokeType(class_def), class_def_index,
+                          method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level);
     it.Next();
   }
   DCHECK(!it.HasNext());
@@ -2209,8 +2229,10 @@
 
 void CompilerDriver::CompileDexFile(jobject class_loader, const DexFile& dex_file,
                                     ThreadPool& thread_pool, base::TimingLogger& timings) {
+  // TODO: strdup memory leak.
   timings.NewSplit(strdup(("Compile " + dex_file.GetLocation()).c_str()));
-  ParallelCompilationManager context(NULL, class_loader, this, &dex_file, thread_pool);
+  ParallelCompilationManager context(Runtime::Current()->GetClassLinker(), class_loader, this,
+                                     &dex_file, thread_pool);
   context.ForAll(0, dex_file.NumClassDefs(), CompilerDriver::CompileClass, thread_count_);
 }
 
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 21a44ea..bcde178 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -110,6 +110,7 @@
     return compiler_backend_;
   }
 
+  // Are we compiling and creating an image file?
   bool IsImage() const {
     return image_;
   }
diff --git a/compiler/llvm/llvm_compilation_unit.cc b/compiler/llvm/llvm_compilation_unit.cc
index 139100b..aa439cc 100644
--- a/compiler/llvm/llvm_compilation_unit.cc
+++ b/compiler/llvm/llvm_compilation_unit.cc
@@ -214,6 +214,7 @@
   ::llvm::TargetOptions target_options;
   target_options.FloatABIType = ::llvm::FloatABI::Soft;
   target_options.NoFramePointerElim = true;
+  target_options.NoFramePointerElimNonLeaf = true;
   target_options.UseSoftFloat = false;
   target_options.EnableFastISel = false;
 
@@ -257,7 +258,7 @@
 
     ::llvm::OwningPtr< ::llvm::tool_output_file> out_file(
       new ::llvm::tool_output_file(bitcode_filename_.c_str(), errmsg,
-                                 ::llvm::sys::fs::F_Binary));
+                                 ::llvm::raw_fd_ostream::F_Binary));
 
 
     if (!errmsg.empty()) {
@@ -277,6 +278,7 @@
   // pm_builder.Inliner = ::llvm::createAlwaysInlinerPass();
   // pm_builder.Inliner = ::llvm::createPartialInliningPass();
   pm_builder.OptLevel = 3;
+  pm_builder.DisableSimplifyLibCalls = 1;
   pm_builder.DisableUnitAtATime = 1;
   pm_builder.populateFunctionPassManager(fpm);
   pm_builder.populateModulePassManager(pm);
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index ceb6bf6..511788b 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -137,6 +137,8 @@
   UsageError("");
   UsageError("  --host: used with Portable backend to link against host runtime libraries");
   UsageError("");
+  UsageError("  --dump-timing: display a breakdown of where time was spent");
+  UsageError("");
   UsageError("  --runtime-arg <argument>: used to specify various arguments for the runtime,");
   UsageError("      such as initial heap size, maximum heap size, and verbose output.");
   UsageError("      Use a separate --runtime-arg switch for each argument.");
@@ -607,7 +609,8 @@
 #endif
   bool is_host = false;
   bool dump_stats = kIsDebugBuild;
-  bool dump_timings = kIsDebugBuild;
+  bool dump_timing = false;
+  bool dump_slow_timing = kIsDebugBuild;
   bool watch_dog_enabled = !kIsTargetBuild;
 
 
@@ -695,6 +698,8 @@
         LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i];
       }
       runtime_args.push_back(argv[i]);
+    } else if (option == "--dump-timing") {
+      dump_timing = true;
     } else {
       Usage("unknown argument %s", option.data());
     }
@@ -825,6 +830,7 @@
     return EXIT_FAILURE;
   }
 
+  timings.StartSplit("dex2oat Setup");
   LOG(INFO) << "dex2oat: " << oat_location;
 
   Runtime::Options options;
@@ -926,7 +932,6 @@
     }
   }
 
-  timings.StartSplit("dex2oat Setup");
   UniquePtr<const CompilerDriver> compiler(dex2oat->CreateOatFile(boot_image_option,
                                                                   host_prefix.get(),
                                                                   android_root,
@@ -1012,7 +1017,7 @@
   }
 
   if (is_host) {
-    if (dump_timings && timings.GetTotalNs() > MsToNs(1000)) {
+    if (dump_timing || (dump_slow_timing && timings.GetTotalNs() > MsToNs(1000))) {
       LOG(INFO) << Dumpable<base::TimingLogger>(timings);
     }
     return EXIT_SUCCESS;
@@ -1053,7 +1058,7 @@
 
   timings.EndSplit();
 
-  if (dump_timings && timings.GetTotalNs() > MsToNs(1000)) {
+  if (dump_timing && timings.GetTotalNs() > MsToNs(1000)) {
     LOG(INFO) << Dumpable<base::TimingLogger>(timings);
   }
   return EXIT_SUCCESS;
diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h
index 297a63d..cec06cf 100644
--- a/runtime/base/mutex.h
+++ b/runtime/base/mutex.h
@@ -51,8 +51,8 @@
 
 // Record Log contention information, dumpable via SIGQUIT.
 #ifdef ART_USE_FUTEXES
-// To enable lock contention logging, flip this to true.
-const bool kLogLockContentions = false;
+// To disable lock contention logging, flip this to false.
+const bool kLogLockContentions = true;
 #else
 // Keep this false as lock contention logging is supported only with
 // futex.
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index d0b8bbd..0110b36 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1290,6 +1290,11 @@
   return klass;
 }
 
+bool ClassLinker::IsInBootClassPath(const char* descriptor) {
+  DexFile::ClassPathEntry pair = DexFile::FindInClassPath(descriptor, boot_class_path_);
+  return pair.second != NULL;
+}
+
 mirror::Class* ClassLinker::FindSystemClass(const char* descriptor) {
   return FindClass(descriptor, NULL);
 }
@@ -1320,18 +1325,17 @@
     }
 
   } else if (Runtime::Current()->UseCompileTimeClassPath()) {
-    // first try the boot class path
-    mirror::Class* system_class = FindSystemClass(descriptor);
-    if (system_class != NULL) {
+    // First try the boot class path, we check the descriptor first to avoid an unnecessary
+    // throw of a NoClassDefFoundError.
+    if (IsInBootClassPath(descriptor)) {
+      mirror::Class* system_class = FindSystemClass(descriptor);
+      CHECK(system_class != NULL);
       return system_class;
     }
-    CHECK(self->IsExceptionPending());
-    self->ClearException();
-
-    // next try the compile time class path
+    // Next try the compile time class path.
     const std::vector<const DexFile*>* class_path;
     {
-      ScopedObjectAccessUnchecked soa(Thread::Current());
+      ScopedObjectAccessUnchecked soa(self);
       ScopedLocalRef<jobject> jclass_loader(soa.Env(), soa.AddLocalReference<jobject>(class_loader));
       class_path = &Runtime::Current()->GetCompileTimeClassPath(jclass_loader.get());
     }
@@ -2311,8 +2315,9 @@
   mirror::Class::Status oat_file_class_status(mirror::Class::kStatusNotReady);
   bool preverified = VerifyClassUsingOatFile(dex_file, klass, oat_file_class_status);
   if (oat_file_class_status == mirror::Class::kStatusError) {
-    LOG(WARNING) << "Skipping runtime verification of erroneous class " << PrettyDescriptor(klass)
-                 << " in " << klass->GetDexCache()->GetLocation()->ToModifiedUtf8();
+    VLOG(class_linker) << "Skipping runtime verification of erroneous class "
+        << PrettyDescriptor(klass) << " in "
+        << klass->GetDexCache()->GetLocation()->ToModifiedUtf8();
     ThrowVerifyError(klass, "Rejecting class %s because it failed compile-time verification",
                      PrettyDescriptor(klass).c_str());
     klass->SetStatus(mirror::Class::kStatusError);
@@ -2326,7 +2331,7 @@
   }
   if (preverified || verifier_failure != verifier::MethodVerifier::kHardFailure) {
     if (!preverified && verifier_failure != verifier::MethodVerifier::kNoFailure) {
-      LOG(WARNING) << "Soft verification failure in class " << PrettyDescriptor(klass)
+      VLOG(class_linker) << "Soft verification failure in class " << PrettyDescriptor(klass)
           << " in " << klass->GetDexCache()->GetLocation()->ToModifiedUtf8()
           << " because: " << error_msg;
     }
@@ -2696,7 +2701,6 @@
 
   Thread* self = Thread::Current();
 
-  mirror::ArtMethod* clinit = NULL;
   {
     // see JLS 3rd edition, 12.4.2 "Detailed Initialization Procedure" for the locking protocol
     ObjectLock lock(self, klass);
@@ -2721,16 +2725,6 @@
       }
     }
 
-    clinit = klass->FindDeclaredDirectMethod("<clinit>", "()V");
-    if (clinit != NULL && !can_run_clinit) {
-      // if the class has a <clinit> but we can't run it during compilation,
-      // don't bother going to kStatusInitializing. We return false so that
-      // sub-classes don't believe this class is initialized.
-      // Opportunistically link non-static methods, TODO: don't initialize and dirty pages
-      // in second pass.
-      return false;
-    }
-
     // If the class is kStatusInitializing, either this thread is
     // initializing higher up the stack or another thread has beat us
     // to initializing and we need to wait. Either way, this
@@ -2775,9 +2769,10 @@
     return false;
   }
 
-  bool has_static_field_initializers = InitializeStaticFields(klass);
+  bool has_static_field_initializers = InitializeStaticFields(klass, can_init_statics);
 
-  if (clinit != NULL) {
+  mirror::ArtMethod* clinit = klass->FindDeclaredDirectMethod("<clinit>", "()V");
+  if (clinit != NULL && can_run_clinit) {
     if (Runtime::Current()->IsStarted()) {
       JValue result;
       clinit->Invoke(self, NULL, 0, &result, 'V');
@@ -2786,7 +2781,11 @@
     }
   }
 
-  FixupStaticTrampolines(klass);
+  // Opportunistically set static method trampolines to their destination. Unless initialization
+  // is being hindered at compile time.
+  if (can_init_statics || can_run_clinit || (!has_static_field_initializers && clinit == NULL)) {
+    FixupStaticTrampolines(klass);
+  }
 
   uint64_t t1 = NanoTime();
 
@@ -2805,15 +2804,15 @@
       ++thread_stats->class_init_count;
       global_stats->class_init_time_ns += (t1 - t0);
       thread_stats->class_init_time_ns += (t1 - t0);
-      // Set the class as initialized except if we can't initialize static fields and static field
-      // initialization is necessary.
-      if (!can_init_statics && has_static_field_initializers) {
-        klass->SetStatus(mirror::Class::kStatusVerified);  // Don't leave class in initializing state.
+      // Set the class as initialized except if failed to initialize static fields.
+      if ((!can_init_statics && has_static_field_initializers) ||
+          (!can_run_clinit && clinit != NULL)) {
+        klass->SetStatus(mirror::Class::kStatusVerified);
         success = false;
       } else {
         klass->SetStatus(mirror::Class::kStatusInitialized);
       }
-      if (VLOG_IS_ON(class_linker)) {
+      if (success && VLOG_IS_ON(class_linker)) {
         ClassHelper kh(klass);
         LOG(INFO) << "Initialized class " << kh.GetDescriptor() << " from " << kh.GetLocation();
       }
@@ -2986,10 +2985,9 @@
     return true;
   }
 
-  Thread* self = Thread::Current();
-  ScopedThreadStateChange tsc(self, kRunnable);
   bool success = InitializeClass(c, can_run_clinit, can_init_fields);
   if (!success) {
+    Thread* self = Thread::Current();
     CHECK(self->IsExceptionPending() || !can_run_clinit) << PrettyClass(c);
   }
   return success;
@@ -3005,7 +3003,7 @@
   }
 }
 
-bool ClassLinker::InitializeStaticFields(mirror::Class* klass) {
+bool ClassLinker::InitializeStaticFields(mirror::Class* klass, bool can_init_statics) {
   size_t num_static_fields = klass->NumStaticFields();
   if (num_static_fields == 0) {
     return false;
@@ -3022,16 +3020,19 @@
   EncodedStaticFieldValueIterator it(dex_file, dex_cache, klass->GetClassLoader(),
                                      this, *dex_class_def);
 
-  if (it.HasNext()) {
-    // We reordered the fields, so we need to be able to map the field indexes to the right fields.
-    SafeMap<uint32_t, mirror::ArtField*> field_map;
-    ConstructFieldMap(dex_file, *dex_class_def, klass, field_map);
-    for (size_t i = 0; it.HasNext(); i++, it.Next()) {
-      it.ReadValueToField(field_map.Get(i));
+  if (!it.HasNext()) {
+    return false;
+  } else {
+    if (can_init_statics) {
+      // We reordered the fields, so we need to be able to map the field indexes to the right fields.
+      SafeMap<uint32_t, mirror::ArtField*> field_map;
+      ConstructFieldMap(dex_file, *dex_class_def, klass, field_map);
+      for (size_t i = 0; it.HasNext(); i++, it.Next()) {
+        it.ReadValueToField(field_map.Get(i));
+      }
     }
     return true;
   }
-  return false;
 }
 
 bool ClassLinker::LinkClass(SirtRef<mirror::Class>& klass,
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index d0cc562..624b7ce 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -62,6 +62,8 @@
 
   ~ClassLinker();
 
+  bool IsInBootClassPath(const char* descriptor);
+
   // Finds a class by its descriptor, loading it if necessary.
   // If class_loader is null, searches boot_class_path_.
   mirror::Class* FindClass(const char* descriptor, mirror::ClassLoader* class_loader)
@@ -443,7 +445,7 @@
   bool InitializeSuperClass(mirror::Class* klass, bool can_run_clinit, bool can_init_fields)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   // Initialize static fields, returns true if fields were initialized.
-  bool InitializeStaticFields(mirror::Class* klass)
+  bool InitializeStaticFields(mirror::Class* klass, bool can_init_statics)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   bool IsSameDescriptorInDifferentClassContexts(const char* descriptor,