Merge "[native bridge] Make sure we always unload the native bridge"
diff --git a/compiler/dex/compiler_ir.cc b/compiler/dex/compiler_ir.cc
index 909c995..a2b3fe4 100644
--- a/compiler/dex/compiler_ir.cc
+++ b/compiler/dex/compiler_ir.cc
@@ -16,6 +16,7 @@
 
 #include "compiler_ir.h"
 
+#include "base/dumpable.h"
 #include "backend.h"
 #include "frontend.h"
 #include "mir_graph.h"
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc
index 2e21d05..3dc5655 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -19,6 +19,7 @@
 #include <cstdint>
 
 #include "backend.h"
+#include "base/dumpable.h"
 #include "compiler.h"
 #include "compiler_internals.h"
 #include "driver/compiler_driver.h"
@@ -134,15 +135,8 @@
         (cu.enable_debug & (1 << kDebugVerbose));
   }
 
-  if (gVerboseMethods.size() != 0) {
-    cu.verbose = false;
-    for (size_t i = 0; i < gVerboseMethods.size(); ++i) {
-      if (PrettyMethod(method_idx, dex_file).find(gVerboseMethods[i])
-          != std::string::npos) {
-        cu.verbose = true;
-        break;
-      }
-    }
+  if (driver.GetCompilerOptions().HasVerboseMethods()) {
+    cu.verbose = driver.GetCompilerOptions().IsVerboseMethod(PrettyMethod(method_idx, dex_file));
   }
 
   if (cu.verbose) {
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 07034cb..acf5599 100755
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -858,6 +858,11 @@
     RegLocation rl_dest = InlineTargetWide(info);
     int res_vreg, src1_vreg, src2_vreg;
 
+    if (rl_dest.s_reg_low == INVALID_SREG) {
+      // Result is unused, the code is dead. Inlining successful, no code generated.
+      return true;
+    }
+
     /*
      * If the result register is the same as the second element, then we
      * need to be careful. The reason is that the first copy will
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 4528688..a60c5bc 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -347,15 +347,11 @@
       image_(image),
       image_classes_(image_classes),
       thread_count_(thread_count),
-      start_ns_(0),
       stats_(new AOTCompilationStats),
       dump_stats_(dump_stats),
       dump_passes_(dump_passes),
       timings_logger_(timer),
-      compiler_library_(nullptr),
       compiler_context_(nullptr),
-      compiler_enable_auto_elf_loading_(nullptr),
-      compiler_get_method_code_addr_(nullptr),
       support_boot_image_fixup_(instruction_set != kMips),
       dedupe_code_("dedupe code"),
       dedupe_src_mapping_table_("dedupe source mapping table"),
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 3d59ef1..0796f48 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -503,7 +503,6 @@
   std::unique_ptr<std::set<std::string>> image_classes_;
 
   size_t thread_count_;
-  uint64_t start_ns_;
 
   class AOTCompilationStats;
   std::unique_ptr<AOTCompilationStats> stats_;
@@ -516,8 +515,6 @@
   typedef void (*CompilerCallbackFn)(CompilerDriver& driver);
   typedef MutexLock* (*CompilerMutexLockFn)(CompilerDriver& driver);
 
-  void* compiler_library_;
-
   typedef void (*DexToDexCompilerFn)(CompilerDriver& driver,
                                      const DexFile::CodeItem* code_item,
                                      uint32_t access_flags, InvokeType invoke_type,
@@ -533,13 +530,6 @@
   // Arena pool used by the compiler.
   ArenaPool arena_pool_;
 
-  typedef void (*CompilerEnableAutoElfLoadingFn)(CompilerDriver& driver);
-  CompilerEnableAutoElfLoadingFn compiler_enable_auto_elf_loading_;
-
-  typedef const void* (*CompilerGetMethodCodeAddrFn)
-      (const CompilerDriver& driver, const CompiledMethod* cm, const mirror::ArtMethod* method);
-  CompilerGetMethodCodeAddrFn compiler_get_method_code_addr_;
-
   bool support_boot_image_fixup_;
 
   // DeDuplication data structures, these own the corresponding byte arrays.
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index 3a50bfd..fb7aeb9 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -17,9 +17,14 @@
 #ifndef ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
 #define ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
 
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+
 namespace art {
 
-class CompilerOptions {
+class CompilerOptions FINAL {
  public:
   enum CompilerFilter {
     kVerifyNone,          // Skip verification and compile nothing except JNI stubs.
@@ -60,11 +65,12 @@
     implicit_null_checks_(false),
     implicit_so_checks_(false),
     implicit_suspend_checks_(false),
-    compile_pic_(false)
+    compile_pic_(false),
 #ifdef ART_SEA_IR_MODE
-    , sea_ir_mode_(false)
+    sea_ir_mode_(false),
 #endif
-    {}
+    verbose_methods_(nullptr) {
+  }
 
   CompilerOptions(CompilerFilter compiler_filter,
                   size_t huge_method_threshold,
@@ -79,10 +85,11 @@
                   bool implicit_null_checks,
                   bool implicit_so_checks,
                   bool implicit_suspend_checks,
-                  bool compile_pic
+                  bool compile_pic,
 #ifdef ART_SEA_IR_MODE
-                  , bool sea_ir_mode
+                  bool sea_ir_mode,
 #endif
+                  const std::vector<std::string>* verbose_methods
                   ) :  // NOLINT(whitespace/parens)
     compiler_filter_(compiler_filter),
     huge_method_threshold_(huge_method_threshold),
@@ -97,11 +104,12 @@
     implicit_null_checks_(implicit_null_checks),
     implicit_so_checks_(implicit_so_checks),
     implicit_suspend_checks_(implicit_suspend_checks),
-    compile_pic_(compile_pic)
+    compile_pic_(compile_pic),
 #ifdef ART_SEA_IR_MODE
-    , sea_ir_mode_(sea_ir_mode)
+    sea_ir_mode_(sea_ir_mode),
 #endif
-    {}
+    verbose_methods_(verbose_methods) {
+  }
 
   CompilerFilter GetCompilerFilter() const {
     return compiler_filter_;
@@ -168,28 +176,18 @@
     return implicit_null_checks_;
   }
 
-  void SetImplicitNullChecks(bool new_val) {
-    implicit_null_checks_ = new_val;
-  }
-
   bool GetImplicitStackOverflowChecks() const {
     return implicit_so_checks_;
   }
 
-  void SetImplicitStackOverflowChecks(bool new_val) {
-    implicit_so_checks_ = new_val;
-  }
-
   bool GetImplicitSuspendChecks() const {
     return implicit_suspend_checks_;
   }
 
-  void SetImplicitSuspendChecks(bool new_val) {
-    implicit_suspend_checks_ = new_val;
-  }
-
 #ifdef ART_SEA_IR_MODE
-  bool GetSeaIrMode();
+  bool GetSeaIrMode() const {
+    return sea_ir_mode_;
+  }
 #endif
 
   bool GetGenerateGDBInformation() const {
@@ -205,25 +203,44 @@
     return compile_pic_;
   }
 
+  bool HasVerboseMethods() const {
+    return verbose_methods_ != nullptr && !verbose_methods_->empty();
+  }
+
+  bool IsVerboseMethod(const std::string& pretty_method) const {
+    for (const std::string& cur_method : *verbose_methods_) {
+      if (pretty_method.find(cur_method) != std::string::npos) {
+        return true;
+      }
+    }
+    return false;
+  }
+
  private:
   CompilerFilter compiler_filter_;
-  size_t huge_method_threshold_;
-  size_t large_method_threshold_;
-  size_t small_method_threshold_;
-  size_t tiny_method_threshold_;
-  size_t num_dex_methods_threshold_;
-  bool generate_gdb_information_;
-  bool include_patch_information_;
+  const size_t huge_method_threshold_;
+  const size_t large_method_threshold_;
+  const size_t small_method_threshold_;
+  const size_t tiny_method_threshold_;
+  const size_t num_dex_methods_threshold_;
+  const bool generate_gdb_information_;
+  const bool include_patch_information_;
   // When using a profile file only the top K% of the profiled samples will be compiled.
-  double top_k_profile_threshold_;
-  bool include_debug_symbols_;
-  bool implicit_null_checks_;
-  bool implicit_so_checks_;
-  bool implicit_suspend_checks_;
-  bool compile_pic_;
+  const double top_k_profile_threshold_;
+  const bool include_debug_symbols_;
+  const bool implicit_null_checks_;
+  const bool implicit_so_checks_;
+  const bool implicit_suspend_checks_;
+  const bool compile_pic_;
+
 #ifdef ART_SEA_IR_MODE
-  bool sea_ir_mode_;
+  const bool sea_ir_mode_;
 #endif
+
+  // Vector of methods to have verbose output enabled for.
+  const std::vector<std::string>* const verbose_methods_;
+
+  DISALLOW_COPY_AND_ASSIGN(CompilerOptions);
 };
 
 }  // namespace art
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 1188ec0..f48f4c3 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -748,6 +748,11 @@
       break;
     }
 
+    case Instruction::NOT_INT: {
+      Unop_12x<HNot>(instruction, Primitive::kPrimInt);
+      break;
+    }
+
     case Instruction::ADD_INT: {
       Binop_23x<HAdd>(instruction, Primitive::kPrimInt);
       break;
@@ -793,6 +798,16 @@
       break;
     }
 
+    case Instruction::MUL_FLOAT: {
+      Binop_23x<HMul>(instruction, Primitive::kPrimFloat);
+      break;
+    }
+
+    case Instruction::MUL_DOUBLE: {
+      Binop_23x<HMul>(instruction, Primitive::kPrimDouble);
+      break;
+    }
+
     case Instruction::ADD_LONG_2ADDR: {
       Binop_12x<HAdd>(instruction, Primitive::kPrimLong);
       break;
@@ -828,6 +843,16 @@
       break;
     }
 
+    case Instruction::MUL_FLOAT_2ADDR: {
+      Binop_12x<HMul>(instruction, Primitive::kPrimFloat);
+      break;
+    }
+
+    case Instruction::MUL_DOUBLE_2ADDR: {
+      Binop_12x<HMul>(instruction, Primitive::kPrimDouble);
+      break;
+    }
+
     case Instruction::ADD_INT_LIT16: {
       Binop_22s<HAdd>(instruction, false);
       break;
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 792ff45..b042beb 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -1219,15 +1219,16 @@
       break;
     }
 
-    case Primitive::kPrimBoolean:
-    case Primitive::kPrimByte:
-    case Primitive::kPrimChar:
-    case Primitive::kPrimShort:
-      LOG(FATAL) << "Unexpected mul type " << mul->GetResultType();
+    case Primitive::kPrimFloat:
+    case Primitive::kPrimDouble: {
+      locations->SetInAt(0, Location::RequiresFpuRegister());
+      locations->SetInAt(1, Location::RequiresFpuRegister());
+      locations->SetOut(Location::RequiresFpuRegister());
       break;
+    }
 
     default:
-      LOG(FATAL) << "Unimplemented mul type " << mul->GetResultType();
+      LOG(FATAL) << "Unexpected mul type " << mul->GetResultType();
   }
 }
 
@@ -1271,15 +1272,21 @@
       __ add(out_hi, out_hi, ShifterOperand(IP));
       break;
     }
-    case Primitive::kPrimBoolean:
-    case Primitive::kPrimByte:
-    case Primitive::kPrimChar:
-    case Primitive::kPrimShort:
-      LOG(FATAL) << "Unexpected mul type " << mul->GetResultType();
+
+    case Primitive::kPrimFloat: {
+      __ vmuls(FromDToLowS(out.As<DRegister>()),
+               FromDToLowS(first.As<DRegister>()),
+               FromDToLowS(second.As<DRegister>()));
       break;
+    }
+
+    case Primitive::kPrimDouble: {
+      __ vmuld(out.As<DRegister>(), first.As<DRegister>(), second.As<DRegister>());
+      break;
+    }
 
     default:
-      LOG(FATAL) << "Unimplemented mul type " << mul->GetResultType();
+      LOG(FATAL) << "Unexpected mul type " << mul->GetResultType();
   }
 }
 
@@ -1344,17 +1351,33 @@
   // Nothing to do, the parameter is already at its location.
 }
 
-void LocationsBuilderARM::VisitNot(HNot* instruction) {
+void LocationsBuilderARM::VisitNot(HNot* not_) {
   LocationSummary* locations =
-      new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
+      new (GetGraph()->GetArena()) LocationSummary(not_, LocationSummary::kNoCall);
   locations->SetInAt(0, Location::RequiresRegister());
   locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
 }
 
-void InstructionCodeGeneratorARM::VisitNot(HNot* instruction) {
-  LocationSummary* locations = instruction->GetLocations();
-  __ eor(locations->Out().As<Register>(),
-         locations->InAt(0).As<Register>(), ShifterOperand(1));
+void InstructionCodeGeneratorARM::VisitNot(HNot* not_) {
+  LocationSummary* locations = not_->GetLocations();
+  Location out = locations->Out();
+  Location in = locations->InAt(0);
+  switch (not_->InputAt(0)->GetType()) {
+    case Primitive::kPrimBoolean:
+      __ eor(out.As<Register>(), in.As<Register>(), ShifterOperand(1));
+      break;
+
+    case Primitive::kPrimInt:
+      __ mvn(out.As<Register>(), ShifterOperand(in.As<Register>()));
+      break;
+
+    case Primitive::kPrimLong:
+      LOG(FATAL) << "Not yet implemented type for not operation " << not_->GetResultType();
+      break;
+
+    default:
+      LOG(FATAL) << "Unimplemented type for not operation " << not_->GetResultType();
+  }
 }
 
 void LocationsBuilderARM::VisitCompare(HCompare* compare) {
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index acf4103..3b4b835 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -1212,16 +1212,16 @@
       locations->AddTemp(Location::RegisterLocation(EDX));
       break;
     }
-
-    case Primitive::kPrimBoolean:
-    case Primitive::kPrimByte:
-    case Primitive::kPrimChar:
-    case Primitive::kPrimShort:
-      LOG(FATAL) << "Unexpected mul type " << mul->GetResultType();
+    case Primitive::kPrimFloat:
+    case Primitive::kPrimDouble: {
+      locations->SetInAt(0, Location::RequiresFpuRegister());
+      locations->SetInAt(1, Location::RequiresFpuRegister());
+      locations->SetOut(Location::SameAsFirstInput());
       break;
+    }
 
     default:
-      LOG(FATAL) << "Unimplemented mul type " << mul->GetResultType();
+      LOG(FATAL) << "Unexpected mul type " << mul->GetResultType();
   }
 }
 
@@ -1283,15 +1283,18 @@
       break;
     }
 
-    case Primitive::kPrimBoolean:
-    case Primitive::kPrimByte:
-    case Primitive::kPrimChar:
-    case Primitive::kPrimShort:
-      LOG(FATAL) << "Unexpected mul type " << mul->GetResultType();
+    case Primitive::kPrimFloat: {
+      __ mulss(first.As<XmmRegister>(), second.As<XmmRegister>());
       break;
+    }
+
+    case Primitive::kPrimDouble: {
+      __ mulsd(first.As<XmmRegister>(), second.As<XmmRegister>());
+      break;
+    }
 
     default:
-      LOG(FATAL) << "Unimplemented mul type " << mul->GetResultType();
+      LOG(FATAL) << "Unexpected mul type " << mul->GetResultType();
   }
 }
 
@@ -1353,18 +1356,34 @@
 void InstructionCodeGeneratorX86::VisitParameterValue(HParameterValue* instruction) {
 }
 
-void LocationsBuilderX86::VisitNot(HNot* instruction) {
+void LocationsBuilderX86::VisitNot(HNot* not_) {
   LocationSummary* locations =
-      new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
+      new (GetGraph()->GetArena()) LocationSummary(not_, LocationSummary::kNoCall);
   locations->SetInAt(0, Location::RequiresRegister());
   locations->SetOut(Location::SameAsFirstInput());
 }
 
-void InstructionCodeGeneratorX86::VisitNot(HNot* instruction) {
-  LocationSummary* locations = instruction->GetLocations();
+void InstructionCodeGeneratorX86::VisitNot(HNot* not_) {
+  LocationSummary* locations = not_->GetLocations();
+  DCHECK_EQ(locations->InAt(0).As<Register>(), locations->Out().As<Register>());
   Location out = locations->Out();
   DCHECK_EQ(locations->InAt(0).As<Register>(), out.As<Register>());
-  __ xorl(out.As<Register>(), Immediate(1));
+  switch (not_->InputAt(0)->GetType()) {
+    case Primitive::kPrimBoolean:
+      __ xorl(out.As<Register>(), Immediate(1));
+      break;
+
+    case Primitive::kPrimInt:
+      __ notl(out.As<Register>());
+      break;
+
+    case Primitive::kPrimLong:
+      LOG(FATAL) << "Not yet implemented type for not operation " << not_->GetResultType();
+      break;
+
+    default:
+      LOG(FATAL) << "Unimplemented type for not operation " << not_->GetResultType();
+  }
 }
 
 void LocationsBuilderX86::VisitCompare(HCompare* compare) {
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 58dda16..ac623f6 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -1166,16 +1166,16 @@
       locations->SetOut(Location::SameAsFirstInput());
       break;
     }
-
-    case Primitive::kPrimBoolean:
-    case Primitive::kPrimByte:
-    case Primitive::kPrimChar:
-    case Primitive::kPrimShort:
-      LOG(FATAL) << "Unexpected mul type " << mul->GetResultType();
+    case Primitive::kPrimFloat:
+    case Primitive::kPrimDouble: {
+      locations->SetInAt(0, Location::RequiresFpuRegister());
+      locations->SetInAt(1, Location::RequiresFpuRegister());
+      locations->SetOut(Location::SameAsFirstInput());
       break;
+    }
 
     default:
-      LOG(FATAL) << "Unimplemented mul type " << mul->GetResultType();
+      LOG(FATAL) << "Unexpected mul type " << mul->GetResultType();
   }
 }
 
@@ -1202,15 +1202,18 @@
       break;
     }
 
-    case Primitive::kPrimBoolean:
-    case Primitive::kPrimByte:
-    case Primitive::kPrimChar:
-    case Primitive::kPrimShort:
-      LOG(FATAL) << "Unexpected mul type " << mul->GetResultType();
+    case Primitive::kPrimFloat: {
+      __ mulss(first.As<XmmRegister>(), second.As<XmmRegister>());
       break;
+    }
+
+    case Primitive::kPrimDouble: {
+      __ mulsd(first.As<XmmRegister>(), second.As<XmmRegister>());
+      break;
+    }
 
     default:
-      LOG(FATAL) << "Unimplemented mul type " << mul->GetResultType();
+      LOG(FATAL) << "Unexpected mul type " << mul->GetResultType();
   }
 }
 
@@ -1273,18 +1276,34 @@
   // Nothing to do, the parameter is already at its location.
 }
 
-void LocationsBuilderX86_64::VisitNot(HNot* instruction) {
+void LocationsBuilderX86_64::VisitNot(HNot* not_) {
   LocationSummary* locations =
-      new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
+      new (GetGraph()->GetArena()) LocationSummary(not_, LocationSummary::kNoCall);
   locations->SetInAt(0, Location::RequiresRegister());
   locations->SetOut(Location::SameAsFirstInput());
 }
 
-void InstructionCodeGeneratorX86_64::VisitNot(HNot* instruction) {
-  LocationSummary* locations = instruction->GetLocations();
+void InstructionCodeGeneratorX86_64::VisitNot(HNot* not_) {
+  LocationSummary* locations = not_->GetLocations();
   DCHECK_EQ(locations->InAt(0).As<CpuRegister>().AsRegister(),
             locations->Out().As<CpuRegister>().AsRegister());
-  __ xorq(locations->Out().As<CpuRegister>(), Immediate(1));
+  Location out = locations->Out();
+  switch (not_->InputAt(0)->GetType()) {
+    case Primitive::kPrimBoolean:
+      __ xorq(out.As<CpuRegister>(), Immediate(1));
+      break;
+
+    case Primitive::kPrimInt:
+      __ notl(out.As<CpuRegister>());
+      break;
+
+    case Primitive::kPrimLong:
+      LOG(FATAL) << "Not yet implemented type for not operation " << not_->GetResultType();
+      break;
+
+    default:
+      LOG(FATAL) << "Unimplemented type for not operation " << not_->GetResultType();
+  }
 }
 
 void LocationsBuilderX86_64::VisitPhi(HPhi* instruction) {
diff --git a/compiler/optimizing/codegen_test.cc b/compiler/optimizing/codegen_test.cc
index 8bb12de..a84931a 100644
--- a/compiler/optimizing/codegen_test.cc
+++ b/compiler/optimizing/codegen_test.cc
@@ -135,8 +135,8 @@
   const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
   HGraph* graph = builder.BuildGraph(*item);
   // Remove suspend checks, they cannot be executed in this context.
-  RemoveSuspendChecks(graph);
   ASSERT_NE(graph, nullptr);
+  RemoveSuspendChecks(graph);
   RunCodeBaseline(graph, has_result, expected);
 }
 
@@ -260,6 +260,31 @@
   TestCode(data, true, 0);
 }
 
+// Exercise bit-wise (one's complement) not-int instruction.
+#define NOT_INT_TEST(TEST_NAME, INPUT, EXPECTED_OUTPUT) \
+TEST(CodegenTest, TEST_NAME) {                          \
+  const int32_t input = INPUT;                          \
+  const uint16_t input_lo = input & 0x0000FFFF;         \
+  const uint16_t input_hi = input >> 16;                \
+  const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(      \
+      Instruction::CONST | 0 << 8, input_lo, input_hi,  \
+      Instruction::NOT_INT | 1 << 8 | 0 << 12 ,         \
+      Instruction::RETURN | 1 << 8);                    \
+                                                        \
+  TestCode(data, true, EXPECTED_OUTPUT);                \
+}
+
+NOT_INT_TEST(ReturnNotIntMinus2, -2, 1)
+NOT_INT_TEST(ReturnNotIntMinus1, -1, 0)
+NOT_INT_TEST(ReturnNotInt0, 0, -1)
+NOT_INT_TEST(ReturnNotInt1, 1, -2)
+NOT_INT_TEST(ReturnNotIntINT_MIN, -2147483648, 2147483647)  // (2^31) - 1
+NOT_INT_TEST(ReturnNotIntINT_MINPlus1, -2147483647, 2147483646)  // (2^31) - 2
+NOT_INT_TEST(ReturnNotIntINT_MAXMinus1, 2147483646, -2147483647)  // -(2^31) - 1
+NOT_INT_TEST(ReturnNotIntINT_MAX, 2147483647, -2147483648)  // -(2^31)
+
+#undef NOT_INT_TEST
+
 TEST(CodegenTest, ReturnAdd1) {
   const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
     Instruction::CONST_4 | 3 << 12 | 0,
diff --git a/compiler/optimizing/graph_checker.h b/compiler/optimizing/graph_checker.h
index db31306..badf21d 100644
--- a/compiler/optimizing/graph_checker.h
+++ b/compiler/optimizing/graph_checker.h
@@ -53,7 +53,7 @@
   }
 
   // Print detected errors on output stream `os`.
-  void Dump(std::ostream& os) {
+  void Dump(std::ostream& os) const {
     for (size_t i = 0, e = errors_.Size(); i < e; ++i) {
       os << dump_prefix_ << errors_.Get(i) << std::endl;
     }
@@ -68,7 +68,7 @@
 
  private:
   // String displayed before dumped errors.
-  const char* dump_prefix_;
+  const char* const dump_prefix_;
 
   DISALLOW_COPY_AND_ASSIGN(GraphChecker);
 };
diff --git a/compiler/optimizing/graph_visualizer.h b/compiler/optimizing/graph_visualizer.h
index 05984a0..4d8bec2 100644
--- a/compiler/optimizing/graph_visualizer.h
+++ b/compiler/optimizing/graph_visualizer.h
@@ -17,6 +17,8 @@
 #ifndef ART_COMPILER_OPTIMIZING_GRAPH_VISUALIZER_H_
 #define ART_COMPILER_OPTIMIZING_GRAPH_VISUALIZER_H_
 
+#include <ostream>
+
 #include "base/value_object.h"
 
 namespace art {
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 2d9e35c..29eabe7 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -50,7 +50,7 @@
       // Replace (bool_value == 0) with !bool_value
       DCHECK_EQ(input2->AsIntConstant()->GetValue(), 0);
       equal->GetBlock()->ReplaceAndRemoveInstructionWith(
-          equal, new (GetGraph()->GetArena()) HNot(input1));
+          equal, new (GetGraph()->GetArena()) HNot(Primitive::kPrimBoolean, input1));
     }
   }
 }
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 9b7ff88..7adb840 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -485,7 +485,7 @@
   M(Local, Instruction)                                                 \
   M(LongConstant, Constant)                                             \
   M(NewInstance, Instruction)                                           \
-  M(Not, Instruction)                                                   \
+  M(Not, UnaryOperation)                                                \
   M(ParameterValue, Instruction)                                        \
   M(ParallelMove, Instruction)                                          \
   M(Phi, Instruction)                                                   \
@@ -1708,15 +1708,17 @@
   DISALLOW_COPY_AND_ASSIGN(HParameterValue);
 };
 
-class HNot : public HExpression<1> {
+class HNot : public HUnaryOperation {
  public:
-  explicit HNot(HInstruction* input) : HExpression(Primitive::kPrimBoolean, SideEffects::None()) {
-    SetRawInputAt(0, input);
-  }
+  explicit HNot(Primitive::Type result_type, HInstruction* input)
+      : HUnaryOperation(result_type, input) {}
 
   virtual bool CanBeMoved() const { return true; }
   virtual bool InstructionDataEquals(HInstruction* other) const { return true; }
 
+  virtual int32_t Evaluate(int32_t x) const OVERRIDE { return ~x; }
+  virtual int64_t Evaluate(int64_t x) const OVERRIDE { return ~x; }
+
   DECLARE_INSTRUCTION(Not);
 
  private:
@@ -2123,7 +2125,7 @@
 #undef DECLARE_VISIT_INSTRUCTION
 
  private:
-  HGraph* graph_;
+  HGraph* const graph_;
 
   DISALLOW_COPY_AND_ASSIGN(HGraphVisitor);
 };
diff --git a/compiler/optimizing/optimization.cc b/compiler/optimizing/optimization.cc
index 33dc040..ea98186 100644
--- a/compiler/optimizing/optimization.cc
+++ b/compiler/optimizing/optimization.cc
@@ -16,6 +16,7 @@
 
 #include "optimization.h"
 
+#include "base/dumpable.h"
 #include "graph_checker.h"
 
 namespace art {
diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc
index fc65f97..f95c4a4 100644
--- a/compiler/optimizing/register_allocator.cc
+++ b/compiler/optimizing/register_allocator.cc
@@ -16,6 +16,8 @@
 
 #include "register_allocator.h"
 
+#include <sstream>
+
 #include "base/bit_vector-inl.h"
 #include "code_generator.h"
 #include "ssa_liveness_analysis.h"
diff --git a/compiler/optimizing/ssa_liveness_analysis.h b/compiler/optimizing/ssa_liveness_analysis.h
index 8f71848..7dda4f6 100644
--- a/compiler/optimizing/ssa_liveness_analysis.h
+++ b/compiler/optimizing/ssa_liveness_analysis.h
@@ -32,6 +32,7 @@
         live_in_(allocator, number_of_ssa_values, false),
         live_out_(allocator, number_of_ssa_values, false),
         kill_(allocator, number_of_ssa_values, false) {
+    UNUSED(block_);
     live_in_.ClearAllBits();
     live_out_.ClearAllBits();
     kill_.ClearAllBits();
diff --git a/compiler/utils/assembler_test.h b/compiler/utils/assembler_test.h
index 5bfa462..91237ae 100644
--- a/compiler/utils/assembler_test.h
+++ b/compiler/utils/assembler_test.h
@@ -24,7 +24,6 @@
 #include <cstdio>
 #include <cstdlib>
 #include <fstream>
-#include <iostream>
 #include <iterator>
 #include <sys/stat.h>
 
@@ -118,9 +117,8 @@
     std::vector<int64_t> imms = CreateImmediateValues(imm_bytes);
     for (auto reg : registers) {
       for (int64_t imm : imms) {
-        Imm* new_imm = CreateImmediate(imm);
-        (assembler_.get()->*f)(*reg, *new_imm);
-        delete new_imm;
+        Imm new_imm = CreateImmediate(imm);
+        (assembler_.get()->*f)(*reg, new_imm);
         std::string base = fmt;
 
         size_t reg_index = base.find("{reg}");
@@ -154,9 +152,8 @@
     std::string str;
     std::vector<int64_t> imms = CreateImmediateValues(imm_bytes);
     for (int64_t imm : imms) {
-      Imm* new_imm = CreateImmediate(imm);
-      (assembler_.get()->*f)(*new_imm);
-      delete new_imm;
+      Imm new_imm = CreateImmediate(imm);
+      (assembler_.get()->*f)(new_imm);
       std::string base = fmt;
 
       size_t imm_index = base.find("{imm}");
@@ -333,7 +330,7 @@
   }
 
   // Create an immediate from the specific value.
-  virtual Imm* CreateImmediate(int64_t imm_value) = 0;
+  virtual Imm CreateImmediate(int64_t imm_value) = 0;
 
  private:
   // Driver() assembles and compares the results. If the results are not equal and we have a
diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h
index c7eada3..b5bf31b 100644
--- a/compiler/utils/x86/assembler_x86.h
+++ b/compiler/utils/x86/assembler_x86.h
@@ -29,7 +29,7 @@
 namespace art {
 namespace x86 {
 
-class Immediate {
+class Immediate : public ValueObject {
  public:
   explicit Immediate(int32_t value) : value_(value) {}
 
@@ -47,7 +47,7 @@
 };
 
 
-class Operand {
+class Operand : public ValueObject {
  public:
   uint8_t mod() const {
     return (encoding_at(0) >> 6) & 3;
@@ -129,8 +129,6 @@
   }
 
   friend class X86Assembler;
-
-  DISALLOW_COPY_AND_ASSIGN(Operand);
 };
 
 
@@ -168,7 +166,6 @@
     }
   }
 
-
   Address(Register index, ScaleFactor scale, int32_t disp) {
     CHECK_NE(index, ESP);  // Illegal addressing mode.
     SetModRM(0, ESP);
@@ -205,14 +202,12 @@
 
  private:
   Address() {}
-
-  DISALLOW_COPY_AND_ASSIGN(Address);
 };
 
 
 class X86Assembler FINAL : public Assembler {
  public:
-  explicit X86Assembler() {}
+  explicit X86Assembler() : cfi_cfa_offset_(0), cfi_pc_(0) {}
   virtual ~X86Assembler() {}
 
   /*
diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h
index 7e5859c..92b81ec 100644
--- a/compiler/utils/x86_64/assembler_x86_64.h
+++ b/compiler/utils/x86_64/assembler_x86_64.h
@@ -36,7 +36,7 @@
 //
 // Note: As we support cross-compilation, the value type must be int64_t. Please be aware of
 // conversion rules in expressions regarding negation, especially size_t on 32b.
-class Immediate {
+class Immediate : public ValueObject {
  public:
   explicit Immediate(int64_t value) : value_(value) {}
 
@@ -54,12 +54,10 @@
 
  private:
   const int64_t value_;
-
-  DISALLOW_COPY_AND_ASSIGN(Immediate);
 };
 
 
-class Operand {
+class Operand : public ValueObject {
  public:
   uint8_t mod() const {
     return (encoding_at(0) >> 6) & 3;
@@ -157,8 +155,6 @@
   }
 
   friend class X86_64Assembler;
-
-  DISALLOW_COPY_AND_ASSIGN(Operand);
 };
 
 
@@ -247,8 +243,6 @@
 
  private:
   Address() {}
-
-  DISALLOW_COPY_AND_ASSIGN(Address);
 };
 
 
diff --git a/compiler/utils/x86_64/assembler_x86_64_test.cc b/compiler/utils/x86_64/assembler_x86_64_test.cc
index 37a0932..18c5cbc 100644
--- a/compiler/utils/x86_64/assembler_x86_64_test.cc
+++ b/compiler/utils/x86_64/assembler_x86_64_test.cc
@@ -72,8 +72,8 @@
     return registers_;
   }
 
-  x86_64::Immediate* CreateImmediate(int64_t imm_value) OVERRIDE {
-    return new x86_64::Immediate(imm_value);
+  x86_64::Immediate CreateImmediate(int64_t imm_value) OVERRIDE {
+    return x86_64::Immediate(imm_value);
   }
 
  private:
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 326fa72..98712cd 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -30,6 +30,10 @@
 #include <sys/utsname.h>
 #endif
 
+#define ATRACE_TAG ATRACE_TAG_DALVIK
+#include "cutils/trace.h"
+
+#include "base/dumpable.h"
 #include "base/stl_util.h"
 #include "base/stringpiece.h"
 #include "base/timing_logger.h"
@@ -832,6 +836,7 @@
   int small_method_threshold = CompilerOptions::kDefaultSmallMethodThreshold;
   int tiny_method_threshold = CompilerOptions::kDefaultTinyMethodThreshold;
   int num_dex_methods_threshold = CompilerOptions::kDefaultNumDexMethodsThreshold;
+  std::vector<std::string> verbose_methods;
 
   // Initialize ISA and ISA features to default values.
   InstructionSet instruction_set = kRuntimeISA;
@@ -1058,6 +1063,11 @@
       include_patch_information = true;
     } else if (option == "--no-include-patch-information") {
       include_patch_information = false;
+    } else if (option.starts_with("--verbose-methods=")) {
+      // TODO: rather than switch off compiler logging, make all VLOG(compiler) messages conditional
+      //       on having verbost methods.
+      gLogVerbosity.compiler = false;
+      Split(option.substr(strlen("--verbose-methods=")).ToString(), ',', &verbose_methods);
     } else {
       Usage("Unknown argument %s", option.data());
     }
@@ -1213,25 +1223,25 @@
     PassDriverMEOpts::PrintPassOptions();
   }
 
-  std::unique_ptr<CompilerOptions> compiler_options(new CompilerOptions(compiler_filter,
-                                                                        huge_method_threshold,
-                                                                        large_method_threshold,
-                                                                        small_method_threshold,
-                                                                        tiny_method_threshold,
-                                                                        num_dex_methods_threshold,
-                                                                        generate_gdb_information,
-                                                                        include_patch_information,
-                                                                        top_k_profile_threshold,
-                                                                        include_debug_symbols,
-                                                                        implicit_null_checks,
-                                                                        implicit_so_checks,
-                                                                        implicit_suspend_checks,
-                                                                        compile_pic
+  std::unique_ptr<CompilerOptions> compiler_options(
+      new CompilerOptions(compiler_filter,
+                          huge_method_threshold,
+                          large_method_threshold,
+                          small_method_threshold,
+                          tiny_method_threshold,
+                          num_dex_methods_threshold,
+                          generate_gdb_information,
+                          include_patch_information,
+                          top_k_profile_threshold,
+                          include_debug_symbols,
+                          implicit_null_checks,
+                          implicit_so_checks,
+                          implicit_suspend_checks,
+                          compile_pic,
 #ifdef ART_SEA_IR_MODE
-                                                                        , compiler_options.sea_ir_ =
-                                                                              true;
+                          true,
 #endif
-  ));  // NOLINT(whitespace/parens)
+                          verbose_methods.empty() ? nullptr : &verbose_methods));
 
   // Done with usage checks, enable watchdog if requested
   WatchDog watch_dog(watch_dog_enabled);
diff --git a/disassembler/disassembler.cc b/disassembler/disassembler.cc
index c97bf64..bf68204 100644
--- a/disassembler/disassembler.cc
+++ b/disassembler/disassembler.cc
@@ -16,7 +16,7 @@
 
 #include "disassembler.h"
 
-#include <iostream>
+#include <ostream>
 
 #include "base/logging.h"
 #include "base/stringprintf.h"
diff --git a/disassembler/disassembler_arm.cc b/disassembler/disassembler_arm.cc
index ac883fe..ee652b3 100644
--- a/disassembler/disassembler_arm.cc
+++ b/disassembler/disassembler_arm.cc
@@ -18,7 +18,8 @@
 
 #include <inttypes.h>
 
-#include <iostream>
+#include <ostream>
+#include <sstream>
 
 #include "base/logging.h"
 #include "base/stringprintf.h"
diff --git a/disassembler/disassembler_arm64.cc b/disassembler/disassembler_arm64.cc
index fc1065a..229ac97 100644
--- a/disassembler/disassembler_arm64.cc
+++ b/disassembler/disassembler_arm64.cc
@@ -18,7 +18,7 @@
 
 #include <inttypes.h>
 
-#include <iostream>
+#include <ostream>
 
 #include "base/logging.h"
 #include "base/stringprintf.h"
diff --git a/disassembler/disassembler_mips.cc b/disassembler/disassembler_mips.cc
index bd5fac7..97c06f1 100644
--- a/disassembler/disassembler_mips.cc
+++ b/disassembler/disassembler_mips.cc
@@ -16,7 +16,8 @@
 
 #include "disassembler_mips.h"
 
-#include <iostream>
+#include <ostream>
+#include <sstream>
 
 #include "base/logging.h"
 #include "base/stringprintf.h"
diff --git a/disassembler/disassembler_x86.cc b/disassembler/disassembler_x86.cc
index 63a74c7..e12559f 100644
--- a/disassembler/disassembler_x86.cc
+++ b/disassembler/disassembler_x86.cc
@@ -16,12 +16,14 @@
 
 #include "disassembler_x86.h"
 
-#include <iostream>
+#include <inttypes.h>
+
+#include <ostream>
+#include <sstream>
 
 #include "base/logging.h"
 #include "base/stringprintf.h"
 #include "thread.h"
-#include <inttypes.h>
 
 namespace art {
 namespace x86 {
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index c0c96e5..8e5af53 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -24,6 +24,7 @@
 #include <string>
 #include <vector>
 
+#include "base/dumpable.h"
 #include "base/scoped_flock.h"
 #include "base/stringpiece.h"
 #include "base/stringprintf.h"
diff --git a/runtime/Android.mk b/runtime/Android.mk
index d9b4139..0ef0fef 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -209,7 +209,6 @@
 
 LIBART_TARGET_SRC_FILES := \
   $(LIBART_COMMON_SRC_FILES) \
-  base/logging_android.cc \
   jdwp/jdwp_adb.cc \
   monitor_android.cc \
   runtime_android.cc \
@@ -282,7 +281,6 @@
 
 LIBART_HOST_SRC_FILES := \
   $(LIBART_COMMON_SRC_FILES) \
-  base/logging_linux.cc \
   monitor_linux.cc \
   runtime_linux.cc \
   thread_linux.cc
@@ -477,7 +475,7 @@
     endif
   endif
   LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk
-#  LOCAL_ADDITIONAL_DEPENDENCIES += $$(LOCAL_PATH)/Android.mk
+  LOCAL_ADDITIONAL_DEPENDENCIES += $$(LOCAL_PATH)/Android.mk
 
   ifeq ($$(art_target_or_host),target)
     LOCAL_MODULE_TARGET_ARCH := $$(ART_TARGET_SUPPORTED_ARCH)
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 0fb96d7..147d434 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -1285,7 +1285,7 @@
 THREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
 THREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
 THREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
-THREE_ARG_DOWNCALL art_quick_set64_instance, artSet64InstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
+THREE_ARG_REF_DOWNCALL art_quick_set64_instance, artSet64InstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
 THREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
 
 // This is separated out as the argument order is different.
diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc
index ea586b8..c5a0f6c 100644
--- a/runtime/arch/stub_test.cc
+++ b/runtime/arch/stub_test.cc
@@ -1148,7 +1148,7 @@
   // For some reason this does not work, as the type_idx is artificial and outside what the
   // resolved types of c_obj allow...
 
-  if (false) {
+  if ((false)) {
     // Use an arbitrary method from c to use as referrer
     size_t result = Invoke3(static_cast<size_t>(c->GetDexTypeIndex()),    // type_idx
                             reinterpret_cast<size_t>(c_obj->GetVirtualMethod(0)),  // arbitrary
diff --git a/runtime/base/bit_vector.cc b/runtime/base/bit_vector.cc
index 1d67962..5b8b6e2 100644
--- a/runtime/base/bit_vector.cc
+++ b/runtime/base/bit_vector.cc
@@ -16,6 +16,8 @@
 
 #include "bit_vector.h"
 
+#include <sstream>
+
 #include "allocator.h"
 #include "bit_vector-inl.h"
 
diff --git a/runtime/base/dumpable.h b/runtime/base/dumpable.h
new file mode 100644
index 0000000..3c316cc
--- /dev/null
+++ b/runtime/base/dumpable.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_BASE_DUMPABLE_H_
+#define ART_RUNTIME_BASE_DUMPABLE_H_
+
+#include "base/macros.h"
+
+namespace art {
+
+// A convenience to allow any class with a "Dump(std::ostream& os)" member function
+// but without an operator<< to be used as if it had an operator<<. Use like this:
+//
+//   os << Dumpable<MyType>(my_type_instance);
+//
+template<typename T>
+class Dumpable FINAL {
+ public:
+  explicit Dumpable(const T& value) : value_(value) {
+  }
+
+  void Dump(std::ostream& os) const {
+    value_.Dump(os);
+  }
+
+ private:
+  const T& value_;
+
+  DISALLOW_COPY_AND_ASSIGN(Dumpable);
+};
+
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const Dumpable<T>& rhs) {
+  rhs.Dump(os);
+  return os;
+}
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_BASE_DUMPABLE_H_
diff --git a/runtime/base/logging.cc b/runtime/base/logging.cc
index 5af597b..46c3538 100644
--- a/runtime/base/logging.cc
+++ b/runtime/base/logging.cc
@@ -16,17 +16,25 @@
 
 #include "logging.h"
 
+#include <sstream>
+
 #include "base/mutex.h"
 #include "runtime.h"
 #include "thread-inl.h"
 #include "utils.h"
 
+// Headers for LogMessage::LogLine.
+#ifdef HAVE_ANDROID_OS
+#include "cutils/log.h"
+#else
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
 namespace art {
 
 LogVerbosity gLogVerbosity;
 
-std::vector<std::string> gVerboseMethods;
-
 unsigned int gAborting = 0;
 
 static LogSeverity gMinimumLogSeverity = INFO;
@@ -47,14 +55,6 @@
                                                         : "art";
 }
 
-// Configure logging based on ANDROID_LOG_TAGS environment variable.
-// We need to parse a string that looks like
-//
-//      *:v jdwp:d dalvikvm:d dalvikvm-gc:i dalvikvmi:i
-//
-// The tag (or '*' for the global level) comes first, followed by a colon
-// and a letter indicating the minimum priority level we're expected to log.
-// This can be used to reveal or conceal logs with specific tags.
 void InitLogging(char* argv[]) {
   if (gCmdLine.get() != nullptr) {
     return;
@@ -65,22 +65,22 @@
   // Stash the command line for later use. We can use /proc/self/cmdline on Linux to recover this,
   // but we don't have that luxury on the Mac, and there are a couple of argv[0] variants that are
   // commonly used.
-  if (argv != NULL) {
+  if (argv != nullptr) {
     gCmdLine.reset(new std::string(argv[0]));
-    for (size_t i = 1; argv[i] != NULL; ++i) {
+    for (size_t i = 1; argv[i] != nullptr; ++i) {
       gCmdLine->append(" ");
       gCmdLine->append(argv[i]);
     }
     gProgramInvocationName.reset(new std::string(argv[0]));
     const char* last_slash = strrchr(argv[0], '/');
-    gProgramInvocationShortName.reset(new std::string((last_slash != NULL) ? last_slash + 1
+    gProgramInvocationShortName.reset(new std::string((last_slash != nullptr) ? last_slash + 1
                                                                            : argv[0]));
   } else {
-    // TODO: fall back to /proc/self/cmdline when argv is NULL on Linux
+    // TODO: fall back to /proc/self/cmdline when argv is NULL on Linux.
     gCmdLine.reset(new std::string("<unset>"));
   }
   const char* tags = getenv("ANDROID_LOG_TAGS");
-  if (tags == NULL) {
+  if (tags == nullptr) {
     return;
   }
 
@@ -119,47 +119,121 @@
   }
 }
 
-LogMessageData::LogMessageData(const char* file, int line, LogSeverity severity, int error)
-    : file(file),
-      line_number(line),
-      severity(severity),
-      error(error) {
-  const char* last_slash = strrchr(file, '/');
-  file = (last_slash == NULL) ? file : last_slash + 1;
-}
+// This indirection greatly reduces the stack impact of having
+// lots of checks/logging in a function.
+class LogMessageData {
+ public:
+  LogMessageData(const char* file, unsigned int line, LogSeverity severity, int error)
+      : file_(file),
+        line_number_(line),
+        severity_(severity),
+        error_(error) {
+    const char* last_slash = strrchr(file, '/');
+    file = (last_slash == nullptr) ? file : last_slash + 1;
+  }
 
+  const char * GetFile() const {
+    return file_;
+  }
+
+  unsigned int GetLineNumber() const {
+    return line_number_;
+  }
+
+  LogSeverity GetSeverity() const {
+    return severity_;
+  }
+
+  int GetError() const {
+    return error_;
+  }
+
+  std::ostream& GetBuffer() {
+    return buffer_;
+  }
+
+  std::string ToString() const {
+    return buffer_.str();
+  }
+
+ private:
+  std::ostringstream buffer_;
+  const char* const file_;
+  const unsigned int line_number_;
+  const LogSeverity severity_;
+  const int error_;
+
+  DISALLOW_COPY_AND_ASSIGN(LogMessageData);
+};
+
+
+LogMessage::LogMessage(const char* file, unsigned int line, LogSeverity severity, int error)
+  : data_(new LogMessageData(file, line, severity, error)) {
+}
 LogMessage::~LogMessage() {
-  if (data_->severity < gMinimumLogSeverity) {
+  if (data_->GetSeverity() < gMinimumLogSeverity) {
     return;  // No need to format something we're not going to output.
   }
 
   // Finish constructing the message.
-  if (data_->error != -1) {
-    data_->buffer << ": " << strerror(data_->error);
+  if (data_->GetError() != -1) {
+    data_->GetBuffer() << ": " << strerror(data_->GetError());
   }
-  std::string msg(data_->buffer.str());
+  std::string msg(data_->ToString());
 
   // Do the actual logging with the lock held.
   {
     MutexLock mu(Thread::Current(), *Locks::logging_lock_);
     if (msg.find('\n') == std::string::npos) {
-      LogLine(*data_, msg.c_str());
+      LogLine(data_->GetFile(), data_->GetLineNumber(), data_->GetSeverity(), msg.c_str());
     } else {
       msg += '\n';
       size_t i = 0;
       while (i < msg.size()) {
         size_t nl = msg.find('\n', i);
         msg[nl] = '\0';
-        LogLine(*data_, &msg[i]);
+        LogLine(data_->GetFile(), data_->GetLineNumber(), data_->GetSeverity(), &msg[i]);
         i = nl + 1;
       }
     }
   }
 
   // Abort if necessary.
-  if (data_->severity == FATAL) {
+  if (data_->GetSeverity() == FATAL) {
     Runtime::Abort();
   }
 }
 
+std::ostream& LogMessage::stream() {
+  return data_->GetBuffer();
+}
+
+#ifdef HAVE_ANDROID_OS
+static const android_LogPriority kLogSeverityToAndroidLogPriority[] = {
+  ANDROID_LOG_VERBOSE, ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN,
+  ANDROID_LOG_ERROR, ANDROID_LOG_FATAL, ANDROID_LOG_FATAL
+};
+COMPILE_ASSERT(arraysize(kLogSeverityToAndroidLogPriority) == INTERNAL_FATAL + 1,
+               mismatch_in_size_of_kLogSeverityToAndroidLogPriority_and_values_in_LogSeverity);
+#endif
+
+void LogMessage::LogLine(const char* file, unsigned int line, LogSeverity log_severity,
+                         const char* message) {
+#ifdef HAVE_ANDROID_OS
+  const char* tag = ProgramInvocationShortName();
+  int priority = kLogSeverityToAndroidLogPriority[log_severity];
+  if (priority == ANDROID_LOG_FATAL) {
+    LOG_PRI(priority, tag, "%s:%u] %s", file, line, message);
+  } else {
+    LOG_PRI(priority, tag, "%s", message);
+  }
+#else
+  static const char* log_characters = "VDIWEFF";
+  CHECK_EQ(strlen(log_characters), INTERNAL_FATAL + 1U);
+  char severity = log_characters[log_severity];
+  fprintf(stderr, "%s %c %5d %5d %s:%u] %s\n",
+          ProgramInvocationShortName(), severity, getpid(), ::art::GetTid(), file, line, message);
+#endif
+}
+
 }  // namespace art
diff --git a/runtime/base/logging.h b/runtime/base/logging.h
index cf3e763..baa83e3 100644
--- a/runtime/base/logging.h
+++ b/runtime/base/logging.h
@@ -17,29 +17,113 @@
 #ifndef ART_RUNTIME_BASE_LOGGING_H_
 #define ART_RUNTIME_BASE_LOGGING_H_
 
-#include <cerrno>
-#include <cstring>
-#include <iostream>  // NOLINT
 #include <memory>
-#include <sstream>
-#include <signal.h>
-#include <vector>
+#include <ostream>
 
 #include "base/macros.h"
-#include "log_severity.h"
 
+namespace art {
+
+enum LogSeverity {
+  VERBOSE,
+  DEBUG,
+  INFO,
+  WARNING,
+  ERROR,
+  FATAL,
+  INTERNAL_FATAL,  // For Runtime::Abort.
+};
+
+// The members of this struct are the valid arguments to VLOG and VLOG_IS_ON in code,
+// and the "-verbose:" command line argument.
+struct LogVerbosity {
+  bool class_linker;  // Enabled with "-verbose:class".
+  bool compiler;
+  bool gc;
+  bool heap;
+  bool jdwp;
+  bool jni;
+  bool monitor;
+  bool profiler;
+  bool signals;
+  bool startup;
+  bool third_party_jni;  // Enabled with "-verbose:third-party-jni".
+  bool threads;
+  bool verifier;
+};
+
+// Global log verbosity setting, initialized by InitLogging.
+extern LogVerbosity gLogVerbosity;
+
+// 0 if not abort, non-zero if an abort is in progress. Used on fatal exit to prevents recursive
+// aborts. Global declaration allows us to disable some error checking to ensure fatal shutdown
+// makes forward progress.
+extern unsigned int gAborting;
+
+// Configure logging based on ANDROID_LOG_TAGS environment variable.
+// We need to parse a string that looks like
+//
+//      *:v jdwp:d dalvikvm:d dalvikvm-gc:i dalvikvmi:i
+//
+// The tag (or '*' for the global level) comes first, followed by a colon
+// and a letter indicating the minimum priority level we're expected to log.
+// This can be used to reveal or conceal logs with specific tags.
+extern void InitLogging(char* argv[]);
+
+// Returns the command line used to invoke the current tool or nullptr if InitLogging hasn't been
+// performed.
+extern const char* GetCmdLine();
+
+// The command used to start the ART runtime, such as "/system/bin/dalvikvm". If InitLogging hasn't
+// been performed then just returns "art"
+extern const char* ProgramInvocationName();
+
+// A short version of the command used to start the ART runtime, such as "dalvikvm". If InitLogging
+// hasn't been performed then just returns "art"
+extern const char* ProgramInvocationShortName();
+
+// Logs a message to logcat on Android otherwise to stderr. If the severity is FATAL it also causes
+// an abort. For example: LOG(FATAL) << "We didn't expect to reach here";
+#define LOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, -1).stream()
+
+// A variant of LOG that also logs the current errno value. To be used when library calls fail.
+#define PLOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, errno).stream()
+
+// Marker that code is yet to be implemented.
+#define UNIMPLEMENTED(level) LOG(level) << __PRETTY_FUNCTION__ << " unimplemented "
+
+// Is verbose logging enabled for the given module? Where the module is defined in LogVerbosity.
+#define VLOG_IS_ON(module) UNLIKELY(::art::gLogVerbosity.module)
+
+// Variant of LOG that logs when verbose logging is enabled for a module. For example,
+// VLOG(jni) << "A JNI operation was performed";
+#define VLOG(module) \
+  if (VLOG_IS_ON(module)) \
+    ::art::LogMessage(__FILE__, __LINE__, INFO, -1).stream()
+
+// Return the stream associated with logging for the given module.
+#define VLOG_STREAM(module) ::art::LogMessage(__FILE__, __LINE__, INFO, -1).stream()
+
+// Check whether condition x holds and LOG(FATAL) if not. The value of the expression x is only
+// evaluated once. Extra logging can be appended using << after. For example,
+// CHECK(false == true) results in a log message of "Check failed: false == true".
 #define CHECK(x) \
   if (UNLIKELY(!(x))) \
-    ::art::LogMessage(__FILE__, __LINE__, FATAL, -1).stream() \
+    ::art::LogMessage(__FILE__, __LINE__, ::art::FATAL, -1).stream() \
         << "Check failed: " #x << " "
 
+// Helper for CHECK_xx(x,y) macros.
 #define CHECK_OP(LHS, RHS, OP) \
   for (auto _values = ::art::MakeEagerEvaluator(LHS, RHS); \
        UNLIKELY(!(_values.lhs OP _values.rhs)); /* empty */) \
-    ::art::LogMessage(__FILE__, __LINE__, FATAL, -1).stream() \
+    ::art::LogMessage(__FILE__, __LINE__, ::art::FATAL, -1).stream() \
         << "Check failed: " << #LHS << " " << #OP << " " << #RHS \
         << " (" #LHS "=" << _values.lhs << ", " #RHS "=" << _values.rhs << ") "
 
+
+// Check whether a condition holds between x and y, LOG(FATAL) if not. The value of the expressions
+// x and y is evaluated once. Extra logging can be appended using << after. For example,
+// CHECK_NE(0 == 1, false) results in "Check failed: false != false (0==1=false, false=false) ".
 #define CHECK_EQ(x, y) CHECK_OP(x, y, ==)
 #define CHECK_NE(x, y) CHECK_OP(x, y, !=)
 #define CHECK_LE(x, y) CHECK_OP(x, y, <=)
@@ -47,22 +131,25 @@
 #define CHECK_GE(x, y) CHECK_OP(x, y, >=)
 #define CHECK_GT(x, y) CHECK_OP(x, y, >)
 
+// Helper for CHECK_STRxx(s1,s2) macros.
 #define CHECK_STROP(s1, s2, sense) \
   if (UNLIKELY((strcmp(s1, s2) == 0) != sense)) \
-    LOG(FATAL) << "Check failed: " \
-               << "\"" << s1 << "\"" \
-               << (sense ? " == " : " != ") \
-               << "\"" << s2 << "\""
+    LOG(::art::FATAL) << "Check failed: " \
+        << "\"" << s1 << "\"" \
+        << (sense ? " == " : " != ") \
+        << "\"" << s2 << "\""
 
+// Check for string (const char*) equality between s1 and s2, LOG(FATAL) if not.
 #define CHECK_STREQ(s1, s2) CHECK_STROP(s1, s2, true)
 #define CHECK_STRNE(s1, s2) CHECK_STROP(s1, s2, false)
 
+// Perform the pthread function call(args), LOG(FATAL) on error.
 #define CHECK_PTHREAD_CALL(call, args, what) \
   do { \
     int rc = call args; \
     if (rc != 0) { \
       errno = rc; \
-      PLOG(FATAL) << # call << " failed for " << what; \
+      PLOG(::art::FATAL) << # call << " failed for " << what; \
     } \
   } while (false)
 
@@ -74,81 +161,34 @@
 //          n / 2;
 //    }
 #define CHECK_CONSTEXPR(x, out, dummy) \
-  (UNLIKELY(!(x))) ? (LOG(FATAL) << "Check failed: " << #x out, dummy) :
+  (UNLIKELY(!(x))) ? (LOG(::art::FATAL) << "Check failed: " << #x out, dummy) :
 
-#ifndef NDEBUG
 
-#define DCHECK(x) CHECK(x)
-#define DCHECK_EQ(x, y) CHECK_EQ(x, y)
-#define DCHECK_NE(x, y) CHECK_NE(x, y)
-#define DCHECK_LE(x, y) CHECK_LE(x, y)
-#define DCHECK_LT(x, y) CHECK_LT(x, y)
-#define DCHECK_GE(x, y) CHECK_GE(x, y)
-#define DCHECK_GT(x, y) CHECK_GT(x, y)
-#define DCHECK_STREQ(s1, s2) CHECK_STREQ(s1, s2)
-#define DCHECK_STRNE(s1, s2) CHECK_STRNE(s1, s2)
-#define DCHECK_CONSTEXPR(x, out, dummy) CHECK_CONSTEXPR(x, out, dummy)
-
-#else  // NDEBUG
-
-#define DCHECK(condition) \
-  while (false) \
-    CHECK(condition)
-
-#define DCHECK_EQ(val1, val2) \
-  while (false) \
-    CHECK_EQ(val1, val2)
-
-#define DCHECK_NE(val1, val2) \
-  while (false) \
-    CHECK_NE(val1, val2)
-
-#define DCHECK_LE(val1, val2) \
-  while (false) \
-    CHECK_LE(val1, val2)
-
-#define DCHECK_LT(val1, val2) \
-  while (false) \
-    CHECK_LT(val1, val2)
-
-#define DCHECK_GE(val1, val2) \
-  while (false) \
-    CHECK_GE(val1, val2)
-
-#define DCHECK_GT(val1, val2) \
-  while (false) \
-    CHECK_GT(val1, val2)
-
-#define DCHECK_STREQ(str1, str2) \
-  while (false) \
-    CHECK_STREQ(str1, str2)
-
-#define DCHECK_STRNE(str1, str2) \
-  while (false) \
-    CHECK_STRNE(str1, str2)
-
-#define DCHECK_CONSTEXPR(x, out, dummy) \
-  (false && (x)) ? (dummy) :
-
+// DCHECKs are debug variants of CHECKs only enabled in debug builds. Generally CHECK should be
+// used unless profiling identifies a CHECK as being in performance critical code.
+#if defined(NDEBUG)
+static constexpr bool kEnableDChecks = false;
+#else
+static constexpr bool kEnableDChecks = true;
 #endif
 
-#define LOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, -1).stream()
-#define PLOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, errno).stream()
+#define DCHECK(x) if (::art::kEnableDChecks) CHECK(x)
+#define DCHECK_EQ(x, y) if (::art::kEnableDChecks) CHECK_EQ(x, y)
+#define DCHECK_NE(x, y) if (::art::kEnableDChecks) CHECK_NE(x, y)
+#define DCHECK_LE(x, y) if (::art::kEnableDChecks) CHECK_LE(x, y)
+#define DCHECK_LT(x, y) if (::art::kEnableDChecks) CHECK_LT(x, y)
+#define DCHECK_GE(x, y) if (::art::kEnableDChecks) CHECK_GE(x, y)
+#define DCHECK_GT(x, y) if (::art::kEnableDChecks) CHECK_GT(x, y)
+#define DCHECK_STREQ(s1, s2) if (::art::kEnableDChecks) CHECK_STREQ(s1, s2)
+#define DCHECK_STRNE(s1, s2) if (::art::kEnableDChecks) CHECK_STRNE(s1, s2)
+#if defined(NDEBUG)
+#define DCHECK_CONSTEXPR(x, out, dummy)
+#else
+#define DCHECK_CONSTEXPR(x, out, dummy) CHECK_CONSTEXPR(x, out, dummy)
+#endif
 
-#define LG LOG(INFO)
-
-#define UNIMPLEMENTED(level) LOG(level) << __PRETTY_FUNCTION__ << " unimplemented "
-
-#define VLOG_IS_ON(module) UNLIKELY(::art::gLogVerbosity.module)
-#define VLOG(module) if (VLOG_IS_ON(module)) ::art::LogMessage(__FILE__, __LINE__, INFO, -1).stream()
-#define VLOG_STREAM(module) ::art::LogMessage(__FILE__, __LINE__, INFO, -1).stream()
-
-//
-// Implementation details beyond this point.
-//
-
-namespace art {
-
+// Temporary class created to evaluate the LHS and RHS, used with MakeEagerEvaluator to infer the
+// types of LHS and RHS.
 template <typename LHS, typename RHS>
 struct EagerEvaluator {
   EagerEvaluator(LHS l, RHS r) : lhs(l), rhs(r) { }
@@ -156,10 +196,14 @@
   RHS rhs;
 };
 
-// We want char*s to be treated as pointers, not strings. If you want them treated like strings,
-// you'd need to use CHECK_STREQ and CHECK_STRNE anyway to compare the characters rather than their
-// addresses. We could express this more succinctly with std::remove_const, but this is quick and
-// easy to understand, and works before we have C++0x. We rely on signed/unsigned warnings to
+// Helper function for CHECK_xx.
+template <typename LHS, typename RHS>
+static inline EagerEvaluator<LHS, RHS> MakeEagerEvaluator(LHS lhs, RHS rhs) {
+  return EagerEvaluator<LHS, RHS>(lhs, rhs);
+}
+
+// Explicitly instantiate EagerEvalue for pointers so that char*s aren't treated as strings. To
+// compare strings use CHECK_STREQ and CHECK_STRNE. We rely on signed/unsigned warnings to
 // protect you against combinations not explicitly listed below.
 #define EAGER_PTR_EVALUATOR(T1, T2) \
   template <> struct EagerEvaluator<T1, T2> { \
@@ -182,153 +226,30 @@
 EAGER_PTR_EVALUATOR(signed char*, const signed char*);
 EAGER_PTR_EVALUATOR(signed char*, signed char*);
 
-template <typename LHS, typename RHS>
-EagerEvaluator<LHS, RHS> MakeEagerEvaluator(LHS lhs, RHS rhs) {
-  return EagerEvaluator<LHS, RHS>(lhs, rhs);
-}
+// Data for the log message, not stored in LogMessage to avoid increasing the stack size.
+class LogMessageData;
 
-// This indirection greatly reduces the stack impact of having
-// lots of checks/logging in a function.
-struct LogMessageData {
- public:
-  LogMessageData(const char* file, int line, LogSeverity severity, int error);
-  std::ostringstream buffer;
-  const char* const file;
-  const int line_number;
-  const LogSeverity severity;
-  const int error;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(LogMessageData);
-};
-
+// A LogMessage is a temporarily scoped object used by LOG and the unlikely part of a CHECK. The
+// destructor will abort if the severity is FATAL.
 class LogMessage {
  public:
-  LogMessage(const char* file, int line, LogSeverity severity, int error)
-    : data_(new LogMessageData(file, line, severity, error)) {
-  }
+  LogMessage(const char* file, unsigned int line, LogSeverity severity, int error);
 
   ~LogMessage();  // TODO: enable LOCKS_EXCLUDED(Locks::logging_lock_).
 
-  std::ostream& stream() {
-    return data_->buffer;
-  }
+  // Returns the stream associated with the message, the LogMessage performs output when it goes
+  // out of scope.
+  std::ostream& stream();
+
+  // The routine that performs the actual logging.
+  static void LogLine(const char* file, unsigned int line, LogSeverity severity, const char* msg);
 
  private:
-  static void LogLine(const LogMessageData& data, const char*);
-
   const std::unique_ptr<LogMessageData> data_;
 
-  friend void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context);
-  friend class Mutex;
   DISALLOW_COPY_AND_ASSIGN(LogMessage);
 };
 
-// A convenience to allow any class with a "Dump(std::ostream& os)" member function
-// but without an operator<< to be used as if it had an operator<<. Use like this:
-//
-//   os << Dumpable<MyType>(my_type_instance);
-//
-template<typename T>
-class Dumpable {
- public:
-  explicit Dumpable(T& value) : value_(value) {
-  }
-
-  void Dump(std::ostream& os) const {
-    value_.Dump(os);
-  }
-
- private:
-  T& value_;
-
-  DISALLOW_COPY_AND_ASSIGN(Dumpable);
-};
-
-template<typename T>
-std::ostream& operator<<(std::ostream& os, const Dumpable<T>& rhs) {
-  rhs.Dump(os);
-  return os;
-}
-
-template<typename T>
-class ConstDumpable {
- public:
-  explicit ConstDumpable(const T& value) : value_(value) {
-  }
-
-  void Dump(std::ostream& os) const {
-    value_.Dump(os);
-  }
-
- private:
-  const T& value_;
-
-  DISALLOW_COPY_AND_ASSIGN(ConstDumpable);
-};
-
-template<typename T>
-std::ostream& operator<<(std::ostream& os, const ConstDumpable<T>& rhs) {
-  rhs.Dump(os);
-  return os;
-}
-
-// Helps you use operator<< in a const char*-like context such as our various 'F' methods with
-// format strings.
-template<typename T>
-class ToStr {
- public:
-  explicit ToStr(const T& value) {
-    std::ostringstream os;
-    os << value;
-    s_ = os.str();
-  }
-
-  const char* c_str() const {
-    return s_.c_str();
-  }
-
-  const std::string& str() const {
-    return s_;
-  }
-
- private:
-  std::string s_;
-  DISALLOW_COPY_AND_ASSIGN(ToStr);
-};
-
-// The members of this struct are the valid arguments to VLOG and VLOG_IS_ON in code,
-// and the "-verbose:" command line argument.
-struct LogVerbosity {
-  bool class_linker;  // Enabled with "-verbose:class".
-  bool compiler;
-  bool gc;
-  bool heap;
-  bool jdwp;
-  bool jni;
-  bool monitor;
-  bool profiler;
-  bool signals;
-  bool startup;
-  bool third_party_jni;  // Enabled with "-verbose:third-party-jni".
-  bool threads;
-  bool verifier;
-};
-
-extern LogVerbosity gLogVerbosity;
-
-extern std::vector<std::string> gVerboseMethods;
-
-// Used on fatal exit. Prevents recursive aborts. Allows us to disable
-// some error checking to ensure fatal shutdown makes forward progress.
-extern unsigned int gAborting;
-
-extern void InitLogging(char* argv[]);
-
-extern const char* GetCmdLine();
-extern const char* ProgramInvocationName();
-extern const char* ProgramInvocationShortName();
-
 }  // namespace art
 
 #endif  // ART_RUNTIME_BASE_LOGGING_H_
diff --git a/runtime/base/logging_android.cc b/runtime/base/logging_android.cc
deleted file mode 100644
index 9b1ac58..0000000
--- a/runtime/base/logging_android.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "logging.h"
-
-#include <unistd.h>
-
-#include <iostream>
-
-#include "base/stringprintf.h"
-#include "cutils/log.h"
-
-namespace art {
-
-static const int kLogSeverityToAndroidLogPriority[] = {
-  ANDROID_LOG_VERBOSE, ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN,
-  ANDROID_LOG_ERROR, ANDROID_LOG_FATAL, ANDROID_LOG_FATAL
-};
-
-void LogMessage::LogLine(const LogMessageData& data, const char* message) {
-  const char* tag = ProgramInvocationShortName();
-  int priority = kLogSeverityToAndroidLogPriority[data.severity];
-  if (priority == ANDROID_LOG_FATAL) {
-    LOG_PRI(priority, tag, "%s:%d] %s", data.file, data.line_number, message);
-  } else {
-    LOG_PRI(priority, tag, "%s", message);
-  }
-}
-
-}  // namespace art
diff --git a/runtime/base/logging_linux.cc b/runtime/base/logging_linux.cc
deleted file mode 100644
index 0399128..0000000
--- a/runtime/base/logging_linux.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "logging.h"
-
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <cstdio>
-#include <cstring>
-#include <iostream>
-
-#include "base/stringprintf.h"
-#include "utils.h"
-
-namespace art {
-
-void LogMessage::LogLine(const LogMessageData& data, const char* message) {
-  char severity = "VDIWEFF"[data.severity];
-  fprintf(stderr, "%s %c %5d %5d %s:%d] %s\n",
-          ProgramInvocationShortName(), severity, getpid(), ::art::GetTid(),
-          data.file, data.line_number, message);
-}
-
-}  // namespace art
diff --git a/runtime/base/macros.h b/runtime/base/macros.h
index c80d35e..febea61 100644
--- a/runtime/base/macros.h
+++ b/runtime/base/macros.h
@@ -68,22 +68,28 @@
 #define ART_FRIEND_TEST(test_set_name, individual_test)\
 friend class test_set_name##_##individual_test##_Test
 
-// DISALLOW_COPY_AND_ASSIGN disallows the copy and operator= functions.
-// It goes in the private: declarations in a class.
+// DISALLOW_COPY_AND_ASSIGN disallows the copy and operator= functions. It goes in the private:
+// declarations in a class.
 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
-  TypeName(const TypeName&);               \
-  void operator=(const TypeName&)
+  TypeName(const TypeName&) = delete;  \
+  void operator=(const TypeName&) = delete
 
-// A macro to disallow all the implicit constructors, namely the
-// default constructor, copy constructor and operator= functions.
+// A macro to disallow all the implicit constructors, namely the default constructor, copy
+// constructor and operator= functions.
 //
-// This should be used in the private: declarations for a class
-// that wants to prevent anyone from instantiating it. This is
-// especially useful for classes containing only static methods.
+// This should be used in the private: declarations for a class that wants to prevent anyone from
+// instantiating it. This is especially useful for classes containing only static methods.
 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
-  TypeName();                                    \
+  TypeName() = delete;  \
   DISALLOW_COPY_AND_ASSIGN(TypeName)
 
+// A macro to disallow new and delete operators for a class. It goes in the private: declarations.
+#define DISALLOW_ALLOCATION() \
+  public: \
+    ALWAYS_INLINE void operator delete(void*, size_t) { UNREACHABLE(); } \
+  private: \
+    void* operator new(size_t) = delete
+
 // The arraysize(arr) macro returns the # of elements in an array arr.
 // The expression is a compile-time constant, and therefore can be
 // used in defining new arrays, for example.  If you use arraysize on
diff --git a/runtime/base/mutex-inl.h b/runtime/base/mutex-inl.h
index f70db35..e066787 100644
--- a/runtime/base/mutex-inl.h
+++ b/runtime/base/mutex-inl.h
@@ -21,11 +21,8 @@
 
 #include "mutex.h"
 
-#define ATRACE_TAG ATRACE_TAG_DALVIK
-
-#include "cutils/trace.h"
-
 #include "base/stringprintf.h"
+#include "base/value_object.h"
 #include "runtime.h"
 #include "thread.h"
 
@@ -44,35 +41,6 @@
 }
 #endif  // ART_USE_FUTEXES
 
-class ScopedContentionRecorder {
- public:
-  ScopedContentionRecorder(BaseMutex* mutex, uint64_t blocked_tid, uint64_t owner_tid)
-      : mutex_(kLogLockContentions ? mutex : NULL),
-        blocked_tid_(kLogLockContentions ? blocked_tid : 0),
-        owner_tid_(kLogLockContentions ? owner_tid : 0),
-        start_nano_time_(kLogLockContentions ? NanoTime() : 0) {
-    if (ATRACE_ENABLED()) {
-      std::string msg = StringPrintf("Lock contention on %s (owner tid: %" PRIu64 ")",
-                                     mutex->GetName(), owner_tid);
-      ATRACE_BEGIN(msg.c_str());
-    }
-  }
-
-  ~ScopedContentionRecorder() {
-    ATRACE_END();
-    if (kLogLockContentions) {
-      uint64_t end_nano_time = NanoTime();
-      mutex_->RecordContention(blocked_tid_, owner_tid_, end_nano_time - start_nano_time_);
-    }
-  }
-
- private:
-  BaseMutex* const mutex_;
-  const uint64_t blocked_tid_;
-  const uint64_t owner_tid_;
-  const uint64_t start_nano_time_;
-};
-
 static inline uint64_t SafeGetTid(const Thread* self) {
   if (self != NULL) {
     return static_cast<uint64_t>(self->GetTid());
@@ -158,15 +126,7 @@
       // Add as an extra reader.
       done = state_.CompareExchangeWeakAcquire(cur_state, cur_state + 1);
     } else {
-      // Owner holds it exclusively, hang up.
-      ScopedContentionRecorder scr(this, GetExclusiveOwnerTid(), SafeGetTid(self));
-      ++num_pending_readers_;
-      if (futex(state_.Address(), FUTEX_WAIT, cur_state, NULL, NULL, 0) != 0) {
-        if (errno != EAGAIN) {
-          PLOG(FATAL) << "futex wait failed for " << name_;
-        }
-      }
-      --num_pending_readers_;
+      HandleSharedLockContention(self, cur_state);
     }
   } while (!done);
 #else
diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc
index 70b6f7e..6362a98 100644
--- a/runtime/base/mutex.cc
+++ b/runtime/base/mutex.cc
@@ -19,8 +19,12 @@
 #include <errno.h>
 #include <sys/time.h>
 
+#define ATRACE_TAG ATRACE_TAG_DALVIK
+#include "cutils/trace.h"
+
 #include "atomic.h"
 #include "base/logging.h"
+#include "base/value_object.h"
 #include "mutex-inl.h"
 #include "runtime.h"
 #include "scoped_thread_state_change.h"
@@ -106,6 +110,36 @@
   const BaseMutex* const mutex_;
 };
 
+// Scoped class that generates events at the beginning and end of lock contention.
+class ScopedContentionRecorder FINAL : public ValueObject {
+ public:
+  ScopedContentionRecorder(BaseMutex* mutex, uint64_t blocked_tid, uint64_t owner_tid)
+      : mutex_(kLogLockContentions ? mutex : NULL),
+        blocked_tid_(kLogLockContentions ? blocked_tid : 0),
+        owner_tid_(kLogLockContentions ? owner_tid : 0),
+        start_nano_time_(kLogLockContentions ? NanoTime() : 0) {
+    if (ATRACE_ENABLED()) {
+      std::string msg = StringPrintf("Lock contention on %s (owner tid: %" PRIu64 ")",
+                                     mutex->GetName(), owner_tid);
+      ATRACE_BEGIN(msg.c_str());
+    }
+  }
+
+  ~ScopedContentionRecorder() {
+    ATRACE_END();
+    if (kLogLockContentions) {
+      uint64_t end_nano_time = NanoTime();
+      mutex_->RecordContention(blocked_tid_, owner_tid_, end_nano_time - start_nano_time_);
+    }
+  }
+
+ private:
+  BaseMutex* const mutex_;
+  const uint64_t blocked_tid_;
+  const uint64_t owner_tid_;
+  const uint64_t start_nano_time_;
+};
+
 BaseMutex::BaseMutex(const char* name, LockLevel level) : level_(level), name_(name) {
   if (kLogLockContentions) {
     ScopedAllMutexesLock mu(this);
@@ -428,9 +462,9 @@
         if (this != Locks::logging_lock_) {
           LOG(FATAL) << "Unexpected state_ in unlock " << cur_state << " for " << name_;
         } else {
-          LogMessageData data(__FILE__, __LINE__, INTERNAL_FATAL, -1);
-          LogMessage::LogLine(data, StringPrintf("Unexpected state_ %d in unlock for %s",
-                                                 cur_state, name_).c_str());
+          LogMessage::LogLine(__FILE__, __LINE__, INTERNAL_FATAL,
+                              StringPrintf("Unexpected state_ %d in unlock for %s",
+                                           cur_state, name_).c_str());
           _exit(1);
         }
       }
@@ -612,6 +646,18 @@
 }
 #endif
 
+void ReaderWriterMutex::HandleSharedLockContention(Thread* self, int32_t cur_state) {
+  // Owner holds it exclusively, hang up.
+  ScopedContentionRecorder scr(this, GetExclusiveOwnerTid(), SafeGetTid(self));
+  ++num_pending_readers_;
+  if (futex(state_.Address(), FUTEX_WAIT, cur_state, NULL, NULL, 0) != 0) {
+    if (errno != EAGAIN) {
+      PLOG(FATAL) << "futex wait failed for " << name_;
+    }
+  }
+  --num_pending_readers_;
+}
+
 bool ReaderWriterMutex::SharedTryLock(Thread* self) {
   DCHECK(self == NULL || self == Thread::Current());
 #if ART_USE_FUTEXES
diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h
index 516fa07..25fdd59 100644
--- a/runtime/base/mutex.h
+++ b/runtime/base/mutex.h
@@ -360,6 +360,9 @@
   virtual void Dump(std::ostream& os) const;
 
  private:
+  // Out-of-inline path for handling contention for a SharedLock.
+  void HandleSharedLockContention(Thread* self, int32_t cur_state);
+
 #if ART_USE_FUTEXES
   // -1 implies held exclusive, +ve shared held by state_ many owners.
   AtomicInteger state_;
diff --git a/runtime/base/stringpiece.cc b/runtime/base/stringpiece.cc
index 824ee48..2570bad 100644
--- a/runtime/base/stringpiece.cc
+++ b/runtime/base/stringpiece.cc
@@ -16,7 +16,7 @@
 
 #include "stringpiece.h"
 
-#include <iostream>
+#include <ostream>
 #include <utility>
 
 #include "logging.h"
diff --git a/runtime/base/to_str.h b/runtime/base/to_str.h
new file mode 100644
index 0000000..6b1c84c
--- /dev/null
+++ b/runtime/base/to_str.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_BASE_TO_STR_H_
+#define ART_RUNTIME_BASE_TO_STR_H_
+
+#include <sstream>
+
+namespace art {
+
+// Helps you use operator<< in a const char*-like context such as our various 'F' methods with
+// format strings.
+template<typename T>
+class ToStr {
+ public:
+  explicit ToStr(const T& value) {
+    std::ostringstream os;
+    os << value;
+    s_ = os.str();
+  }
+
+  const char* c_str() const {
+    return s_.c_str();
+  }
+
+  const std::string& str() const {
+    return s_;
+  }
+
+ private:
+  std::string s_;
+  DISALLOW_COPY_AND_ASSIGN(ToStr);
+};
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_BASE_TO_STR_H_
diff --git a/runtime/base/unix_file/mapped_file.cc b/runtime/base/unix_file/mapped_file.cc
index 63927b1..77f4d02 100644
--- a/runtime/base/unix_file/mapped_file.cc
+++ b/runtime/base/unix_file/mapped_file.cc
@@ -42,7 +42,7 @@
   struct stat st;
   int result = TEMP_FAILURE_RETRY(fstat(Fd(), &st));
   if (result == -1) {
-    PLOG(WARNING) << "Failed to stat file '" << GetPath() << "'";
+    PLOG(::art::WARNING) << "Failed to stat file '" << GetPath() << "'";
     return false;
   }
   file_size_ = st.st_size;
@@ -50,8 +50,8 @@
     mapped_file_ = mmap(NULL, file_size_, PROT_READ, MAP_PRIVATE, Fd(), 0);
   } while (mapped_file_ == MAP_FAILED && errno == EINTR);
   if (mapped_file_ == MAP_FAILED) {
-    PLOG(WARNING) << "Failed to mmap file '" << GetPath() << "' of size "
-                  << file_size_ << " bytes to memory";
+    PLOG(::art::WARNING) << "Failed to mmap file '" << GetPath() << "' of size "
+        << file_size_ << " bytes to memory";
     return false;
   }
   map_mode_ = kMapReadOnly;
@@ -67,8 +67,7 @@
   int result = TEMP_FAILURE_RETRY(ftruncate(Fd(), file_size));
 #endif
   if (result == -1) {
-    PLOG(ERROR) << "Failed to truncate file '" << GetPath()
-                << "' to size " << file_size;
+    PLOG(::art::ERROR) << "Failed to truncate file '" << GetPath() << "' to size " << file_size;
     return false;
   }
   file_size_ = file_size;
@@ -77,7 +76,7 @@
         mmap(NULL, file_size_, PROT_READ | PROT_WRITE, MAP_SHARED, Fd(), 0);
   } while (mapped_file_ == MAP_FAILED && errno == EINTR);
   if (mapped_file_ == MAP_FAILED) {
-    PLOG(WARNING) << "Failed to mmap file '" << GetPath() << "' of size "
+    PLOG(::art::WARNING) << "Failed to mmap file '" << GetPath() << "' of size "
                   << file_size_ << " bytes to memory";
     return false;
   }
@@ -89,8 +88,7 @@
   CHECK(IsMapped());
   int result = TEMP_FAILURE_RETRY(munmap(mapped_file_, file_size_));
   if (result == -1) {
-    PLOG(WARNING) << "Failed unmap file '" << GetPath() << "' of size "
-                  << file_size_;
+    PLOG(::art::WARNING) << "Failed unmap file '" << GetPath() << "' of size " << file_size_;
     return false;
   } else {
     mapped_file_ = NULL;
diff --git a/runtime/base/value_object.h b/runtime/base/value_object.h
index ee0e2a0..8c752a9 100644
--- a/runtime/base/value_object.h
+++ b/runtime/base/value_object.h
@@ -17,19 +17,13 @@
 #ifndef ART_RUNTIME_BASE_VALUE_OBJECT_H_
 #define ART_RUNTIME_BASE_VALUE_OBJECT_H_
 
-#include "base/logging.h"
+#include "base/macros.h"
 
 namespace art {
 
 class ValueObject {
- public:
-  void* operator new(size_t size) {
-    LOG(FATAL) << "UNREACHABLE";
-    abort();
-  }
-  void operator delete(void*, size_t) {
-    LOG(FATAL) << "UNREACHABLE";
-  }
+ private:
+  DISALLOW_ALLOCATION();
 };
 
 }  // namespace art
diff --git a/runtime/check_jni.cc b/runtime/check_jni.cc
index fec1824..b2df091 100644
--- a/runtime/check_jni.cc
+++ b/runtime/check_jni.cc
@@ -20,6 +20,7 @@
 #include <zlib.h>
 
 #include "base/logging.h"
+#include "base/to_str.h"
 #include "class_linker.h"
 #include "class_linker-inl.h"
 #include "dex_file-inl.h"
diff --git a/runtime/check_reference_map_visitor.h b/runtime/check_reference_map_visitor.h
index 8c2293f..9d2d59c 100644
--- a/runtime/check_reference_map_visitor.h
+++ b/runtime/check_reference_map_visitor.h
@@ -37,7 +37,7 @@
       CHECK_EQ(GetDexPc(), DexFile::kDexNoIndex);
     }
 
-    if (!m || m->IsNative() || m->IsRuntimeMethod() || IsShadowFrame()) {
+    if (m == nullptr || m->IsNative() || m->IsRuntimeMethod() || IsShadowFrame()) {
       return true;
     }
 
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index bbbb9e0..f6717fb 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -17,6 +17,7 @@
 #include "class_linker.h"
 
 #include <deque>
+#include <iostream>
 #include <memory>
 #include <queue>
 #include <string>
@@ -5110,7 +5111,7 @@
     bool seen_non_ref = false;
     for (size_t i = 0; i < num_fields; i++) {
       mirror::ArtField* field = fields->Get(i);
-      if (false) {  // enable to debug field layout
+      if ((false)) {  // enable to debug field layout
         LOG(INFO) << "LinkFields: " << (is_static ? "static" : "instance")
                     << " class=" << PrettyClass(klass.Get())
                     << " field=" << PrettyField(field)
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index ea3da64..6e3ebc2 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -44,7 +44,7 @@
 
 int main(int argc, char **argv) {
   art::InitLogging(argv);
-  LOG(INFO) << "Running main() from common_runtime_test.cc...";
+  LOG(::art::INFO) << "Running main() from common_runtime_test.cc...";
   testing::InitGoogleTest(&argc, argv);
   return RUN_ALL_TESTS();
 }
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index b676c62..18bbc38 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -4116,7 +4116,6 @@
   HeapChunkContext(bool merge, bool native)
       : buf_(16384 - 16),
         type_(0),
-        merge_(merge),
         chunk_overhead_(0) {
     Reset();
     if (native) {
@@ -4327,7 +4326,6 @@
   void* startOfNextMemoryChunk_;
   size_t totalAllocationUnits_;
   uint32_t type_;
-  bool merge_;
   bool needHeader_;
   size_t chunk_overhead_;
 
@@ -4678,7 +4676,7 @@
  * between the contents of these tables.
  */
 jbyteArray Dbg::GetRecentAllocations() {
-  if (false) {
+  if ((false)) {
     DumpRecentAllocations();
   }
 
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index f408386..78cbe58 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -23,7 +23,9 @@
 #include <string.h>
 #include <sys/file.h>
 #include <sys/stat.h>
+
 #include <memory>
+#include <sstream>
 
 #include "base/logging.h"
 #include "base/stringprintf.h"
diff --git a/runtime/dex_instruction.cc b/runtime/dex_instruction.cc
index 7e775f4..af38433 100644
--- a/runtime/dex_instruction.cc
+++ b/runtime/dex_instruction.cc
@@ -19,6 +19,7 @@
 #include <inttypes.h>
 
 #include <iomanip>
+#include <sstream>
 
 #include "base/stringprintf.h"
 #include "dex_file-inl.h"
diff --git a/runtime/dex_instruction_visitor_test.cc b/runtime/dex_instruction_visitor_test.cc
index c5e63eb..5273084 100644
--- a/runtime/dex_instruction_visitor_test.cc
+++ b/runtime/dex_instruction_visitor_test.cc
@@ -16,7 +16,6 @@
 
 #include "dex_instruction_visitor.h"
 
-#include <iostream>
 #include <memory>
 
 #include "gtest/gtest.h"
diff --git a/runtime/dex_method_iterator_test.cc b/runtime/dex_method_iterator_test.cc
index b8f180b..c6f333f 100644
--- a/runtime/dex_method_iterator_test.cc
+++ b/runtime/dex_method_iterator_test.cc
@@ -38,8 +38,8 @@
     const DexFile& dex_file = it.GetDexFile();
     InvokeType invoke_type = it.GetInvokeType();
     uint32_t method_idx = it.GetMemberIndex();
-    if (false) {
-      LG << invoke_type << " " << PrettyMethod(method_idx, dex_file);
+    if ((false)) {
+      LOG(INFO) << invoke_type << " " << PrettyMethod(method_idx, dex_file);
     }
     it.Next();
   }
diff --git a/runtime/elf_utils.h b/runtime/elf_utils.h
index 676cd52..7b00bad 100644
--- a/runtime/elf_utils.h
+++ b/runtime/elf_utils.h
@@ -24,6 +24,8 @@
 
 #include "base/logging.h"
 
+namespace art {
+
 // Architecture dependent flags for the ELF header.
 #define EF_ARM_EABI_VER5 0x05000000
 #define EF_MIPS_ABI_O32 0x00001000
@@ -163,4 +165,6 @@
   }
 }
 
+}  // namespace art
+
 #endif  // ART_RUNTIME_ELF_UTILS_H_
diff --git a/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc b/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc
index 6b3e9dc..f78273f 100644
--- a/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc
@@ -52,7 +52,7 @@
                                                               uint64_t fpr_result)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   // Compute address of return PC and sanity check that it currently holds 0.
-  uint32_t return_pc_offset = GetCalleeSaveReturnPcOffset(kRuntimeISA, Runtime::kRefsOnly);
+  size_t return_pc_offset = GetCalleeSaveReturnPcOffset(kRuntimeISA, Runtime::kRefsOnly);
   uintptr_t* return_pc = reinterpret_cast<uintptr_t*>(reinterpret_cast<uint8_t*>(sp) +
                                                       return_pc_offset);
   CHECK_EQ(*return_pc, 0U);
diff --git a/runtime/entrypoints/quick/quick_jni_entrypoints.cc b/runtime/entrypoints/quick/quick_jni_entrypoints.cc
index c239535..c1276b5 100644
--- a/runtime/entrypoints/quick/quick_jni_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_jni_entrypoints.cc
@@ -15,6 +15,7 @@
  */
 
 #include "entrypoints/entrypoint_utils-inl.h"
+#include "mirror/art_method-inl.h"
 #include "mirror/object-inl.h"
 #include "thread-inl.h"
 #include "verify_object-inl.h"
diff --git a/runtime/gc/allocator/dlmalloc.cc b/runtime/gc/allocator/dlmalloc.cc
index a6a3ee7..fbeba7f 100644
--- a/runtime/gc/allocator/dlmalloc.cc
+++ b/runtime/gc/allocator/dlmalloc.cc
@@ -39,11 +39,11 @@
 
 
 static void art_heap_corruption(const char* function) {
-  LOG(FATAL) << "Corrupt heap detected in: " << function;
+  LOG(::art::FATAL) << "Corrupt heap detected in: " << function;
 }
 
 static void art_heap_usage_error(const char* function, void* p) {
-  LOG(FATAL) << "Incorrect use of function '" << function << "' argument " << p << " not expected";
+  LOG(::art::FATAL) << "Incorrect use of function '" << function << "' argument " << p << " not expected";
 }
 
 #include "globals.h"
@@ -63,7 +63,7 @@
     int rc = madvise(start, length, MADV_DONTNEED);
     if (UNLIKELY(rc != 0)) {
       errno = rc;
-      PLOG(FATAL) << "madvise failed during heap trimming";
+      PLOG(::art::FATAL) << "madvise failed during heap trimming";
     }
     size_t* reclaimed = reinterpret_cast<size_t*>(arg);
     *reclaimed += length;
diff --git a/runtime/gc/allocator/rosalloc.cc b/runtime/gc/allocator/rosalloc.cc
index a3da532..fa531a7 100644
--- a/runtime/gc/allocator/rosalloc.cc
+++ b/runtime/gc/allocator/rosalloc.cc
@@ -24,6 +24,7 @@
 
 #include <map>
 #include <list>
+#include <sstream>
 #include <vector>
 
 namespace art {
@@ -1143,7 +1144,7 @@
 
 size_t RosAlloc::BulkFree(Thread* self, void** ptrs, size_t num_ptrs) {
   size_t freed_bytes = 0;
-  if (false) {
+  if ((false)) {
     // Used only to test Free() as GC uses only BulkFree().
     for (size_t i = 0; i < num_ptrs; ++i) {
       freed_bytes += FreeInternal(self, ptrs[i]);
diff --git a/runtime/gc/collector/garbage_collector.cc b/runtime/gc/collector/garbage_collector.cc
index 07b61e6..9e6a800 100644
--- a/runtime/gc/collector/garbage_collector.cc
+++ b/runtime/gc/collector/garbage_collector.cc
@@ -18,6 +18,10 @@
 
 #include "garbage_collector.h"
 
+#define ATRACE_TAG ATRACE_TAG_DALVIK
+#include "cutils/trace.h"
+
+#include "base/dumpable.h"
 #include "base/histogram-inl.h"
 #include "base/logging.h"
 #include "base/mutex-inl.h"
@@ -188,7 +192,7 @@
   if (iterations == 0) {
     return;
   }
-  os << ConstDumpable<CumulativeLogger>(logger);
+  os << Dumpable<CumulativeLogger>(logger);
   const uint64_t total_ns = logger.GetTotalNs();
   double seconds = NsToMs(logger.GetTotalNs()) / 1000.0;
   const uint64_t freed_bytes = GetTotalFreedBytes();
diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc
index 942b556..83da063 100644
--- a/runtime/gc/collector/mark_sweep.cc
+++ b/runtime/gc/collector/mark_sweep.cc
@@ -21,6 +21,9 @@
 #include <climits>
 #include <vector>
 
+#define ATRACE_TAG ATRACE_TAG_DALVIK
+#include "cutils/trace.h"
+
 #include "base/bounded_fifo.h"
 #include "base/logging.h"
 #include "base/macros.h"
diff --git a/runtime/gc/collector/semi_space.cc b/runtime/gc/collector/semi_space.cc
index 9459a3b..e141b6f 100644
--- a/runtime/gc/collector/semi_space.cc
+++ b/runtime/gc/collector/semi_space.cc
@@ -16,9 +16,10 @@
 
 #include "semi_space-inl.h"
 
+#include <climits>
 #include <functional>
 #include <numeric>
-#include <climits>
+#include <sstream>
 #include <vector>
 
 #include "base/logging.h"
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index b9d69d5..c2baa29 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -24,6 +24,7 @@
 #include <vector>
 
 #include "base/allocator.h"
+#include "base/dumpable.h"
 #include "base/histogram-inl.h"
 #include "base/stl_util.h"
 #include "common_throws.h"
@@ -2178,7 +2179,7 @@
               << percent_free << "% free, " << PrettySize(current_heap_size) << "/"
               << PrettySize(total_memory) << ", " << "paused " << pause_string.str()
               << " total " << PrettyDuration((duration / 1000) * 1000);
-    VLOG(heap) << ConstDumpable<TimingLogger>(*current_gc_iteration_.GetTimings());
+    VLOG(heap) << Dumpable<TimingLogger>(*current_gc_iteration_.GetTimings());
   }
   FinishGC(self, gc_type);
   // Inform DDMS that a GC completed.
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index ba85c55..ff1e38b 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -601,9 +601,6 @@
   void RemoveRememberedSet(space::Space* space);
 
   bool IsCompilingBoot() const;
-  bool RunningOnValgrind() const {
-    return running_on_valgrind_;
-  }
   bool HasImageSpace() const;
 
   ReferenceProcessor* GetReferenceProcessor() {
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 39d82cc..d479038 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -21,6 +21,7 @@
 
 #include <random>
 
+#include "base/macros.h"
 #include "base/stl_util.h"
 #include "base/unix_file/fd_file.h"
 #include "base/scoped_flock.h"
diff --git a/runtime/gc/space/malloc_space.h b/runtime/gc/space/malloc_space.h
index 7230116..cfde460 100644
--- a/runtime/gc/space/malloc_space.h
+++ b/runtime/gc/space/malloc_space.h
@@ -19,7 +19,7 @@
 
 #include "space.h"
 
-#include <iostream>
+#include <ostream>
 #include <valgrind.h>
 #include <memcheck/memcheck.h>
 
diff --git a/runtime/gc/space/rosalloc_space.cc b/runtime/gc/space/rosalloc_space.cc
index d25694a..161eba9 100644
--- a/runtime/gc/space/rosalloc_space.cc
+++ b/runtime/gc/space/rosalloc_space.cc
@@ -17,6 +17,9 @@
 
 #include "rosalloc_space-inl.h"
 
+#define ATRACE_TAG ATRACE_TAG_DALVIK
+#include "cutils/trace.h"
+
 #include "gc/accounting/card_table.h"
 #include "gc/accounting/space_bitmap-inl.h"
 #include "gc/heap.h"
@@ -73,8 +76,9 @@
   uint8_t* begin = mem_map->Begin();
   // TODO: Fix RosAllocSpace to support valgrind. There is currently some issues with
   // AllocationSize caused by redzones. b/12944686
-  if (false && Runtime::Current()->GetHeap()->RunningOnValgrind()) {
-    LOG(FATAL) << "Unimplemented";
+  if (Runtime::Current()->RunningOnValgrind()) {
+    UNIMPLEMENTED(FATAL);
+    UNREACHABLE();
   } else {
     return new RosAllocSpace(name, mem_map, rosalloc, begin, end, begin + capacity, growth_limit,
                              can_move_objects, starting_size, initial_size, low_memory_mode);
diff --git a/runtime/indirect_reference_table.cc b/runtime/indirect_reference_table.cc
index c1455fd..4d177a3 100644
--- a/runtime/indirect_reference_table.cc
+++ b/runtime/indirect_reference_table.cc
@@ -126,7 +126,7 @@
   }
   table_[index].Add(obj);
   result = ToIndirectRef(index);
-  if (false) {
+  if ((false)) {
     LOG(INFO) << "+++ added at " << ExtractIndex(result) << " top=" << segment_state_.parts.topIndex
               << " holes=" << segment_state_.parts.numHoles;
   }
@@ -193,7 +193,7 @@
     int numHoles = segment_state_.parts.numHoles - prevState.parts.numHoles;
     if (numHoles != 0) {
       while (--topIndex > bottomIndex && numHoles != 0) {
-        if (false) {
+        if ((false)) {
           LOG(INFO) << "+++ checking for hole at " << topIndex - 1
                     << " (cookie=" << cookie << ") val="
                     << table_[topIndex - 1].GetReference()->Read<kWithoutReadBarrier>();
@@ -201,7 +201,7 @@
         if (!table_[topIndex - 1].GetReference()->IsNull()) {
           break;
         }
-        if (false) {
+        if ((false)) {
           LOG(INFO) << "+++ ate hole at " << (topIndex - 1);
         }
         numHoles--;
@@ -210,7 +210,7 @@
       segment_state_.parts.topIndex = topIndex;
     } else {
       segment_state_.parts.topIndex = topIndex-1;
-      if (false) {
+      if ((false)) {
         LOG(INFO) << "+++ ate last entry " << topIndex - 1;
       }
     }
@@ -228,7 +228,7 @@
 
     *table_[idx].GetReference() = GcRoot<mirror::Object>(nullptr);
     segment_state_.parts.numHoles++;
-    if (false) {
+    if ((false)) {
       LOG(INFO) << "+++ left hole at " << idx << ", holes=" << segment_state_.parts.numHoles;
     }
   }
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index adbece0..f981522 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -18,12 +18,15 @@
 
 #include <sys/uio.h>
 
+#include <sstream>
+
 #include "arch/context.h"
 #include "atomic.h"
 #include "base/unix_file/fd_file.h"
 #include "class_linker.h"
 #include "debugger.h"
 #include "dex_file-inl.h"
+#include "entrypoints/quick/quick_entrypoints.h"
 #include "entrypoints/quick/quick_alloc_entrypoints.h"
 #include "entrypoints/runtime_asm_entrypoints.h"
 #include "gc_root-inl.h"
@@ -34,9 +37,6 @@
 #include "mirror/object_array-inl.h"
 #include "mirror/object-inl.h"
 #include "nth_caller_visitor.h"
-#if !defined(ART_USE_PORTABLE_COMPILER)
-#include "entrypoints/quick/quick_entrypoints.h"
-#endif
 #include "os.h"
 #include "scoped_thread_state_change.h"
 #include "thread.h"
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index a8345ad..fa03fc7 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -21,6 +21,9 @@
 
 #include <math.h>
 
+#include <iostream>
+#include <sstream>
+
 #include "base/logging.h"
 #include "class_linker-inl.h"
 #include "common_throws.h"
diff --git a/runtime/java_vm_ext.cc b/runtime/java_vm_ext.cc
index fed8bf0..19e03d8 100644
--- a/runtime/java_vm_ext.cc
+++ b/runtime/java_vm_ext.cc
@@ -18,6 +18,7 @@
 
 #include <dlfcn.h>
 
+#include "base/dumpable.h"
 #include "base/mutex.h"
 #include "base/stl_util.h"
 #include "check_jni.h"
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 70754f2..ad06b85 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -2705,7 +2705,7 @@
     os << "JNIWeakGlobalRefType";
     return os;
   default:
-    LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
-    return os;
+    LOG(::art::FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
+    UNREACHABLE();
   }
 }
diff --git a/runtime/log_severity.h b/runtime/log_severity.h
deleted file mode 100644
index 31682df..0000000
--- a/runtime/log_severity.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_RUNTIME_LOG_SEVERITY_H_
-#define ART_RUNTIME_LOG_SEVERITY_H_
-
-typedef int LogSeverity;
-
-const int VERBOSE = 0, DEBUG = 1, INFO = 2, WARNING = 3, ERROR = 4, FATAL = 5;
-const int INTERNAL_FATAL = 6;  // For Runtime::Abort.
-
-#endif  // ART_RUNTIME_LOG_SEVERITY_H_
diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc
index 3144ce1..c118471 100644
--- a/runtime/mem_map.cc
+++ b/runtime/mem_map.cc
@@ -15,11 +15,12 @@
  */
 
 #include "mem_map.h"
-#include "thread-inl.h"
 
-#include <inttypes.h>
 #include <backtrace/BacktraceMap.h>
+#include <inttypes.h>
+
 #include <memory>
+#include <sstream>
 
 // See CreateStartPos below.
 #ifdef __BIONIC__
@@ -28,6 +29,7 @@
 
 #include "base/stringprintf.h"
 #include "ScopedFd.h"
+#include "thread-inl.h"
 #include "utils.h"
 
 #define USE_ASHMEM 1
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index 1bbcf8e..b2b2420 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -478,6 +478,7 @@
   friend struct art::ObjectOffsets;  // for verifying offset information
   friend class CopyObjectVisitor;  // for CopyObject().
   friend class CopyClassVisitor;   // for CopyObject().
+  DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
 };
 
diff --git a/runtime/native/scoped_fast_native_object_access.h b/runtime/native/scoped_fast_native_object_access.h
index 606d62d..dfabff5 100644
--- a/runtime/native/scoped_fast_native_object_access.h
+++ b/runtime/native/scoped_fast_native_object_access.h
@@ -17,7 +17,7 @@
 #ifndef ART_RUNTIME_NATIVE_SCOPED_FAST_NATIVE_OBJECT_ACCESS_H_
 #define ART_RUNTIME_NATIVE_SCOPED_FAST_NATIVE_OBJECT_ACCESS_H_
 
-#include "mirror/art_method.h"
+#include "mirror/art_method-inl.h"
 #include "scoped_thread_state_change.h"
 
 namespace art {
diff --git a/runtime/offsets.cc b/runtime/offsets.cc
index 3691401..f59ed88 100644
--- a/runtime/offsets.cc
+++ b/runtime/offsets.cc
@@ -16,7 +16,7 @@
 
 #include "offsets.h"
 
-#include <iostream>  // NOLINT
+#include <ostream>
 
 namespace art {
 
diff --git a/runtime/offsets.h b/runtime/offsets.h
index 72a6b0f..9d5063f 100644
--- a/runtime/offsets.h
+++ b/runtime/offsets.h
@@ -17,7 +17,8 @@
 #ifndef ART_RUNTIME_OFFSETS_H_
 #define ART_RUNTIME_OFFSETS_H_
 
-#include <iostream>  // NOLINT
+#include <ostream>
+
 #include "globals.h"
 
 namespace art {
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index dcca9d3..6b64c25 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -16,6 +16,8 @@
 
 #include "parsed_options.h"
 
+#include <sstream>
+
 #ifdef HAVE_ANDROID_OS
 #include "cutils/properties.h"
 #endif
@@ -534,9 +536,6 @@
           return false;
         }
       }
-    } else if (StartsWith(option, "-verbose-methods:")) {
-      gLogVerbosity.compiler = false;
-      Split(option.substr(strlen("-verbose-methods:")), ',', &gVerboseMethods);
     } else if (StartsWith(option, "-Xlockprofthreshold:")) {
       if (!ParseUnsignedInteger(option, ':', &lock_profiling_threshold_)) {
         return false;
diff --git a/runtime/profiler.cc b/runtime/profiler.cc
index 1d06d35..e399195 100644
--- a/runtime/profiler.cc
+++ b/runtime/profiler.cc
@@ -97,7 +97,7 @@
   switch (profile_options.GetProfileType()) {
     case kProfilerMethod: {
       mirror::ArtMethod* method = thread->GetCurrentMethod(nullptr);
-      if (false && method == nullptr) {
+      if ((false) && method == nullptr) {
         LOG(INFO) << "No current method available";
         std::ostringstream os;
         thread->Dump(os);
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index 8e57837..c58735a 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -300,7 +300,7 @@
   InstrumentationStackVisitor(Thread* self, bool is_deoptimization, size_t frame_depth)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
       : StackVisitor(self, nullptr),
-        self_(self), frame_depth_(frame_depth),
+        frame_depth_(frame_depth),
         instrumentation_frames_to_pop_(0) {
     CHECK_NE(frame_depth_, kInvalidFrameDepth);
   }
@@ -324,7 +324,6 @@
   }
 
  private:
-  Thread* const self_;
   const size_t frame_depth_;
   size_t instrumentation_frames_to_pop_;
 
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 50cdf8e..8ba098f 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -45,6 +45,7 @@
 #include "arch/x86_64/registers_x86_64.h"
 #include "asm_support.h"
 #include "atomic.h"
+#include "base/dumpable.h"
 #include "base/unix_file/fd_file.h"
 #include "class_linker.h"
 #include "debugger.h"
@@ -208,7 +209,7 @@
 }
 
 struct AbortState {
-  void Dump(std::ostream& os) {
+  void Dump(std::ostream& os) const {
     if (gAborting > 1) {
       os << "Runtime aborting --- recursively, so no thread-specific detail!\n";
       return;
@@ -239,7 +240,7 @@
   }
 
   // No thread-safety analysis as we do explicitly test for holding the mutator lock.
-  void DumpThread(std::ostream& os, Thread* self) NO_THREAD_SAFETY_ANALYSIS {
+  void DumpThread(std::ostream& os, Thread* self) const NO_THREAD_SAFETY_ANALYSIS {
     DCHECK(Locks::mutator_lock_->IsExclusiveHeld(self) || Locks::mutator_lock_->IsSharedHeld(self));
     self->Dump(os);
     if (self->IsExceptionPending()) {
@@ -251,7 +252,7 @@
     }
   }
 
-  void DumpAllThreads(std::ostream& os, Thread* self) {
+  void DumpAllThreads(std::ostream& os, Thread* self) const {
     Runtime* runtime = Runtime::Current();
     if (runtime != nullptr) {
       ThreadList* thread_list = runtime->GetThreadList();
diff --git a/runtime/runtime_android.cc b/runtime/runtime_android.cc
index 079d7e5..33600dd 100644
--- a/runtime/runtime_android.cc
+++ b/runtime/runtime_android.cc
@@ -32,13 +32,12 @@
 
 struct sigaction old_action;
 void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) {
-  static bool handlingUnexpectedSignal = false;
-  if (handlingUnexpectedSignal) {
-    LogMessageData data(__FILE__, __LINE__, INTERNAL_FATAL, -1);
-    LogMessage::LogLine(data, "HandleUnexpectedSignal reentered\n");
+  static bool handling_unexpected_signal = false;
+  if (handling_unexpected_signal) {
+    LogMessage::LogLine(__FILE__, __LINE__, INTERNAL_FATAL, "HandleUnexpectedSignal reentered\n");
     _exit(1);
   }
-  handlingUnexpectedSignal = true;
+  handling_unexpected_signal = true;
   gAborting++;  // set before taking any locks
   MutexLock mu(Thread::Current(), *Locks::unexpected_signal_lock_);
 
diff --git a/runtime/runtime_linux.cc b/runtime/runtime_linux.cc
index 46ee274..1de035c 100644
--- a/runtime/runtime_linux.cc
+++ b/runtime/runtime_linux.cc
@@ -21,6 +21,9 @@
 #include <sys/utsname.h>
 #include <inttypes.h>
 
+#include <sstream>
+
+#include "base/dumpable.h"
 #include "base/logging.h"
 #include "base/mutex.h"
 #include "base/stringprintf.h"
@@ -32,13 +35,13 @@
 static constexpr bool kDumpHeapObjectOnSigsevg = false;
 
 struct Backtrace {
-  void Dump(std::ostream& os) {
+  void Dump(std::ostream& os) const {
     DumpNativeStack(os, GetTid(), "\t");
   }
 };
 
 struct OsInfo {
-  void Dump(std::ostream& os) {
+  void Dump(std::ostream& os) const {
     utsname info;
     uname(&info);
     // Linux 2.6.38.8-gg784 (x86_64)
@@ -132,9 +135,11 @@
 }
 
 struct UContext {
-  explicit UContext(void* raw_context) : context(reinterpret_cast<ucontext_t*>(raw_context)->uc_mcontext) {}
+  explicit UContext(void* raw_context) :
+      context(reinterpret_cast<ucontext_t*>(raw_context)->uc_mcontext) {
+  }
 
-  void Dump(std::ostream& os) {
+  void Dump(std::ostream& os) const {
     // TODO: support non-x86 hosts (not urgent because this code doesn't run on targets).
 #if defined(__APPLE__) && defined(__i386__)
     DumpRegister32(os, "eax", context->__ss.__eax);
@@ -228,15 +233,15 @@
 #endif
   }
 
-  void DumpRegister32(std::ostream& os, const char* name, uint32_t value) {
+  void DumpRegister32(std::ostream& os, const char* name, uint32_t value) const {
     os << StringPrintf(" %6s: 0x%08x", name, value);
   }
 
-  void DumpRegister64(std::ostream& os, const char* name, uint64_t value) {
+  void DumpRegister64(std::ostream& os, const char* name, uint64_t value) const {
     os << StringPrintf(" %6s: 0x%016" PRIx64, name, value);
   }
 
-  void DumpX86Flags(std::ostream& os, uint32_t flags) {
+  void DumpX86Flags(std::ostream& os, uint32_t flags) const {
     os << " [";
     if ((flags & (1 << 0)) != 0) {
       os << " CF";
@@ -274,8 +279,7 @@
 void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) {
   static bool handlingUnexpectedSignal = false;
   if (handlingUnexpectedSignal) {
-    LogMessageData data(__FILE__, __LINE__, INTERNAL_FATAL, -1);
-    LogMessage::LogLine(data, "HandleUnexpectedSignal reentered\n");
+    LogMessage::LogLine(__FILE__, __LINE__, INTERNAL_FATAL, "HandleUnexpectedSignal reentered\n");
     _exit(1);
   }
   handlingUnexpectedSignal = true;
diff --git a/runtime/signal_catcher.cc b/runtime/signal_catcher.cc
index 336340e..d4ec803 100644
--- a/runtime/signal_catcher.cc
+++ b/runtime/signal_catcher.cc
@@ -25,6 +25,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <sstream>
+
 #include "base/unix_file/fd_file.h"
 #include "class_linker.h"
 #include "gc/heap.h"
@@ -131,7 +133,7 @@
 
   runtime->DumpForSigQuit(os);
 
-  if (false) {
+  if ((false)) {
     std::string maps;
     if (ReadFileToString("/proc/self/maps", &maps)) {
       os << "/proc/self/maps:\n" << maps;
diff --git a/runtime/thread.cc b/runtime/thread.cc
index f93b15b..9c04133 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -29,9 +29,11 @@
 #include <cerrno>
 #include <iostream>
 #include <list>
+#include <sstream>
 
 #include "arch/context.h"
 #include "base/mutex.h"
+#include "base/to_str.h"
 #include "class_linker-inl.h"
 #include "class_linker.h"
 #include "debugger.h"
diff --git a/runtime/thread_linux.cc b/runtime/thread_linux.cc
index 1254056..0284364 100644
--- a/runtime/thread_linux.cc
+++ b/runtime/thread_linux.cc
@@ -16,6 +16,8 @@
 
 #include "thread.h"
 
+#include <signal.h>
+
 namespace art {
 
 void Thread::SetNativePriority(int) {
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index 646830a..6e18904 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -25,6 +25,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <sstream>
+
 #include "base/mutex.h"
 #include "base/mutex-inl.h"
 #include "base/timing_logger.h"
@@ -480,17 +482,18 @@
   VLOG(threads) << "Resume(" << reinterpret_cast<void*>(thread) << ") complete";
 }
 
-static void ThreadSuspendByPeerWarning(Thread* self, int level, const char* message, jobject peer) {
+static void ThreadSuspendByPeerWarning(Thread* self, LogSeverity severity, const char* message,
+                                       jobject peer) {
   JNIEnvExt* env = self->GetJniEnv();
   ScopedLocalRef<jstring>
       scoped_name_string(env, (jstring)env->GetObjectField(peer,
                                                           WellKnownClasses::java_lang_Thread_name));
   ScopedUtfChars scoped_name_chars(env, scoped_name_string.get());
   if (scoped_name_chars.c_str() == NULL) {
-      LOG(level) << message << ": " << peer;
+      LOG(severity) << message << ": " << peer;
       env->ExceptionClear();
   } else {
-      LOG(level) << message << ": " << peer << ":" << scoped_name_chars.c_str();
+      LOG(severity) << message << ": " << peer << ":" << scoped_name_chars.c_str();
   }
 }
 
@@ -562,8 +565,9 @@
   }
 }
 
-static void ThreadSuspendByThreadIdWarning(int level, const char* message, uint32_t thread_id) {
-  LOG(level) << StringPrintf("%s: %d", message, thread_id);
+static void ThreadSuspendByThreadIdWarning(LogSeverity severity, const char* message,
+                                           uint32_t thread_id) {
+  LOG(severity) << StringPrintf("%s: %d", message, thread_id);
 }
 
 Thread* ThreadList::SuspendThreadByThreadId(uint32_t thread_id, bool debug_suspension,
diff --git a/runtime/trace.cc b/runtime/trace.cc
index 91a37fd..b3158a4 100644
--- a/runtime/trace.cc
+++ b/runtime/trace.cc
@@ -18,6 +18,9 @@
 
 #include <sys/uio.h>
 
+#define ATRACE_TAG ATRACE_TAG_DALVIK
+#include "cutils/trace.h"
+
 #include "base/stl_util.h"
 #include "base/unix_file/fd_file.h"
 #include "class_linker.h"
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 4a3c3ec..fc3c879 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -18,6 +18,8 @@
 
 #include <stdlib.h>
 
+#include <sstream>
+
 #include "base/logging.h"
 #include "mirror/class.h"
 #include "ScopedLocalRef.h"
diff --git a/sigchainlib/sigchain_dummy.cc b/sigchainlib/sigchain_dummy.cc
index fbc8c3f..17bfe8f 100644
--- a/sigchainlib/sigchain_dummy.cc
+++ b/sigchainlib/sigchain_dummy.cc
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+#include <stdio.h>
+#include <stdlib.h>
+
 #ifdef HAVE_ANDROID_OS
 #include <android/log.h>
 #else
@@ -21,8 +24,6 @@
 #include <iostream>
 #endif
 
-#include <stdlib.h>
-
 #include "sigchain.h"
 
 static void log(const char* format, ...) {
diff --git a/test/115-native-bridge/run b/test/115-native-bridge/run
index e475cd6..32a9975 100644
--- a/test/115-native-bridge/run
+++ b/test/115-native-bridge/run
@@ -18,9 +18,9 @@
 
 # Use libnativebridgetest as a native bridge, start NativeBridgeMain (Main is JniTest main file).
 LIBPATH=$(echo ${ARGS} | sed -r 's/.*Djava.library.path=([^ ]*) .*/\1/')
-cp ${LIBPATH}/libnativebridgetest.so .
+ln -s ${LIBPATH}/libnativebridgetest.so .
 touch libarttest.so
-cp ${LIBPATH}/libarttest.so libarttest2.so
+ln -s ${LIBPATH}/libarttest.so libarttest2.so
 
 # pwd likely has /, so it's a pain to put that into a sed rule.
 LEFT=$(echo ${ARGS} | sed -r 's/-Djava.library.path.*//')
diff --git a/test/411-optimizing-arith/src/Main.java b/test/411-optimizing-arith/src/Main.java
index ab8a83f..4de2271 100644
--- a/test/411-optimizing-arith/src/Main.java
+++ b/test/411-optimizing-arith/src/Main.java
@@ -16,7 +16,6 @@
 
 // Note that $opt$ is a marker for the optimizing compiler to ensure
 // it does compile the method.
-
 public class Main {
 
   public static void expectEquals(int expected, int result) {
@@ -31,29 +30,140 @@
     }
   }
 
+  public static void expectEquals(float expected, float result) {
+    if (expected != result) {
+      throw new Error("Expected: " + expected + ", found: " + result);
+    }
+  }
+
+  public static void expectEquals(double expected, double result) {
+    if (expected != result) {
+      throw new Error("Expected: " + expected + ", found: " + result);
+    }
+  }
+
+  public static void expectApproxEquals(float a, float b, float maxDelta) {
+    boolean aproxEquals = (a > b)
+      ? ((a - b) < maxDelta)
+      : ((b - a) < maxDelta);
+    if (!aproxEquals) {
+      throw new Error("Expected: " + a + ", found: " + b + ", with delta: " + maxDelta);
+    }
+  }
+
+  public static void expectApproxEquals(double a, double b, double maxDelta) {
+    boolean aproxEquals = (a > b)
+      ? ((a - b) < maxDelta)
+      : ((b - a) < maxDelta);
+    if (!aproxEquals) {
+      throw new Error("Expected: " + a + ", found: " + b + ", with delta: " + maxDelta);
+    }
+  }
+
+  public static void expectNaN(float a) {
+    if (a == a) {
+      throw new Error("Expected NaN: " + a);
+    }
+  }
+
+  public static void expectNaN(double a) {
+    if (a == a) {
+      throw new Error("Expected NaN: " + a);
+    }
+  }
+
   public static void main(String[] args) {
     mul();
     neg();
   }
 
   public static void mul() {
+    mulInt();
+    mulLong();
+    mulFloat();
+    mulDouble();
+  }
+
+  private static void mulInt() {
     expectEquals(15, $opt$Mul(5, 3));
+    expectEquals(0, $opt$Mul(0, 0));
     expectEquals(0, $opt$Mul(0, 3));
     expectEquals(0, $opt$Mul(3, 0));
     expectEquals(-3, $opt$Mul(1, -3));
     expectEquals(36, $opt$Mul(-12, -3));
     expectEquals(33, $opt$Mul(1, 3) * 11);
     expectEquals(671088645, $opt$Mul(134217729, 5)); // (2^27 + 1) * 5
+  }
 
+  private static void mulLong() {
     expectEquals(15L, $opt$Mul(5L, 3L));
+    expectEquals(0L, $opt$Mul(0L, 0L));
     expectEquals(0L, $opt$Mul(0L, 3L));
     expectEquals(0L, $opt$Mul(3L, 0L));
     expectEquals(-3L, $opt$Mul(1L, -3L));
     expectEquals(36L, $opt$Mul(-12L, -3L));
-    expectEquals(33L, $opt$Mul(1L, 3L) * 11);
+    expectEquals(33L, $opt$Mul(1L, 3L) * 11F);
     expectEquals(240518168583L, $opt$Mul(34359738369L, 7L)); // (2^35 + 1) * 7
   }
 
+  private static void mulFloat() {
+    expectApproxEquals(15F, $opt$Mul(5F, 3F), 0.0001F);
+    expectApproxEquals(0F, $opt$Mul(0F, 0F), 0.0001F);
+    expectApproxEquals(0F, $opt$Mul(0F, 3F), 0.0001F);
+    expectApproxEquals(0F, $opt$Mul(3F, 0F), 0.0001F);
+    expectApproxEquals(-3F, $opt$Mul(1F, -3F), 0.0001F);
+    expectApproxEquals(36F, $opt$Mul(-12F, -3F), 0.0001F);
+    expectApproxEquals(33F, $opt$Mul(1F, 3F) * 11F, 0.0001F);
+    expectApproxEquals(0.02F, 0.1F * 0.2F, 0.0001F);
+    expectApproxEquals(-0.1F, -0.5F * 0.2F, 0.0001F);
+
+    expectNaN($opt$Mul(0F, Float.POSITIVE_INFINITY));
+    expectNaN($opt$Mul(0F, Float.NEGATIVE_INFINITY));
+    expectNaN($opt$Mul(Float.NaN, 11F));
+    expectNaN($opt$Mul(Float.NaN, -11F));
+    expectNaN($opt$Mul(Float.NaN, Float.NEGATIVE_INFINITY));
+    expectNaN($opt$Mul(Float.NaN, Float.POSITIVE_INFINITY));
+
+    expectEquals(Float.POSITIVE_INFINITY, $opt$Mul(2F, 3.40282346638528860e+38F));
+    expectEquals(Float.POSITIVE_INFINITY, $opt$Mul(2F, Float.POSITIVE_INFINITY));
+    expectEquals(Float.NEGATIVE_INFINITY, $opt$Mul(-2F, Float.POSITIVE_INFINITY));
+    expectEquals(Float.NEGATIVE_INFINITY, $opt$Mul(-2F, 3.40282346638528860e+38F));
+    expectEquals(Float.NEGATIVE_INFINITY, $opt$Mul(2F, Float.NEGATIVE_INFINITY));
+    expectEquals(Float.POSITIVE_INFINITY, $opt$Mul(-2F, Float.NEGATIVE_INFINITY));
+    expectEquals(Float.NEGATIVE_INFINITY, $opt$Mul(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY));
+    expectEquals(Float.POSITIVE_INFINITY, $opt$Mul(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY));
+    expectEquals(Float.POSITIVE_INFINITY, $opt$Mul(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY));
+  }
+
+  private static void mulDouble() {
+    expectApproxEquals(15D, $opt$Mul(5D, 3D), 0.0001D);
+    expectApproxEquals(0D, $opt$Mul(0D, 0D), 0.0001D);
+    expectApproxEquals(0D, $opt$Mul(0D, 3D), 0.0001D);
+    expectApproxEquals(0D, $opt$Mul(3D, 0D), 0.0001D);
+    expectApproxEquals(-3D, $opt$Mul(1D, -3D), 0.0001D);
+    expectApproxEquals(36D, $opt$Mul(-12D, -3D), 0.0001D);
+    expectApproxEquals(33D, $opt$Mul(1D, 3D) * 11D, 0.0001D);
+    expectApproxEquals(0.02D, 0.1D * 0.2D, 0.0001D);
+    expectApproxEquals(-0.1D, -0.5D * 0.2D, 0.0001D);
+
+    expectNaN($opt$Mul(0D, Double.POSITIVE_INFINITY));
+    expectNaN($opt$Mul(0D, Double.NEGATIVE_INFINITY));
+    expectNaN($opt$Mul(Double.NaN, 11D));
+    expectNaN($opt$Mul(Double.NaN, -11D));
+    expectNaN($opt$Mul(Double.NaN, Double.NEGATIVE_INFINITY));
+    expectNaN($opt$Mul(Double.NaN, Double.POSITIVE_INFINITY));
+
+    expectEquals(Double.POSITIVE_INFINITY, $opt$Mul(2D, 1.79769313486231570e+308));
+    expectEquals(Double.POSITIVE_INFINITY, $opt$Mul(2D, Double.POSITIVE_INFINITY));
+    expectEquals(Double.NEGATIVE_INFINITY, $opt$Mul(-2D, Double.POSITIVE_INFINITY));
+    expectEquals(Double.NEGATIVE_INFINITY, $opt$Mul(-2D, 1.79769313486231570e+308));
+    expectEquals(Double.NEGATIVE_INFINITY, $opt$Mul(2D, Double.NEGATIVE_INFINITY));
+    expectEquals(Double.POSITIVE_INFINITY, $opt$Mul(-2D, Double.NEGATIVE_INFINITY));
+    expectEquals(Double.NEGATIVE_INFINITY, $opt$Mul(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY));
+    expectEquals(Double.POSITIVE_INFINITY, $opt$Mul(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY));
+    expectEquals(Double.POSITIVE_INFINITY, $opt$Mul(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY));
+  }
+
   public static void neg() {
     expectEquals(-1, $opt$Neg(1));
     expectEquals(1, $opt$Neg(-1));
@@ -90,7 +200,16 @@
     return a * b;
   }
 
+  static float $opt$Mul(float a, float b) {
+    return a * b;
+  }
+
+  static double $opt$Mul(double a, double b) {
+    return a * b;
+  }
+
   static int $opt$Neg(int a){
     return -a;
   }
+
 }
diff --git a/test/Android.libarttest.mk b/test/Android.libarttest.mk
index fd95038..55de1f3 100644
--- a/test/Android.libarttest.mk
+++ b/test/Android.libarttest.mk
@@ -58,8 +58,7 @@
   ifeq ($$(art_target_or_host),target)
     $(call set-target-local-clang-vars)
     $(call set-target-local-cflags-vars,debug)
-    LOCAL_SHARED_LIBRARIES += libdl libcutils
-    LOCAL_STATIC_LIBRARIES := libgtest
+    LOCAL_SHARED_LIBRARIES += libdl
     LOCAL_MULTILIB := both
     LOCAL_MODULE_PATH_32 := $(ART_TARGET_TEST_OUT)/$(ART_TARGET_ARCH_32)
     LOCAL_MODULE_PATH_64 := $(ART_TARGET_TEST_OUT)/$(ART_TARGET_ARCH_64)
@@ -68,11 +67,7 @@
   else # host
     LOCAL_CLANG := $(ART_HOST_CLANG)
     LOCAL_CFLAGS := $(ART_HOST_CFLAGS) $(ART_HOST_DEBUG_CFLAGS)
-    LOCAL_STATIC_LIBRARIES := libcutils
     LOCAL_LDLIBS := $(ART_HOST_LDLIBS) -ldl -lpthread
-    ifeq ($(HOST_OS),linux)
-      LOCAL_LDLIBS += -lrt
-    endif
     LOCAL_IS_HOST_MODULE := true
     LOCAL_MULTILIB := both
     include $(BUILD_HOST_SHARED_LIBRARY)
diff --git a/test/Android.libnativebridgetest.mk b/test/Android.libnativebridgetest.mk
index 5e2493c..1b20e69 100644
--- a/test/Android.libnativebridgetest.mk
+++ b/test/Android.libnativebridgetest.mk
@@ -51,7 +51,7 @@
   ifeq ($$(art_target_or_host),target)
     $(call set-target-local-clang-vars)
     $(call set-target-local-cflags-vars,debug)
-    LOCAL_SHARED_LIBRARIES += libdl libcutils
+    LOCAL_SHARED_LIBRARIES += libdl
     LOCAL_STATIC_LIBRARIES := libgtest
     LOCAL_MULTILIB := both
     LOCAL_MODULE_PATH_32 := $(ART_TARGET_TEST_OUT)/$(ART_TARGET_ARCH_32)
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 5fff69e..427e0b1 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -66,11 +66,6 @@
 ########################################################################
 # General rules to build and run a run-test.
 
-# Test rule names or of the form:
-# test-art-{1: host or target}-run-test-{2: prebuild no-prebuild no-dex2oat}-
-#    {3: interpreter default optimizing}-{4: relocate no-relocate relocate-no-patchoat}-
-#    {5: trace or no-trace}-{6: gcstress gcverify cms}-{7: forcecopy checkjni jni}-
-#    {8: no-image or image}-{9: test name}{10: 32 or 64}
 TARGET_TYPES := host target
 PREBUILD_TYPES := prebuild
 ifeq ($(ART_TEST_RUN_TEST_NO_PREBUILD),true)
@@ -289,8 +284,8 @@
 
 ifneq (,$(filter default,$(COMPILER_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
-      defaut,$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
-      $(IMAGE_TYPES),$(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+      default,$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
+      $(IMAGE_TYPES),$(TEST_ART_BROKEN_DEFAULT_RUN_TESTS),$(ALL_ADDRESS_SIZES))
 endif
 
 TEST_ART_BROKEN_DEFAULT_RUN_TESTS :=
@@ -360,7 +355,7 @@
 endif
 
 # Create a rule to build and run a tests following the form:
-# test-art-{1: host or target}-run-test-{2:debug ndebug}-{3: prebuild no-prebuild no-dex2oat}-
+# test-art-{1: host or target}-run-test-{2: debug ndebug}-{3: prebuild no-prebuild no-dex2oat}-
 #    {4: interpreter default optimizing}-{5: relocate no-relocate relocate-no-patchoat}-
 #    {6: trace or no-trace}-{7: gcstress gcverify cms}-{8: forcecopy checkjni jni}-
 #    {9: no-image image}-{10: test name}{11: 32 or 64}
diff --git a/test/run-test b/test/run-test
index 73ffc31..2ef3ab1 100755
--- a/test/run-test
+++ b/test/run-test
@@ -469,9 +469,6 @@
   file_size_limit=5120
 elif echo "$test_dir" | grep 083; then
   file_size_limit=5120
-elif echo "$test_dir" | grep 115; then
-# Native bridge test copies libarttest.so into its directory, which needs 2MB already.
-  file_size_limit=5120
 fi
 if ! ulimit -S "$file_size_limit"; then
    echo "ulimit file size setting failed"