Merge "Disable adding main and non moving spaces to immune region in GSS"
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index 3a19c40..a340588 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -179,6 +179,42 @@
   ART_TEST_CFLAGS += -DART_USE_PORTABLE_COMPILER=1
 endif
 
+include $(CLEAR_VARS)
+LOCAL_MODULE := libart-gtest
+LOCAL_MODULE_TAGS := optional
+LOCAL_CPP_EXTENSION := cc
+LOCAL_CFLAGS := $(ART_TARGET_CFLAGS)
+LOCAL_SRC_FILES := runtime/common_runtime_test.cc compiler/common_compiler_test.cc
+LOCAL_C_INCLUDES := $(ART_C_INCLUDES) art/runtime art/compiler
+LOCAL_SHARED_LIBRARIES := libcutils libartd libartd-compiler libdl
+LOCAL_STATIC_LIBRARIES += libgtest_libc++
+LOCAL_CLANG := $(ART_TARGET_CLANG)
+LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk
+LOCAL_ADDITIONAL_DEPENDENCIES += art/build/Android.gtest.mk
+include external/libcxx/libcxx.mk
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libart-gtest
+LOCAL_MODULE_TAGS := optional
+LOCAL_CPP_EXTENSION := cc
+LOCAL_CFLAGS := $(ART_HOST_CFLAGS)
+LOCAL_SRC_FILES := runtime/common_runtime_test.cc compiler/common_compiler_test.cc
+LOCAL_C_INCLUDES := $(ART_C_INCLUDES) art/runtime art/compiler
+LOCAL_SHARED_LIBRARIES := libartd libartd-compiler
+LOCAL_STATIC_LIBRARIES := libcutils
+ifneq ($(WITHOUT_HOST_CLANG),true)
+  # GCC host compiled tests fail with this linked, presumably due to destructors that run.
+  LOCAL_STATIC_LIBRARIES += libgtest_libc++_host
+endif
+LOCAL_LDLIBS += -ldl -lpthread
+LOCAL_MULTILIB := both
+LOCAL_CLANG := $(ART_HOST_CLANG)
+LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk
+LOCAL_ADDITIONAL_DEPENDENCIES += art/build/Android.gtest.mk
+include external/libcxx/libcxx.mk
+include $(BUILD_HOST_SHARED_LIBRARY)
+
 # Variables holding collections of gtest pre-requisits used to run a number of gtests.
 ART_TEST_HOST_GTEST$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
 ART_TEST_HOST_GTEST$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
@@ -285,12 +321,12 @@
     LOCAL_MODULE_TAGS := tests
   endif
   LOCAL_CPP_EXTENSION := $$(ART_CPP_EXTENSION)
-  LOCAL_SRC_FILES := $$(art_gtest_filename) runtime/common_runtime_test.cc
+  LOCAL_SRC_FILES := $$(art_gtest_filename)
   LOCAL_C_INCLUDES += $$(ART_C_INCLUDES) art/runtime $$(art_gtest_extra_c_includes)
-  LOCAL_SHARED_LIBRARIES += libartd $$(art_gtest_extra_shared_libraries)
+  LOCAL_SHARED_LIBRARIES += libartd $$(art_gtest_extra_shared_libraries) libart-gtest
 
-  # LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common.mk
-  # LOCAL_ADDITIONAL_DEPENDENCIES += art/build/Android.gtest.mk
+  LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk
+  LOCAL_ADDITIONAL_DEPENDENCIES += art/build/Android.gtest.mk
 
   # Mac OS linker doesn't understand --export-dynamic.
   ifneq ($$(HOST_OS)-$$(art_target_or_host),darwin-host)
@@ -304,7 +340,6 @@
     $$(eval $$(call set-target-local-clang-vars))
     $$(eval $$(call set-target-local-cflags-vars,debug))
     LOCAL_SHARED_LIBRARIES += libdl libicuuc libicui18n libnativehelper libz libcutils libvixl
-    LOCAL_STATIC_LIBRARIES += libgtest_libc++
     LOCAL_MODULE_PATH_32 := $$(ART_TARGET_NATIVETEST_OUT)/$$(ART_TARGET_ARCH_32)
     LOCAL_MODULE_PATH_64 := $$(ART_TARGET_NATIVETEST_OUT)/$$(ART_TARGET_ARCH_64)
     LOCAL_MULTILIB := both
@@ -328,10 +363,6 @@
     LOCAL_CFLAGS += $$(ART_HOST_CFLAGS) $$(ART_HOST_DEBUG_CFLAGS)
     LOCAL_SHARED_LIBRARIES += libicuuc-host libicui18n-host libnativehelper libz-host
     LOCAL_STATIC_LIBRARIES += libcutils libvixl
-    ifneq ($$(WITHOUT_HOST_CLANG),true)
-      # GCC host compiled tests fail with this linked, presumably due to destructors that run.
-      LOCAL_STATIC_LIBRARIES += libgtest_libc++_host
-    endif
     LOCAL_LDLIBS += -lpthread -ldl
     LOCAL_IS_HOST_MODULE := true
     LOCAL_MULTILIB := both
diff --git a/compiler/Android.mk b/compiler/Android.mk
index 98a4c2f..02dad2a 100644
--- a/compiler/Android.mk
+++ b/compiler/Android.mk
@@ -72,6 +72,7 @@
 	dex/verification_results.cc \
 	dex/vreg_analysis.cc \
 	dex/ssa_transformation.cc \
+	dex/quick_compiler_callbacks.cc \
 	driver/compiler_driver.cc \
 	driver/dex_compilation_unit.cc \
 	jni/quick/arm/calling_convention_arm.cc \
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
new file mode 100644
index 0000000..051cfb6
--- /dev/null
+++ b/compiler/common_compiler_test.cc
@@ -0,0 +1,413 @@
+/*
+ * 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 "common_compiler_test.h"
+
+#if defined(__arm__)
+#include <sys/ucontext.h>
+#endif
+#include <fstream>
+
+#include "class_linker.h"
+#include "compiled_method.h"
+#include "dex/quick_compiler_callbacks.h"
+#include "dex/verification_results.h"
+#include "dex/quick/dex_file_to_method_inliner_map.h"
+#include "driver/compiler_driver.h"
+#include "entrypoints/entrypoint_utils.h"
+#include "interpreter/interpreter.h"
+#include "mirror/art_method.h"
+#include "mirror/dex_cache.h"
+#include "mirror/object-inl.h"
+#include "scoped_thread_state_change.h"
+#include "thread-inl.h"
+#include "utils.h"
+
+namespace art {
+
+// Normally the ClassLinker supplies this.
+extern "C" void art_quick_generic_jni_trampoline(mirror::ArtMethod*);
+
+#if defined(__arm__)
+// A signal handler called when have an illegal instruction.  We record the fact in
+// a global boolean and then increment the PC in the signal context to return to
+// the next instruction.  We know the instruction is an sdiv (4 bytes long).
+static void baddivideinst(int signo, siginfo *si, void *data) {
+  UNUSED(signo);
+  UNUSED(si);
+  struct ucontext *uc = (struct ucontext *)data;
+  struct sigcontext *sc = &uc->uc_mcontext;
+  sc->arm_r0 = 0;     // set R0 to #0 to signal error
+  sc->arm_pc += 4;    // skip offending instruction
+}
+
+// This is in arch/arm/arm_sdiv.S.  It does the following:
+// mov r1,#1
+// sdiv r0,r1,r1
+// bx lr
+//
+// the result will be the value 1 if sdiv is supported.  If it is not supported
+// a SIGILL signal will be raised and the signal handler (baddivideinst) called.
+// The signal handler sets r0 to #0 and then increments pc beyond the failed instruction.
+// Thus if the instruction is not supported, the result of this function will be #0
+
+extern "C" bool CheckForARMSDIVInstruction();
+
+static InstructionSetFeatures GuessInstructionFeatures() {
+  InstructionSetFeatures f;
+
+  // Uncomment this for processing of /proc/cpuinfo.
+  if (false) {
+    // Look in /proc/cpuinfo for features we need.  Only use this when we can guarantee that
+    // the kernel puts the appropriate feature flags in here.  Sometimes it doesn't.
+    std::ifstream in("/proc/cpuinfo");
+    if (in) {
+      while (!in.eof()) {
+        std::string line;
+        std::getline(in, line);
+        if (!in.eof()) {
+          if (line.find("Features") != std::string::npos) {
+            if (line.find("idivt") != std::string::npos) {
+              f.SetHasDivideInstruction(true);
+            }
+          }
+        }
+        in.close();
+      }
+    } else {
+      LOG(INFO) << "Failed to open /proc/cpuinfo";
+    }
+  }
+
+  // See if have a sdiv instruction.  Register a signal handler and try to execute
+  // an sdiv instruction.  If we get a SIGILL then it's not supported.  We can't use
+  // the /proc/cpuinfo method for this because Krait devices don't always put the idivt
+  // feature in the list.
+  struct sigaction sa, osa;
+  sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
+  sa.sa_sigaction = baddivideinst;
+  sigaction(SIGILL, &sa, &osa);
+
+  if (CheckForARMSDIVInstruction()) {
+    f.SetHasDivideInstruction(true);
+  }
+
+  // Restore the signal handler.
+  sigaction(SIGILL, &osa, nullptr);
+
+  // Other feature guesses in here.
+  return f;
+}
+#endif
+
+// Given a set of instruction features from the build, parse it.  The
+// input 'str' is a comma separated list of feature names.  Parse it and
+// return the InstructionSetFeatures object.
+static InstructionSetFeatures ParseFeatureList(std::string str) {
+  InstructionSetFeatures result;
+  typedef std::vector<std::string> FeatureList;
+  FeatureList features;
+  Split(str, ',', features);
+  for (FeatureList::iterator i = features.begin(); i != features.end(); i++) {
+    std::string feature = Trim(*i);
+    if (feature == "default") {
+      // Nothing to do.
+    } else if (feature == "div") {
+      // Supports divide instruction.
+      result.SetHasDivideInstruction(true);
+    } else if (feature == "nodiv") {
+      // Turn off support for divide instruction.
+      result.SetHasDivideInstruction(false);
+    } else {
+      LOG(FATAL) << "Unknown instruction set feature: '" << feature << "'";
+    }
+  }
+  // Others...
+  return result;
+}
+
+CommonCompilerTest::CommonCompilerTest() {}
+CommonCompilerTest::~CommonCompilerTest() {}
+
+OatFile::OatMethod CommonCompilerTest::CreateOatMethod(const void* code, const uint8_t* gc_map) {
+  CHECK(code != nullptr);
+  const byte* base;
+  uint32_t code_offset, gc_map_offset;
+  if (gc_map == nullptr) {
+    base = reinterpret_cast<const byte*>(code);  // Base of data points at code.
+    base -= kPointerSize;  // Move backward so that code_offset != 0.
+    code_offset = kPointerSize;
+    gc_map_offset = 0;
+  } else {
+    // TODO: 64bit support.
+    base = nullptr;  // Base of data in oat file, ie 0.
+    code_offset = PointerToLowMemUInt32(code);
+    gc_map_offset = PointerToLowMemUInt32(gc_map);
+  }
+  return OatFile::OatMethod(base, code_offset, gc_map_offset);
+}
+
+void CommonCompilerTest::MakeExecutable(mirror::ArtMethod* method) {
+  CHECK(method != nullptr);
+
+  const CompiledMethod* compiled_method = nullptr;
+  if (!method->IsAbstract()) {
+    mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
+    const DexFile& dex_file = *dex_cache->GetDexFile();
+    compiled_method =
+        compiler_driver_->GetCompiledMethod(MethodReference(&dex_file,
+                                                            method->GetDexMethodIndex()));
+  }
+  if (compiled_method != nullptr) {
+    const std::vector<uint8_t>* code = compiled_method->GetQuickCode();
+    const void* code_ptr;
+    if (code != nullptr) {
+      uint32_t code_size = code->size();
+      CHECK_NE(0u, code_size);
+      const std::vector<uint8_t>& vmap_table = compiled_method->GetVmapTable();
+      uint32_t vmap_table_offset = vmap_table.empty() ? 0u
+          : sizeof(OatQuickMethodHeader) + vmap_table.size();
+      const std::vector<uint8_t>& mapping_table = compiled_method->GetMappingTable();
+      uint32_t mapping_table_offset = mapping_table.empty() ? 0u
+          : sizeof(OatQuickMethodHeader) + vmap_table.size() + mapping_table.size();
+      OatQuickMethodHeader method_header(mapping_table_offset, vmap_table_offset,
+                                         compiled_method->GetFrameSizeInBytes(),
+                                         compiled_method->GetCoreSpillMask(),
+                                         compiled_method->GetFpSpillMask(), code_size);
+
+      header_code_and_maps_chunks_.push_back(std::vector<uint8_t>());
+      std::vector<uint8_t>* chunk = &header_code_and_maps_chunks_.back();
+      size_t size = sizeof(method_header) + code_size + vmap_table.size() + mapping_table.size();
+      size_t code_offset = compiled_method->AlignCode(size - code_size);
+      size_t padding = code_offset - (size - code_size);
+      chunk->reserve(padding + size);
+      chunk->resize(sizeof(method_header));
+      memcpy(&(*chunk)[0], &method_header, sizeof(method_header));
+      chunk->insert(chunk->begin(), vmap_table.begin(), vmap_table.end());
+      chunk->insert(chunk->begin(), mapping_table.begin(), mapping_table.end());
+      chunk->insert(chunk->begin(), padding, 0);
+      chunk->insert(chunk->end(), code->begin(), code->end());
+      CHECK_EQ(padding + size, chunk->size());
+      code_ptr = &(*chunk)[code_offset];
+    } else {
+      code = compiled_method->GetPortableCode();
+      code_ptr = &(*code)[0];
+    }
+    MakeExecutable(code_ptr, code->size());
+    const void* method_code = CompiledMethod::CodePointer(code_ptr,
+                                                          compiled_method->GetInstructionSet());
+    LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
+    OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr);
+    oat_method.LinkMethod(method);
+    method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge);
+  } else {
+    // No code? You must mean to go into the interpreter.
+    // Or the generic JNI...
+    if (!method->IsNative()) {
+      const void* method_code = kUsePortableCompiler ? GetPortableToInterpreterBridge()
+          : GetQuickToInterpreterBridge();
+      OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr);
+      oat_method.LinkMethod(method);
+      method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterBridge);
+    } else {
+      const void* method_code = reinterpret_cast<void*>(art_quick_generic_jni_trampoline);
+
+      OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr);
+      oat_method.LinkMethod(method);
+      method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge);
+    }
+  }
+  // Create bridges to transition between different kinds of compiled bridge.
+  if (method->GetEntryPointFromPortableCompiledCode() == nullptr) {
+    method->SetEntryPointFromPortableCompiledCode(GetPortableToQuickBridge());
+  } else {
+    CHECK(method->GetEntryPointFromQuickCompiledCode() == nullptr);
+    method->SetEntryPointFromQuickCompiledCode(GetQuickToPortableBridge());
+    method->SetIsPortableCompiled();
+  }
+}
+
+void CommonCompilerTest::MakeExecutable(const void* code_start, size_t code_length) {
+  CHECK(code_start != nullptr);
+  CHECK_NE(code_length, 0U);
+  uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
+  uintptr_t base = RoundDown(data, kPageSize);
+  uintptr_t limit = RoundUp(data + code_length, kPageSize);
+  uintptr_t len = limit - base;
+  int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
+  CHECK_EQ(result, 0);
+
+  // Flush instruction cache
+  // Only uses __builtin___clear_cache if GCC >= 4.3.3
+#if GCC_VERSION >= 40303
+  __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
+#else
+  // Only warn if not Intel as Intel doesn't have cache flush instructions.
+#if !defined(__i386__) && !defined(__x86_64__)
+  LOG(WARNING) << "UNIMPLEMENTED: cache flush";
+#endif
+#endif
+}
+
+void CommonCompilerTest::MakeExecutable(mirror::ClassLoader* class_loader, const char* class_name) {
+  std::string class_descriptor(DotToDescriptor(class_name));
+  Thread* self = Thread::Current();
+  StackHandleScope<1> hs(self);
+  Handle<mirror::ClassLoader> loader(hs.NewHandle(class_loader));
+  mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), loader);
+  CHECK(klass != nullptr) << "Class not found " << class_name;
+  for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
+    MakeExecutable(klass->GetDirectMethod(i));
+  }
+  for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
+    MakeExecutable(klass->GetVirtualMethod(i));
+  }
+}
+
+void CommonCompilerTest::SetUp() {
+  CommonRuntimeTest::SetUp();
+  {
+    ScopedObjectAccess soa(Thread::Current());
+
+    InstructionSet instruction_set = kRuntimeISA;
+
+    // Take the default set of instruction features from the build.
+    InstructionSetFeatures instruction_set_features =
+        ParseFeatureList(Runtime::GetDefaultInstructionSetFeatures());
+
+#if defined(__arm__)
+    InstructionSetFeatures runtime_features = GuessInstructionFeatures();
+
+    // for ARM, do a runtime check to make sure that the features we are passed from
+    // the build match the features we actually determine at runtime.
+    ASSERT_LE(instruction_set_features, runtime_features);
+#endif
+
+    runtime_->SetInstructionSet(instruction_set);
+    for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
+      Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
+      if (!runtime_->HasCalleeSaveMethod(type)) {
+        runtime_->SetCalleeSaveMethod(
+            runtime_->CreateCalleeSaveMethod(type), type);
+      }
+    }
+
+    // TODO: make selectable
+    Compiler::Kind compiler_kind
+    = (kUsePortableCompiler) ? Compiler::kPortable : Compiler::kQuick;
+    timer_.reset(new CumulativeLogger("Compilation times"));
+    compiler_driver_.reset(new CompilerDriver(compiler_options_.get(),
+                                              verification_results_.get(),
+                                              method_inliner_map_.get(),
+                                              compiler_kind, instruction_set,
+                                              instruction_set_features,
+                                              true, new CompilerDriver::DescriptorSet,
+                                              2, true, true, timer_.get()));
+  }
+  // We typically don't generate an image in unit tests, disable this optimization by default.
+  compiler_driver_->SetSupportBootImageFixup(false);
+}
+
+void CommonCompilerTest::SetUpRuntimeOptions(RuntimeOptions* options) {
+  CommonRuntimeTest::SetUpRuntimeOptions(options);
+
+  compiler_options_.reset(new CompilerOptions);
+  verification_results_.reset(new VerificationResults(compiler_options_.get()));
+  method_inliner_map_.reset(new DexFileToMethodInlinerMap);
+  callbacks_.reset(new QuickCompilerCallbacks(verification_results_.get(),
+                                              method_inliner_map_.get()));
+  options->push_back(std::make_pair("compilercallbacks", callbacks_.get()));
+}
+
+void CommonCompilerTest::TearDown() {
+  timer_.reset();
+  compiler_driver_.reset();
+  callbacks_.reset();
+  method_inliner_map_.reset();
+  verification_results_.reset();
+  compiler_options_.reset();
+
+  CommonRuntimeTest::TearDown();
+}
+
+void CommonCompilerTest::CompileClass(mirror::ClassLoader* class_loader, const char* class_name) {
+  std::string class_descriptor(DotToDescriptor(class_name));
+  Thread* self = Thread::Current();
+  StackHandleScope<1> hs(self);
+  Handle<mirror::ClassLoader> loader(hs.NewHandle(class_loader));
+  mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), loader);
+  CHECK(klass != nullptr) << "Class not found " << class_name;
+  for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
+    CompileMethod(klass->GetDirectMethod(i));
+  }
+  for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
+    CompileMethod(klass->GetVirtualMethod(i));
+  }
+}
+
+void CommonCompilerTest::CompileMethod(mirror::ArtMethod* method) {
+  CHECK(method != nullptr);
+  TimingLogger timings("CommonTest::CompileMethod", false, false);
+  TimingLogger::ScopedTiming t(__FUNCTION__, &timings);
+  compiler_driver_->CompileOne(method, &timings);
+  TimingLogger::ScopedTiming t2("MakeExecutable", &timings);
+  MakeExecutable(method);
+}
+
+void CommonCompilerTest::CompileDirectMethod(Handle<mirror::ClassLoader> class_loader,
+                                             const char* class_name, const char* method_name,
+                                             const char* signature) {
+  std::string class_descriptor(DotToDescriptor(class_name));
+  Thread* self = Thread::Current();
+  mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), class_loader);
+  CHECK(klass != nullptr) << "Class not found " << class_name;
+  mirror::ArtMethod* method = klass->FindDirectMethod(method_name, signature);
+  CHECK(method != nullptr) << "Direct method not found: "
+      << class_name << "." << method_name << signature;
+  CompileMethod(method);
+}
+
+void CommonCompilerTest::CompileVirtualMethod(Handle<mirror::ClassLoader> class_loader, const char* class_name,
+                                              const char* method_name, const char* signature)
+SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  std::string class_descriptor(DotToDescriptor(class_name));
+  Thread* self = Thread::Current();
+  mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), class_loader);
+  CHECK(klass != nullptr) << "Class not found " << class_name;
+  mirror::ArtMethod* method = klass->FindVirtualMethod(method_name, signature);
+  CHECK(method != NULL) << "Virtual method not found: "
+      << class_name << "." << method_name << signature;
+  CompileMethod(method);
+}
+
+void CommonCompilerTest::ReserveImageSpace() {
+  // Reserve where the image will be loaded up front so that other parts of test set up don't
+  // accidentally end up colliding with the fixed memory address when we need to load the image.
+  std::string error_msg;
+  image_reservation_.reset(MemMap::MapAnonymous("image reservation",
+                                                reinterpret_cast<byte*>(ART_BASE_ADDRESS),
+                                                (size_t)100 * 1024 * 1024,  // 100MB
+                                                PROT_NONE,
+                                                false /* no need for 4gb flag with fixed mmap*/,
+                                                &error_msg));
+  CHECK(image_reservation_.get() != nullptr) << error_msg;
+}
+
+void CommonCompilerTest::UnreserveImageSpace() {
+  image_reservation_.reset();
+}
+
+}  // namespace art
diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h
index e11f61a..df06b71 100644
--- a/compiler/common_compiler_test.h
+++ b/compiler/common_compiler_test.h
@@ -17,409 +17,68 @@
 #ifndef ART_COMPILER_COMMON_COMPILER_TEST_H_
 #define ART_COMPILER_COMMON_COMPILER_TEST_H_
 
-#include "compiler.h"
-#include "compiler_callbacks.h"
+#include <list>
+#include <vector>
+
 #include "common_runtime_test.h"
-#include "dex/quick/dex_file_to_method_inliner_map.h"
-#include "dex/verification_results.h"
-#include "driver/compiler_callbacks_impl.h"
-#include "driver/compiler_driver.h"
-#include "driver/compiler_options.h"
+#include "oat_file.h"
 
 namespace art {
+namespace mirror {
+  class ClassLoader;
+}  // namespace mirror
 
-#if defined(__arm__)
+class CompilerDriver;
+class CompilerOptions;
+class CumulativeLogger;
+class DexFileToMethodInlinerMap;
+class VerificationResults;
 
-#include <sys/ucontext.h>
-
-// A signal handler called when have an illegal instruction.  We record the fact in
-// a global boolean and then increment the PC in the signal context to return to
-// the next instruction.  We know the instruction is an sdiv (4 bytes long).
-static inline void baddivideinst(int signo, siginfo *si, void *data) {
-  UNUSED(signo);
-  UNUSED(si);
-  struct ucontext *uc = (struct ucontext *)data;
-  struct sigcontext *sc = &uc->uc_mcontext;
-  sc->arm_r0 = 0;     // set R0 to #0 to signal error
-  sc->arm_pc += 4;    // skip offending instruction
-}
-
-// This is in arch/arm/arm_sdiv.S.  It does the following:
-// mov r1,#1
-// sdiv r0,r1,r1
-// bx lr
-//
-// the result will be the value 1 if sdiv is supported.  If it is not supported
-// a SIGILL signal will be raised and the signal handler (baddivideinst) called.
-// The signal handler sets r0 to #0 and then increments pc beyond the failed instruction.
-// Thus if the instruction is not supported, the result of this function will be #0
-
-extern "C" bool CheckForARMSDIVInstruction();
-
-static inline InstructionSetFeatures GuessInstructionFeatures() {
-  InstructionSetFeatures f;
-
-  // Uncomment this for processing of /proc/cpuinfo.
-  if (false) {
-    // Look in /proc/cpuinfo for features we need.  Only use this when we can guarantee that
-    // the kernel puts the appropriate feature flags in here.  Sometimes it doesn't.
-    std::ifstream in("/proc/cpuinfo");
-    if (in) {
-      while (!in.eof()) {
-        std::string line;
-        std::getline(in, line);
-        if (!in.eof()) {
-          if (line.find("Features") != std::string::npos) {
-            if (line.find("idivt") != std::string::npos) {
-              f.SetHasDivideInstruction(true);
-            }
-          }
-        }
-        in.close();
-      }
-    } else {
-      LOG(INFO) << "Failed to open /proc/cpuinfo";
-    }
-  }
-
-  // See if have a sdiv instruction.  Register a signal handler and try to execute
-  // an sdiv instruction.  If we get a SIGILL then it's not supported.  We can't use
-  // the /proc/cpuinfo method for this because Krait devices don't always put the idivt
-  // feature in the list.
-  struct sigaction sa, osa;
-  sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
-  sa.sa_sigaction = baddivideinst;
-  sigaction(SIGILL, &sa, &osa);
-
-  if (CheckForARMSDIVInstruction()) {
-    f.SetHasDivideInstruction(true);
-  }
-
-  // Restore the signal handler.
-  sigaction(SIGILL, &osa, nullptr);
-
-  // Other feature guesses in here.
-  return f;
-}
-
-#endif
-
-// Given a set of instruction features from the build, parse it.  The
-// input 'str' is a comma separated list of feature names.  Parse it and
-// return the InstructionSetFeatures object.
-static inline InstructionSetFeatures ParseFeatureList(std::string str) {
-  InstructionSetFeatures result;
-  typedef std::vector<std::string> FeatureList;
-  FeatureList features;
-  Split(str, ',', features);
-  for (FeatureList::iterator i = features.begin(); i != features.end(); i++) {
-    std::string feature = Trim(*i);
-    if (feature == "default") {
-      // Nothing to do.
-    } else if (feature == "div") {
-      // Supports divide instruction.
-      result.SetHasDivideInstruction(true);
-    } else if (feature == "nodiv") {
-      // Turn off support for divide instruction.
-      result.SetHasDivideInstruction(false);
-    } else {
-      LOG(FATAL) << "Unknown instruction set feature: '" << feature << "'";
-    }
-  }
-  // Others...
-  return result;
-}
-
-// Normally the ClassLinker supplies this.
-extern "C" void art_quick_generic_jni_trampoline(mirror::ArtMethod*);
+template<class T> class Handle;
 
 class CommonCompilerTest : public CommonRuntimeTest {
  public:
+  CommonCompilerTest();
+  ~CommonCompilerTest();
+
   // Create an OatMethod based on pointers (for unit tests).
-  OatFile::OatMethod CreateOatMethod(const void* code,
-                                     const uint8_t* gc_map) {
-    CHECK(code != nullptr);
-    const byte* base;
-    uint32_t code_offset, gc_map_offset;
-    if (gc_map == nullptr) {
-      base = reinterpret_cast<const byte*>(code);  // Base of data points at code.
-      base -= kPointerSize;  // Move backward so that code_offset != 0.
-      code_offset = kPointerSize;
-      gc_map_offset = 0;
-    } else {
-      // TODO: 64bit support.
-      base = nullptr;  // Base of data in oat file, ie 0.
-      code_offset = PointerToLowMemUInt32(code);
-      gc_map_offset = PointerToLowMemUInt32(gc_map);
-    }
-    return OatFile::OatMethod(base,
-                              code_offset,
-                              gc_map_offset);
-  }
+  OatFile::OatMethod CreateOatMethod(const void* code, const uint8_t* gc_map);
 
-  void MakeExecutable(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    CHECK(method != nullptr);
+  void MakeExecutable(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-    const CompiledMethod* compiled_method = nullptr;
-    if (!method->IsAbstract()) {
-      mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
-      const DexFile& dex_file = *dex_cache->GetDexFile();
-      compiled_method =
-          compiler_driver_->GetCompiledMethod(MethodReference(&dex_file,
-                                                              method->GetDexMethodIndex()));
-    }
-    if (compiled_method != nullptr) {
-      const std::vector<uint8_t>* code = compiled_method->GetQuickCode();
-      const void* code_ptr;
-      if (code != nullptr) {
-        uint32_t code_size = code->size();
-        CHECK_NE(0u, code_size);
-        const std::vector<uint8_t>& vmap_table = compiled_method->GetVmapTable();
-        uint32_t vmap_table_offset = vmap_table.empty() ? 0u
-            : sizeof(OatQuickMethodHeader) + vmap_table.size();
-        const std::vector<uint8_t>& mapping_table = compiled_method->GetMappingTable();
-        uint32_t mapping_table_offset = mapping_table.empty() ? 0u
-            : sizeof(OatQuickMethodHeader) + vmap_table.size() + mapping_table.size();
-        OatQuickMethodHeader method_header(mapping_table_offset, vmap_table_offset,
-                                           compiled_method->GetFrameSizeInBytes(),
-                                           compiled_method->GetCoreSpillMask(),
-                                           compiled_method->GetFpSpillMask(), code_size);
-
-        header_code_and_maps_chunks_.push_back(std::vector<uint8_t>());
-        std::vector<uint8_t>* chunk = &header_code_and_maps_chunks_.back();
-        size_t size = sizeof(method_header) + code_size + vmap_table.size() + mapping_table.size();
-        size_t code_offset = compiled_method->AlignCode(size - code_size);
-        size_t padding = code_offset - (size - code_size);
-        chunk->reserve(padding + size);
-        chunk->resize(sizeof(method_header));
-        memcpy(&(*chunk)[0], &method_header, sizeof(method_header));
-        chunk->insert(chunk->begin(), vmap_table.begin(), vmap_table.end());
-        chunk->insert(chunk->begin(), mapping_table.begin(), mapping_table.end());
-        chunk->insert(chunk->begin(), padding, 0);
-        chunk->insert(chunk->end(), code->begin(), code->end());
-        CHECK_EQ(padding + size, chunk->size());
-        code_ptr = &(*chunk)[code_offset];
-      } else {
-        code = compiled_method->GetPortableCode();
-        code_ptr = &(*code)[0];
-      }
-      MakeExecutable(code_ptr, code->size());
-      const void* method_code = CompiledMethod::CodePointer(code_ptr,
-                                                            compiled_method->GetInstructionSet());
-      LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
-      OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr);
-      oat_method.LinkMethod(method);
-      method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge);
-    } else {
-      // No code? You must mean to go into the interpreter.
-      // Or the generic JNI...
-      if (!method->IsNative()) {
-        const void* method_code = kUsePortableCompiler ? GetPortableToInterpreterBridge()
-                                                       : GetQuickToInterpreterBridge();
-        OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr);
-        oat_method.LinkMethod(method);
-        method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterBridge);
-      } else {
-        const void* method_code = reinterpret_cast<void*>(art_quick_generic_jni_trampoline);
-
-        OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr);
-        oat_method.LinkMethod(method);
-        method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge);
-      }
-    }
-    // Create bridges to transition between different kinds of compiled bridge.
-    if (method->GetEntryPointFromPortableCompiledCode() == nullptr) {
-      method->SetEntryPointFromPortableCompiledCode(GetPortableToQuickBridge());
-    } else {
-      CHECK(method->GetEntryPointFromQuickCompiledCode() == nullptr);
-      method->SetEntryPointFromQuickCompiledCode(GetQuickToPortableBridge());
-      method->SetIsPortableCompiled();
-    }
-  }
-
-  static void MakeExecutable(const void* code_start, size_t code_length) {
-    CHECK(code_start != nullptr);
-    CHECK_NE(code_length, 0U);
-    uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
-    uintptr_t base = RoundDown(data, kPageSize);
-    uintptr_t limit = RoundUp(data + code_length, kPageSize);
-    uintptr_t len = limit - base;
-    int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
-    CHECK_EQ(result, 0);
-
-    // Flush instruction cache
-    // Only uses __builtin___clear_cache if GCC >= 4.3.3
-#if GCC_VERSION >= 40303
-    __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
-#else
-    LOG(WARNING) << "UNIMPLEMENTED: cache flush";
-#endif
-  }
+  static void MakeExecutable(const void* code_start, size_t code_length);
 
   void MakeExecutable(mirror::ClassLoader* class_loader, const char* class_name)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    std::string class_descriptor(DotToDescriptor(class_name));
-    Thread* self = Thread::Current();
-    StackHandleScope<1> hs(self);
-    Handle<mirror::ClassLoader> loader(hs.NewHandle(class_loader));
-    mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), loader);
-    CHECK(klass != nullptr) << "Class not found " << class_name;
-    for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
-      MakeExecutable(klass->GetDirectMethod(i));
-    }
-    for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
-      MakeExecutable(klass->GetVirtualMethod(i));
-    }
-  }
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
  protected:
-  virtual void SetUp() {
-    CommonRuntimeTest::SetUp();
-    {
-      ScopedObjectAccess soa(Thread::Current());
+  virtual void SetUp();
 
-      InstructionSet instruction_set = kNone;
+  virtual void SetUpRuntimeOptions(RuntimeOptions *options);
 
-      // Take the default set of instruction features from the build.
-      InstructionSetFeatures instruction_set_features =
-          ParseFeatureList(Runtime::GetDefaultInstructionSetFeatures());
-
-#if defined(__arm__)
-      instruction_set = kThumb2;
-      InstructionSetFeatures runtime_features = GuessInstructionFeatures();
-
-      // for ARM, do a runtime check to make sure that the features we are passed from
-      // the build match the features we actually determine at runtime.
-      ASSERT_LE(instruction_set_features, runtime_features);
-#elif defined(__aarch64__)
-      instruction_set = kArm64;
-#elif defined(__mips__)
-      instruction_set = kMips;
-#elif defined(__i386__)
-      instruction_set = kX86;
-#elif defined(__x86_64__)
-      instruction_set = kX86_64;
-#endif
-
-      runtime_->SetInstructionSet(instruction_set);
-      for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
-        Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
-        if (!runtime_->HasCalleeSaveMethod(type)) {
-          runtime_->SetCalleeSaveMethod(
-              runtime_->CreateCalleeSaveMethod(type), type);
-        }
-      }
-
-      // TODO: make selectable
-      Compiler::Kind compiler_kind
-          = (kUsePortableCompiler) ? Compiler::kPortable : Compiler::kQuick;
-      timer_.reset(new CumulativeLogger("Compilation times"));
-      compiler_driver_.reset(new CompilerDriver(compiler_options_.get(),
-                                                verification_results_.get(),
-                                                method_inliner_map_.get(),
-                                                compiler_kind, instruction_set,
-                                                instruction_set_features,
-                                                true, new CompilerDriver::DescriptorSet,
-                                                2, true, true, timer_.get()));
-    }
-    // We typically don't generate an image in unit tests, disable this optimization by default.
-    compiler_driver_->SetSupportBootImageFixup(false);
-  }
-
-  virtual void SetUpRuntimeOptions(Runtime::Options *options) {
-    CommonRuntimeTest::SetUpRuntimeOptions(options);
-
-    compiler_options_.reset(new CompilerOptions);
-    verification_results_.reset(new VerificationResults(compiler_options_.get()));
-    method_inliner_map_.reset(new DexFileToMethodInlinerMap);
-    callbacks_.reset(new CompilerCallbacksImpl(verification_results_.get(),
-                                               method_inliner_map_.get()));
-    options->push_back(std::make_pair("compilercallbacks", callbacks_.get()));
-  }
-
-  virtual void TearDown() {
-    timer_.reset();
-    compiler_driver_.reset();
-    callbacks_.reset();
-    method_inliner_map_.reset();
-    verification_results_.reset();
-    compiler_options_.reset();
-
-    CommonRuntimeTest::TearDown();
-  }
+  virtual void TearDown();
 
   void CompileClass(mirror::ClassLoader* class_loader, const char* class_name)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    std::string class_descriptor(DotToDescriptor(class_name));
-    Thread* self = Thread::Current();
-    StackHandleScope<1> hs(self);
-    Handle<mirror::ClassLoader> loader(hs.NewHandle(class_loader));
-    mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), loader);
-    CHECK(klass != nullptr) << "Class not found " << class_name;
-    for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
-      CompileMethod(klass->GetDirectMethod(i));
-    }
-    for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
-      CompileMethod(klass->GetVirtualMethod(i));
-    }
-  }
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  void CompileMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    CHECK(method != nullptr);
-    TimingLogger timings("CommonTest::CompileMethod", false, false);
-    TimingLogger::ScopedTiming t(__FUNCTION__, &timings);
-    compiler_driver_->CompileOne(method, &timings);
-    TimingLogger::ScopedTiming t2("MakeExecutable", &timings);
-    MakeExecutable(method);
-  }
+  void CompileMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   void CompileDirectMethod(Handle<mirror::ClassLoader> class_loader, const char* class_name,
                            const char* method_name, const char* signature)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    std::string class_descriptor(DotToDescriptor(class_name));
-    Thread* self = Thread::Current();
-    mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), class_loader);
-    CHECK(klass != nullptr) << "Class not found " << class_name;
-    mirror::ArtMethod* method = klass->FindDirectMethod(method_name, signature);
-    CHECK(method != nullptr) << "Direct method not found: "
-                             << class_name << "." << method_name << signature;
-    CompileMethod(method);
-  }
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   void CompileVirtualMethod(Handle<mirror::ClassLoader> class_loader, const char* class_name,
                             const char* method_name, const char* signature)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    std::string class_descriptor(DotToDescriptor(class_name));
-    Thread* self = Thread::Current();
-    mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), class_loader);
-    CHECK(klass != nullptr) << "Class not found " << class_name;
-    mirror::ArtMethod* method = klass->FindVirtualMethod(method_name, signature);
-    CHECK(method != NULL) << "Virtual method not found: "
-                          << class_name << "." << method_name << signature;
-    CompileMethod(method);
-  }
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  void ReserveImageSpace() {
-    // Reserve where the image will be loaded up front so that other parts of test set up don't
-    // accidentally end up colliding with the fixed memory address when we need to load the image.
-    std::string error_msg;
-    image_reservation_.reset(MemMap::MapAnonymous("image reservation",
-                                                  reinterpret_cast<byte*>(ART_BASE_ADDRESS),
-                                                  (size_t)100 * 1024 * 1024,  // 100MB
-                                                  PROT_NONE,
-                                                  false /* no need for 4gb flag with fixed mmap*/,
-                                                  &error_msg));
-    CHECK(image_reservation_.get() != nullptr) << error_msg;
-  }
+  void ReserveImageSpace();
 
-  void UnreserveImageSpace() {
-    image_reservation_.reset();
-  }
+  void UnreserveImageSpace();
 
   std::unique_ptr<CompilerOptions> compiler_options_;
   std::unique_ptr<VerificationResults> verification_results_;
   std::unique_ptr<DexFileToMethodInlinerMap> method_inliner_map_;
-  std::unique_ptr<CompilerCallbacksImpl> callbacks_;
+  std::unique_ptr<CompilerCallbacks> callbacks_;
   std::unique_ptr<CompilerDriver> compiler_driver_;
   std::unique_ptr<CumulativeLogger> timer_;
 
diff --git a/compiler/dex/quick/arm64/assemble_arm64.cc b/compiler/dex/quick/arm64/assemble_arm64.cc
index 083277d..462be54 100644
--- a/compiler/dex/quick/arm64/assemble_arm64.cc
+++ b/compiler/dex/quick/arm64/assemble_arm64.cc
@@ -655,10 +655,10 @@
             if (kIsDebugBuild && (kFailOnSizeError || kReportSizeError)) {
               // Register usage checks: First establish register usage requirements based on the
               // format in `kind'.
-              bool want_float = false;
-              bool want_64_bit = false;
-              bool want_var_size = true;
-              bool want_zero = false;
+              bool want_float = false;     // Want a float (rather than core) register.
+              bool want_64_bit = false;    // Want a 64-bit (rather than 32-bit) register.
+              bool want_var_size = true;   // Want register with variable size (kFmtReg{R,F}).
+              bool want_zero = false;      // Want the zero (rather than sp) register.
               switch (kind) {
                 case kFmtRegX:
                   want_64_bit = true;
@@ -717,9 +717,6 @@
                 }
               }
 
-              // TODO(Arm64): if !want_size_match, then we still should compare the size of the
-              //   register with the size required by the instruction width (kA64Wide).
-
               // Fail, if `expected' contains an unsatisfied requirement.
               if (expected != nullptr) {
                 LOG(WARNING) << "Method: " << PrettyMethod(cu_->method_idx, *cu_->dex_file)
@@ -734,11 +731,12 @@
               }
             }
 
-            // TODO(Arm64): this may or may not be necessary, depending on how wzr, xzr are
-            //   defined.
-            if (is_zero) {
-              operand = 31;
-            }
+            // In the lines below, we rely on (operand & 0x1f) == 31 to be true for register sp
+            // and zr. This means that these two registers do not need any special treatment, as
+            // their bottom 5 bits are correctly set to 31 == 0b11111, which is the right
+            // value for encoding both sp and zr.
+            COMPILE_ASSERT((rxzr & 0x1f) == 0x1f, rzr_register_number_must_be_31);
+            COMPILE_ASSERT((rsp & 0x1f) == 0x1f, rsp_register_number_must_be_31);
           }
 
           value = (operand << encoder->field_loc[i].start) &
diff --git a/compiler/dex/quick/arm64/codegen_arm64.h b/compiler/dex/quick/arm64/codegen_arm64.h
index e4eeeaf..de97653 100644
--- a/compiler/dex/quick/arm64/codegen_arm64.h
+++ b/compiler/dex/quick/arm64/codegen_arm64.h
@@ -105,16 +105,14 @@
     // Required for target - register utilities.
     RegStorage TargetReg(SpecialTargetRegister reg) OVERRIDE;
     RegStorage TargetReg(SpecialTargetRegister symbolic_reg, WideKind wide_kind) OVERRIDE {
-      RegStorage reg = TargetReg(symbolic_reg);
       if (wide_kind == kWide || wide_kind == kRef) {
-        return (reg.Is64Bit()) ? reg : As64BitReg(reg);
+        return As64BitReg(TargetReg(symbolic_reg));
       } else {
-        return (reg.Is32Bit()) ? reg : As32BitReg(reg);
+        return Check32BitReg(TargetReg(symbolic_reg));
       }
     }
     RegStorage TargetPtrReg(SpecialTargetRegister symbolic_reg) OVERRIDE {
-      RegStorage reg = TargetReg(symbolic_reg);
-      return (reg.Is64Bit() ? reg : As64BitReg(reg));
+      return As64BitReg(TargetReg(symbolic_reg));
     }
     RegStorage GetArgMappingToPhysicalReg(int arg_num);
     RegLocation GetReturnAlt();
diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc
index 2212380..6a27ad0 100644
--- a/compiler/dex/quick/arm64/target_arm64.cc
+++ b/compiler/dex/quick/arm64/target_arm64.cc
@@ -108,19 +108,19 @@
 RegStorage Arm64Mir2Lir::TargetReg(SpecialTargetRegister reg) {
   RegStorage res_reg = RegStorage::InvalidReg();
   switch (reg) {
-    case kSelf: res_reg = rs_xSELF; break;
-    case kSuspend: res_reg = rs_xSUSPEND; break;
-    case kLr: res_reg =  rs_xLR; break;
+    case kSelf: res_reg = rs_wSELF; break;
+    case kSuspend: res_reg = rs_wSUSPEND; break;
+    case kLr: res_reg =  rs_wLR; break;
     case kPc: res_reg = RegStorage::InvalidReg(); break;
-    case kSp: res_reg =  rs_sp; break;
-    case kArg0: res_reg = rs_x0; break;
-    case kArg1: res_reg = rs_x1; break;
-    case kArg2: res_reg = rs_x2; break;
-    case kArg3: res_reg = rs_x3; break;
-    case kArg4: res_reg = rs_x4; break;
-    case kArg5: res_reg = rs_x5; break;
-    case kArg6: res_reg = rs_x6; break;
-    case kArg7: res_reg = rs_x7; break;
+    case kSp: res_reg =  rs_wsp; break;
+    case kArg0: res_reg = rs_w0; break;
+    case kArg1: res_reg = rs_w1; break;
+    case kArg2: res_reg = rs_w2; break;
+    case kArg3: res_reg = rs_w3; break;
+    case kArg4: res_reg = rs_w4; break;
+    case kArg5: res_reg = rs_w5; break;
+    case kArg6: res_reg = rs_w6; break;
+    case kArg7: res_reg = rs_w7; break;
     case kFArg0: res_reg = rs_f0; break;
     case kFArg1: res_reg = rs_f1; break;
     case kFArg2: res_reg = rs_f2; break;
@@ -129,10 +129,10 @@
     case kFArg5: res_reg = rs_f5; break;
     case kFArg6: res_reg = rs_f6; break;
     case kFArg7: res_reg = rs_f7; break;
-    case kRet0: res_reg = rs_x0; break;
-    case kRet1: res_reg = rs_x1; break;
-    case kInvokeTgt: res_reg = rs_xLR; break;
-    case kHiddenArg: res_reg = rs_x12; break;
+    case kRet0: res_reg = rs_w0; break;
+    case kRet1: res_reg = rs_w1; break;
+    case kInvokeTgt: res_reg = rs_wLR; break;
+    case kHiddenArg: res_reg = rs_w12; break;
     case kHiddenFpArg: res_reg = RegStorage::InvalidReg(); break;
     case kCount: res_reg = RegStorage::InvalidReg(); break;
     default: res_reg = RegStorage::InvalidReg();
@@ -929,13 +929,13 @@
    */
   RegLocation rl_src = rl_method;
   rl_src.location = kLocPhysReg;
-  rl_src.reg = TargetReg(kArg0);
+  rl_src.reg = TargetReg(kArg0, kRef);
   rl_src.home = false;
   MarkLive(rl_src);
   StoreValue(rl_method, rl_src);
   // If Method* has been promoted, explicitly flush
   if (rl_method.location == kLocPhysReg) {
-    StoreRefDisp(TargetReg(kSp), 0, TargetReg(kArg0), kNotVolatile);
+    StoreRefDisp(TargetPtrReg(kSp), 0, rl_src.reg, kNotVolatile);
   }
 
   if (cu_->num_ins == 0) {
@@ -961,9 +961,9 @@
       } else {
         // Needs flush.
         if (t_loc->ref) {
-          StoreRefDisp(TargetReg(kSp), SRegOffset(start_vreg + i), reg, kNotVolatile);
+          StoreRefDisp(TargetPtrReg(kSp), SRegOffset(start_vreg + i), reg, kNotVolatile);
         } else {
-          StoreBaseDisp(TargetReg(kSp), SRegOffset(start_vreg + i), reg, t_loc->wide ? k64 : k32,
+          StoreBaseDisp(TargetPtrReg(kSp), SRegOffset(start_vreg + i), reg, t_loc->wide ? k64 : k32,
               kNotVolatile);
         }
       }
@@ -971,9 +971,9 @@
       // If arriving in frame & promoted.
       if (t_loc->location == kLocPhysReg) {
         if (t_loc->ref) {
-          LoadRefDisp(TargetReg(kSp), SRegOffset(start_vreg + i), t_loc->reg, kNotVolatile);
+          LoadRefDisp(TargetPtrReg(kSp), SRegOffset(start_vreg + i), t_loc->reg, kNotVolatile);
         } else {
-          LoadBaseDisp(TargetReg(kSp), SRegOffset(start_vreg + i), t_loc->reg,
+          LoadBaseDisp(TargetPtrReg(kSp), SRegOffset(start_vreg + i), t_loc->reg,
                        t_loc->wide ? k64 : k32, kNotVolatile);
         }
       }
@@ -1070,7 +1070,7 @@
         loc = UpdateLocWide(loc);
         if (loc.location == kLocPhysReg) {
           ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
-          StoreBaseDisp(TargetReg(kSp), SRegOffset(loc.s_reg_low), loc.reg, k64, kNotVolatile);
+          StoreBaseDisp(TargetPtrReg(kSp), SRegOffset(loc.s_reg_low), loc.reg, k64, kNotVolatile);
         }
         next_arg += 2;
       } else {
@@ -1078,9 +1078,10 @@
         if (loc.location == kLocPhysReg) {
           ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
           if (loc.ref) {
-            StoreRefDisp(TargetReg(kSp), SRegOffset(loc.s_reg_low), loc.reg, kNotVolatile);
+            StoreRefDisp(TargetPtrReg(kSp), SRegOffset(loc.s_reg_low), loc.reg, kNotVolatile);
           } else {
-            StoreBaseDisp(TargetReg(kSp), SRegOffset(loc.s_reg_low), loc.reg, k32, kNotVolatile);
+            StoreBaseDisp(TargetPtrReg(kSp), SRegOffset(loc.s_reg_low), loc.reg, k32,
+                          kNotVolatile);
           }
         }
         next_arg++;
@@ -1114,8 +1115,8 @@
       RegStorage temp = TargetReg(kArg3, kNotWide);
 
       // Now load the argument VR and store to the outs.
-      Load32Disp(TargetReg(kSp), current_src_offset, temp);
-      Store32Disp(TargetReg(kSp), current_dest_offset, temp);
+      Load32Disp(TargetPtrReg(kSp), current_src_offset, temp);
+      Store32Disp(TargetPtrReg(kSp), current_dest_offset, temp);
 
       current_src_offset += bytes_to_move;
       current_dest_offset += bytes_to_move;
@@ -1126,8 +1127,7 @@
 
   // Now handle rest not registers if they are
   if (in_to_reg_storage_mapping.IsThereStackMapped()) {
-    RegStorage regSingle = TargetReg(kArg2);
-    RegStorage regWide = RegStorage::Solo64(TargetReg(kArg3).GetReg());
+    RegStorage regWide = TargetReg(kArg3, kWide);
     for (int i = start_index; i <= last_mapped_in + regs_left_to_pass_via_stack; i++) {
       RegLocation rl_arg = info->args[i];
       rl_arg = UpdateRawLoc(rl_arg);
@@ -1139,25 +1139,27 @@
           ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
           if (rl_arg.wide) {
             if (rl_arg.location == kLocPhysReg) {
-              StoreBaseDisp(TargetReg(kSp), out_offset, rl_arg.reg, k64, kNotVolatile);
+              StoreBaseDisp(TargetPtrReg(kSp), out_offset, rl_arg.reg, k64, kNotVolatile);
             } else {
               LoadValueDirectWideFixed(rl_arg, regWide);
-              StoreBaseDisp(TargetReg(kSp), out_offset, regWide, k64, kNotVolatile);
+              StoreBaseDisp(TargetPtrReg(kSp), out_offset, regWide, k64, kNotVolatile);
             }
           } else {
             if (rl_arg.location == kLocPhysReg) {
               if (rl_arg.ref) {
-                StoreRefDisp(TargetReg(kSp), out_offset, rl_arg.reg, kNotVolatile);
+                StoreRefDisp(TargetPtrReg(kSp), out_offset, rl_arg.reg, kNotVolatile);
               } else {
-                StoreBaseDisp(TargetReg(kSp), out_offset, rl_arg.reg, k32, kNotVolatile);
+                StoreBaseDisp(TargetPtrReg(kSp), out_offset, rl_arg.reg, k32, kNotVolatile);
               }
             } else {
               if (rl_arg.ref) {
+                RegStorage regSingle = TargetReg(kArg2, kRef);
                 LoadValueDirectFixed(rl_arg, regSingle);
-                StoreRefDisp(TargetReg(kSp), out_offset, regSingle, kNotVolatile);
+                StoreRefDisp(TargetPtrReg(kSp), out_offset, regSingle, kNotVolatile);
               } else {
-                LoadValueDirectFixed(rl_arg, As32BitReg(regSingle));
-                StoreBaseDisp(TargetReg(kSp), out_offset, As32BitReg(regSingle), k32, kNotVolatile);
+                RegStorage regSingle = TargetReg(kArg2, kNotWide);
+                LoadValueDirectFixed(rl_arg, regSingle);
+                StoreBaseDisp(TargetPtrReg(kSp), out_offset, regSingle, k32, kNotVolatile);
               }
             }
           }
@@ -1194,13 +1196,13 @@
                            direct_code, direct_method, type);
   if (pcrLabel) {
     if (cu_->compiler_driver->GetCompilerOptions().GetExplicitNullChecks()) {
-      *pcrLabel = GenExplicitNullCheck(TargetReg(kArg1), info->opt_flags);
+      *pcrLabel = GenExplicitNullCheck(TargetReg(kArg1, kRef), info->opt_flags);
     } else {
       *pcrLabel = nullptr;
       // In lieu of generating a check for kArg1 being null, we need to
       // perform a load when doing implicit checks.
       RegStorage tmp = AllocTemp();
-      Load32Disp(TargetReg(kArg1), 0, tmp);
+      Load32Disp(TargetReg(kArg1, kRef), 0, tmp);
       MarkPossibleNullPointerException(info->opt_flags);
       FreeTemp(tmp);
     }
diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc
index 45dd7f0..0e46c96 100644
--- a/compiler/dex/quick/dex_file_method_inliner.cc
+++ b/compiler/dex/quick/dex_file_method_inliner.cc
@@ -48,6 +48,7 @@
     true,   // kIntrinsicMinMaxFloat
     true,   // kIntrinsicMinMaxDouble
     true,   // kIntrinsicSqrt
+    false,  // kIntrinsicGet
     false,  // kIntrinsicCharAt
     false,  // kIntrinsicCompareTo
     false,  // kIntrinsicIsEmptyOrLength
@@ -74,6 +75,7 @@
 COMPILE_ASSERT(kIntrinsicIsStatic[kIntrinsicMinMaxFloat], MinMaxFloat_must_be_static);
 COMPILE_ASSERT(kIntrinsicIsStatic[kIntrinsicMinMaxDouble], MinMaxDouble_must_be_static);
 COMPILE_ASSERT(kIntrinsicIsStatic[kIntrinsicSqrt], Sqrt_must_be_static);
+COMPILE_ASSERT(!kIntrinsicIsStatic[kIntrinsicGet], Get_must_not_be_static);
 COMPILE_ASSERT(!kIntrinsicIsStatic[kIntrinsicCharAt], CharAt_must_not_be_static);
 COMPILE_ASSERT(!kIntrinsicIsStatic[kIntrinsicCompareTo], CompareTo_must_not_be_static);
 COMPILE_ASSERT(!kIntrinsicIsStatic[kIntrinsicIsEmptyOrLength], IsEmptyOrLength_must_not_be_static);
@@ -126,6 +128,7 @@
     "D",                       // kClassCacheDouble
     "V",                       // kClassCacheVoid
     "Ljava/lang/Object;",      // kClassCacheJavaLangObject
+    "Ljava/lang/ref/Reference;",  // kClassCacheJavaLangRefReference
     "Ljava/lang/String;",      // kClassCacheJavaLangString
     "Ljava/lang/Double;",      // kClassCacheJavaLangDouble
     "Ljava/lang/Float;",       // kClassCacheJavaLangFloat
@@ -152,6 +155,7 @@
     "max",                   // kNameCacheMax
     "min",                   // kNameCacheMin
     "sqrt",                  // kNameCacheSqrt
+    "get",                   // kNameCacheGet
     "charAt",                // kNameCacheCharAt
     "compareTo",             // kNameCacheCompareTo
     "isEmpty",               // kNameCacheIsEmpty
@@ -220,6 +224,8 @@
     { kClassCacheBoolean, 0, { } },
     // kProtoCache_I
     { kClassCacheInt, 0, { } },
+    // kProtoCache_Object
+    { kClassCacheJavaLangObject, 0, { } },
     // kProtoCache_Thread
     { kClassCacheJavaLangThread, 0, { } },
     // kProtoCacheJ_B
@@ -308,6 +314,8 @@
     INTRINSIC(JavaLangMath,       Sqrt, D_D, kIntrinsicSqrt, 0),
     INTRINSIC(JavaLangStrictMath, Sqrt, D_D, kIntrinsicSqrt, 0),
 
+    INTRINSIC(JavaLangRefReference, Get, _Object, kIntrinsicGet, 0),
+
     INTRINSIC(JavaLangString, CharAt, I_C, kIntrinsicCharAt, 0),
     INTRINSIC(JavaLangString, CompareTo, String_I, kIntrinsicCompareTo, 0),
     INTRINSIC(JavaLangString, IsEmpty, _Z, kIntrinsicIsEmptyOrLength, kIntrinsicFlagIsEmpty),
@@ -428,6 +436,8 @@
       return backend->GenInlinedMinMaxFP(info, intrinsic.d.data & kIntrinsicFlagMin, true /* is_double */);
     case kIntrinsicSqrt:
       return backend->GenInlinedSqrt(info);
+    case kIntrinsicGet:
+      return backend->GenInlinedGet(info);
     case kIntrinsicCharAt:
       return backend->GenInlinedCharAt(info);
     case kIntrinsicCompareTo:
diff --git a/compiler/dex/quick/dex_file_method_inliner.h b/compiler/dex/quick/dex_file_method_inliner.h
index 5b3b104..cb8c165 100644
--- a/compiler/dex/quick/dex_file_method_inliner.h
+++ b/compiler/dex/quick/dex_file_method_inliner.h
@@ -107,6 +107,7 @@
       kClassCacheDouble,
       kClassCacheVoid,
       kClassCacheJavaLangObject,
+      kClassCacheJavaLangRefReference,
       kClassCacheJavaLangString,
       kClassCacheJavaLangDouble,
       kClassCacheJavaLangFloat,
@@ -140,6 +141,7 @@
       kNameCacheMax,
       kNameCacheMin,
       kNameCacheSqrt,
+      kNameCacheGet,
       kNameCacheCharAt,
       kNameCacheCompareTo,
       kNameCacheIsEmpty,
@@ -199,6 +201,7 @@
       kProtoCacheString_I,
       kProtoCache_Z,
       kProtoCache_I,
+      kProtoCache_Object,
       kProtoCache_Thread,
       kProtoCacheJ_B,
       kProtoCacheJ_I,
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index 79065b3..9dedeae 100755
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -23,9 +23,12 @@
 #include "invoke_type.h"
 #include "mirror/array.h"
 #include "mirror/class-inl.h"
+#include "mirror/dex_cache.h"
 #include "mirror/object_array-inl.h"
+#include "mirror/reference-inl.h"
 #include "mirror/string.h"
 #include "mir_to_lir-inl.h"
+#include "scoped_thread_state_change.h"
 #include "x86/codegen_x86.h"
 
 namespace art {
@@ -1218,6 +1221,88 @@
   return res;
 }
 
+bool Mir2Lir::GenInlinedGet(CallInfo* info) {
+  if (cu_->instruction_set == kMips) {
+    // TODO - add Mips implementation
+    return false;
+  }
+
+  // the refrence class is stored in the image dex file which might not be the same as the cu's
+  // dex file. Query the reference class for the image dex file then reset to starting dex file
+  // in after loading class type.
+  uint16_t type_idx = 0;
+  const DexFile* ref_dex_file = nullptr;
+  {
+    ScopedObjectAccess soa(Thread::Current());
+    type_idx = mirror::Reference::GetJavaLangRefReference()->GetDexTypeIndex();
+    ref_dex_file = mirror::Reference::GetJavaLangRefReference()->GetDexCache()->GetDexFile();
+  }
+  CHECK(LIKELY(ref_dex_file != nullptr));
+
+  // address is either static within the image file, or needs to be patched up after compilation.
+  bool unused_type_initialized;
+  bool use_direct_type_ptr;
+  uintptr_t direct_type_ptr;
+  bool is_finalizable;
+  const DexFile* old_dex = cu_->dex_file;
+  cu_->dex_file = ref_dex_file;
+  RegStorage reg_class = TargetPtrReg(kArg1);
+  if (!cu_->compiler_driver->CanEmbedTypeInCode(*ref_dex_file, type_idx, &unused_type_initialized,
+                                                &use_direct_type_ptr, &direct_type_ptr,
+                                                &is_finalizable) || is_finalizable) {
+    cu_->dex_file = old_dex;
+    // address is not known and post-compile patch is not possible, cannot insert intrinsic.
+    return false;
+  }
+  if (use_direct_type_ptr) {
+    LoadConstant(reg_class, direct_type_ptr);
+  } else {
+    LoadClassType(type_idx, kArg1);
+  }
+  cu_->dex_file = old_dex;
+
+  // get the offset for flags in reference class.
+  uint32_t slow_path_flag_offset = 0;
+  uint32_t disable_flag_offset = 0;
+  {
+    ScopedObjectAccess soa(Thread::Current());
+    mirror::Class* reference_class = mirror::Reference::GetJavaLangRefReference();
+    slow_path_flag_offset = reference_class->GetSlowPathFlagOffset().Uint32Value();
+    disable_flag_offset = reference_class->GetDisableIntrinsicFlagOffset().Uint32Value();
+  }
+  CHECK(slow_path_flag_offset && disable_flag_offset &&
+        (slow_path_flag_offset != disable_flag_offset));
+
+  // intrinsic logic start.
+  RegLocation rl_obj = info->args[0];
+  rl_obj = LoadValue(rl_obj);
+
+  RegStorage reg_slow_path = AllocTemp();
+  RegStorage reg_disabled = AllocTemp();
+  Load32Disp(reg_class, slow_path_flag_offset, reg_slow_path);
+  Load32Disp(reg_class, disable_flag_offset, reg_disabled);
+  OpRegRegReg(kOpOr, reg_slow_path, reg_slow_path, reg_disabled);
+  FreeTemp(reg_disabled);
+
+  // if slow path, jump to JNI path target
+  LIR* slow_path_branch = OpCmpImmBranch(kCondNe, reg_slow_path, 0, nullptr);
+  FreeTemp(reg_slow_path);
+
+  // slow path not enabled, simply load the referent of the reference object
+  RegLocation rl_dest = InlineTarget(info);
+  RegLocation rl_result = EvalLoc(rl_dest, kRefReg, true);
+  GenNullCheck(rl_obj.reg, info->opt_flags);
+  LoadRefDisp(rl_obj.reg, mirror::Reference::ReferentOffset().Int32Value(), rl_result.reg,
+      kNotVolatile);
+  MarkPossibleNullPointerException(info->opt_flags);
+  StoreValue(rl_dest, rl_result);
+
+  LIR* intrinsic_finish = NewLIR0(kPseudoTargetLabel);
+  AddIntrinsicSlowPath(info, slow_path_branch, intrinsic_finish);
+
+  return true;
+}
+
 bool Mir2Lir::GenInlinedCharAt(CallInfo* info) {
   if (cu_->instruction_set == kMips) {
     // TODO - add Mips implementation
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 07c615f..edb3b23 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -18,7 +18,6 @@
 #include "dex/dataflow_iterator-inl.h"
 #include "dex/quick/dex_file_method_inliner.h"
 #include "mir_to_lir-inl.h"
-#include "object_utils.h"
 #include "thread-inl.h"
 
 namespace art {
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index 634ab94..c68ad6b 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -982,6 +982,7 @@
      */
     RegLocation InlineTargetWide(CallInfo* info);
 
+    bool GenInlinedGet(CallInfo* info);
     bool GenInlinedCharAt(CallInfo* info);
     bool GenInlinedStringIsEmptyOrLength(CallInfo* info, bool is_empty);
     virtual bool GenInlinedReverseBits(CallInfo* info, OpSize size);
@@ -1201,7 +1202,7 @@
      * @param wide_kind What kind of view of the special register is required.
      * @return Return the #RegStorage corresponding to the given purpose @p reg.
      *
-     * Note: For 32b system, wide (kWide) views only make sense for the argument registers and the
+     * @note For 32b system, wide (kWide) views only make sense for the argument registers and the
      *       return. In that case, this function should return a pair where the first component of
      *       the result will be the indicated special register.
      */
diff --git a/compiler/dex/quick_compiler_callbacks.cc b/compiler/dex/quick_compiler_callbacks.cc
new file mode 100644
index 0000000..03bda78
--- /dev/null
+++ b/compiler/dex/quick_compiler_callbacks.cc
@@ -0,0 +1,39 @@
+/*
+ * 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 "quick_compiler_callbacks.h"
+
+#include "quick/dex_file_to_method_inliner_map.h"
+#include "verifier/method_verifier-inl.h"
+#include "verification_results.h"
+
+namespace art {
+
+bool QuickCompilerCallbacks::MethodVerified(verifier::MethodVerifier* verifier) {
+  bool result = verification_results_->ProcessVerifiedMethod(verifier);
+  if (result) {
+    MethodReference ref = verifier->GetMethodReference();
+    method_inliner_map_->GetMethodInliner(ref.dex_file)
+        ->AnalyseMethodCode(verifier);
+  }
+  return result;
+}
+
+void QuickCompilerCallbacks::ClassRejected(ClassReference ref) {
+  verification_results_->AddRejectedClass(ref);
+}
+
+}  // namespace art
diff --git a/compiler/dex/quick_compiler_callbacks.h b/compiler/dex/quick_compiler_callbacks.h
new file mode 100644
index 0000000..7c9614f
--- /dev/null
+++ b/compiler/dex/quick_compiler_callbacks.h
@@ -0,0 +1,51 @@
+/*
+ * 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_COMPILER_DEX_QUICK_COMPILER_CALLBACKS_H_
+#define ART_COMPILER_DEX_QUICK_COMPILER_CALLBACKS_H_
+
+#include "compiler_callbacks.h"
+
+namespace art {
+
+class VerificationResults;
+class DexFileToMethodInlinerMap;
+
+class QuickCompilerCallbacks FINAL : public CompilerCallbacks {
+  public:
+    QuickCompilerCallbacks(VerificationResults* verification_results,
+                           DexFileToMethodInlinerMap* method_inliner_map)
+        : verification_results_(verification_results),
+          method_inliner_map_(method_inliner_map) {
+      CHECK(verification_results != nullptr);
+      CHECK(method_inliner_map != nullptr);
+    }
+
+    ~QuickCompilerCallbacks() { }
+
+    bool MethodVerified(verifier::MethodVerifier* verifier)
+        SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE;
+
+    void ClassRejected(ClassReference ref) OVERRIDE;
+
+  private:
+    VerificationResults* const verification_results_;
+    DexFileToMethodInlinerMap* const method_inliner_map_;
+};
+
+}  // namespace art
+
+#endif  // ART_COMPILER_DEX_QUICK_COMPILER_CALLBACKS_H_
diff --git a/compiler/driver/compiler_callbacks_impl.h b/compiler/driver/compiler_callbacks_impl.h
deleted file mode 100644
index 92adb20..0000000
--- a/compiler/driver/compiler_callbacks_impl.h
+++ /dev/null
@@ -1,61 +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_COMPILER_DRIVER_COMPILER_CALLBACKS_IMPL_H_
-#define ART_COMPILER_DRIVER_COMPILER_CALLBACKS_IMPL_H_
-
-#include "compiler_callbacks.h"
-#include "dex/quick/dex_file_to_method_inliner_map.h"
-#include "verifier/method_verifier-inl.h"
-
-namespace art {
-
-class CompilerCallbacksImpl FINAL : public CompilerCallbacks {
-  public:
-    CompilerCallbacksImpl(VerificationResults* verification_results,
-                          DexFileToMethodInlinerMap* method_inliner_map)
-        : verification_results_(verification_results),
-          method_inliner_map_(method_inliner_map) {
-      CHECK(verification_results != nullptr);
-      CHECK(method_inliner_map != nullptr);
-    }
-
-    ~CompilerCallbacksImpl() { }
-
-    bool MethodVerified(verifier::MethodVerifier* verifier)
-        SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE;
-    void ClassRejected(ClassReference ref) OVERRIDE {
-      verification_results_->AddRejectedClass(ref);
-    }
-
-  private:
-    VerificationResults* const verification_results_;
-    DexFileToMethodInlinerMap* const method_inliner_map_;
-};
-
-inline bool CompilerCallbacksImpl::MethodVerified(verifier::MethodVerifier* verifier) {
-  bool result = verification_results_->ProcessVerifiedMethod(verifier);
-  if (result) {
-    MethodReference ref = verifier->GetMethodReference();
-    method_inliner_map_->GetMethodInliner(ref.dex_file)
-        ->AnalyseMethodCode(verifier);
-  }
-  return result;
-}
-
-}  // namespace art
-
-#endif  // ART_COMPILER_DRIVER_COMPILER_CALLBACKS_IMPL_H_
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h
index e175d37..89295f2 100644
--- a/compiler/driver/compiler_driver-inl.h
+++ b/compiler/driver/compiler_driver-inl.h
@@ -20,12 +20,10 @@
 #include "compiler_driver.h"
 
 #include "dex/compiler_ir.h"
-#include "mirror/art_field.h"
+#include "field_helper.h"
 #include "mirror/art_field-inl.h"
-#include "mirror/art_method.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class_loader.h"
-#include "mirror/dex_cache.h"
 #include "mirror/dex_cache-inl.h"
 #include "mirror/art_field-inl.h"
 #include "scoped_thread_state_change.h"
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 7014c3b..9e88c8d 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -35,7 +35,7 @@
 #include "dex/quick/dex_file_method_inliner.h"
 #include "driver/compiler_options.h"
 #include "jni_internal.h"
-#include "object_utils.h"
+#include "object_lock.h"
 #include "profiler.h"
 #include "runtime.h"
 #include "gc/accounting/card_table-inl.h"
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index 5325a68..9ae9bd4 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -25,12 +25,13 @@
 #include "dex_file.h"
 #include "gc/heap.h"
 #include "mirror/art_method-inl.h"
-#include "mirror/class.h"
 #include "mirror/class-inl.h"
+#include "mirror/class_loader.h"
 #include "mirror/dex_cache-inl.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/object-inl.h"
 #include "handle_scope-inl.h"
+#include "scoped_thread_state_change.h"
 
 namespace art {
 
diff --git a/compiler/elf_writer_test.cc b/compiler/elf_writer_test.cc
index e637cfb..e479322 100644
--- a/compiler/elf_writer_test.cc
+++ b/compiler/elf_writer_test.cc
@@ -16,8 +16,10 @@
 
 #include "elf_file.h"
 
+#include "base/stringprintf.h"
 #include "common_compiler_test.h"
 #include "oat.h"
+#include "utils.h"
 
 namespace art {
 
diff --git a/compiler/image_test.cc b/compiler/image_test.cc
index 6b26980..982e6d4 100644
--- a/compiler/image_test.cc
+++ b/compiler/image_test.cc
@@ -20,14 +20,16 @@
 #include <string>
 #include <vector>
 
+#include "base/unix_file/fd_file.h"
 #include "common_compiler_test.h"
-#include "compiler/elf_fixup.h"
-#include "compiler/image_writer.h"
-#include "compiler/oat_writer.h"
+#include "elf_fixup.h"
 #include "gc/space/image_space.h"
+#include "image_writer.h"
 #include "implicit_check_options.h"
 #include "lock_word.h"
 #include "mirror/object-inl.h"
+#include "oat_writer.h"
+#include "scoped_thread_state_change.h"
 #include "signal_catcher.h"
 #include "utils.h"
 #include "vector_output_stream.h"
@@ -138,7 +140,7 @@
   // Remove the reservation of the memory for use to load the image.
   UnreserveImageSpace();
 
-  Runtime::Options options;
+  RuntimeOptions options;
   std::string image("-Ximage:");
   image.append(image_location.GetFilename());
   options.push_back(std::make_pair(image.c_str(), reinterpret_cast<void*>(NULL)));
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index 38b4100..8ef2964 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -51,7 +51,6 @@
 #include "mirror/string-inl.h"
 #include "oat.h"
 #include "oat_file.h"
-#include "object_utils.h"
 #include "runtime.h"
 #include "scoped_thread_state_change.h"
 #include "handle_scope-inl.h"
diff --git a/compiler/jni/quick/calling_convention.h b/compiler/jni/quick/calling_convention.h
index efc0b42..6db0c3b 100644
--- a/compiler/jni/quick/calling_convention.h
+++ b/compiler/jni/quick/calling_convention.h
@@ -19,6 +19,7 @@
 
 #include <vector>
 #include "handle_scope.h"
+#include "primitive.h"
 #include "thread.h"
 #include "utils/managed_register.h"
 
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index d2ee0ed..1444ca0 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -15,15 +15,19 @@
  */
 
 #include "common_compiler_test.h"
-#include "compiler/compiler.h"
-#include "compiler/oat_writer.h"
+#include "compiler.h"
+#include "dex/verification_results.h"
+#include "dex/quick/dex_file_to_method_inliner_map.h"
+#include "dex/quick_compiler_callbacks.h"
 #include "entrypoints/quick/quick_entrypoints.h"
 #include "implicit_check_options.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class-inl.h"
-#include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
+#include "mirror/object-inl.h"
 #include "oat_file-inl.h"
+#include "oat_writer.h"
+#include "scoped_thread_state_change.h"
 #include "vector_output_stream.h"
 
 namespace art {
@@ -95,8 +99,8 @@
   compiler_options_.reset(new CompilerOptions);
   verification_results_.reset(new VerificationResults(compiler_options_.get()));
   method_inliner_map_.reset(new DexFileToMethodInlinerMap);
-  callbacks_.reset(new CompilerCallbacksImpl(verification_results_.get(),
-                                             method_inliner_map_.get()));
+  callbacks_.reset(new QuickCompilerCallbacks(verification_results_.get(),
+                                              method_inliner_map_.get()));
   timer_.reset(new CumulativeLogger("Compilation times"));
   compiler_driver_.reset(new CompilerDriver(compiler_options_.get(),
                                             verification_results_.get(),
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index ca846b3..e87b044 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -19,6 +19,7 @@
 
 #include "locations.h"
 #include "offsets.h"
+#include "primitive.h"
 #include "utils/allocation.h"
 #include "utils/arena_bit_vector.h"
 #include "utils/growable_array.h"
diff --git a/compiler/optimizing/register_allocator.h b/compiler/optimizing/register_allocator.h
index 7d4cd1a..e35ff56 100644
--- a/compiler/optimizing/register_allocator.h
+++ b/compiler/optimizing/register_allocator.h
@@ -18,6 +18,7 @@
 #define ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_H_
 
 #include "base/macros.h"
+#include "primitive.h"
 #include "utils/growable_array.h"
 
 namespace art {
diff --git a/compiler/output_stream_test.cc b/compiler/output_stream_test.cc
index 5fa0ccb..315ca09 100644
--- a/compiler/output_stream_test.cc
+++ b/compiler/output_stream_test.cc
@@ -17,6 +17,7 @@
 #include "file_output_stream.h"
 #include "vector_output_stream.h"
 
+#include "base/unix_file/fd_file.h"
 #include "base/logging.h"
 #include "buffered_output_stream.h"
 #include "common_runtime_test.h"
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 0d40c8d..77946b0 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -40,7 +40,8 @@
 #include "dex_file-inl.h"
 #include "dex/pass_driver_me_opts.h"
 #include "dex/verification_results.h"
-#include "driver/compiler_callbacks_impl.h"
+#include "dex/quick_compiler_callbacks.h"
+#include "dex/quick/dex_file_to_method_inliner_map.h"
 #include "driver/compiler_driver.h"
 #include "driver/compiler_options.h"
 #include "elf_fixup.h"
@@ -56,7 +57,6 @@
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
 #include "oat_writer.h"
-#include "object_utils.h"
 #include "os.h"
 #include "runtime.h"
 #include "ScopedLocalRef.h"
@@ -233,7 +233,7 @@
 class Dex2Oat {
  public:
   static bool Create(Dex2Oat** p_dex2oat,
-                     const Runtime::Options& runtime_options,
+                     const RuntimeOptions& runtime_options,
                      const CompilerOptions& compiler_options,
                      Compiler::Kind compiler_kind,
                      InstructionSet instruction_set,
@@ -460,7 +460,7 @@
     CHECK(method_inliner_map != nullptr);
   }
 
-  bool CreateRuntime(const Runtime::Options& runtime_options, InstructionSet instruction_set)
+  bool CreateRuntime(const RuntimeOptions& runtime_options, InstructionSet instruction_set)
       SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) {
     if (!Runtime::Create(runtime_options, false)) {
       LOG(ERROR) << "Failed to create runtime";
@@ -1230,7 +1230,7 @@
   timings.StartTiming("dex2oat Setup");
   LOG(INFO) << CommandLine();
 
-  Runtime::Options runtime_options;
+  RuntimeOptions runtime_options;
   std::vector<const DexFile*> boot_class_path;
   if (boot_image_option.empty()) {
     size_t failure_count = OpenDexFiles(dex_filenames, dex_locations, boot_class_path);
@@ -1249,7 +1249,7 @@
   std::unique_ptr<VerificationResults> verification_results(new VerificationResults(
                                                                compiler_options.get()));
   DexFileToMethodInlinerMap method_inliner_map;
-  CompilerCallbacksImpl callbacks(verification_results.get(), &method_inliner_map);
+  QuickCompilerCallbacks callbacks(verification_results.get(), &method_inliner_map);
   runtime_options.push_back(std::make_pair("compilercallbacks", &callbacks));
   runtime_options.push_back(
       std::make_pair("imageinstructionset",
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 0fa1a96..b8f20f3 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -29,6 +29,7 @@
 #include "dex_file-inl.h"
 #include "dex_instruction.h"
 #include "disassembler.h"
+#include "field_helper.h"
 #include "gc_map.h"
 #include "gc/space/image_space.h"
 #include "gc/space/large_object_space.h"
@@ -45,7 +46,6 @@
 #include "noop_compiler_callbacks.h"
 #include "oat.h"
 #include "oat_file-inl.h"
-#include "object_utils.h"
 #include "os.h"
 #include "runtime.h"
 #include "safe_map.h"
@@ -1548,7 +1548,7 @@
     return EXIT_SUCCESS;
   }
 
-  Runtime::Options options;
+  RuntimeOptions options;
   std::string image_option;
   std::string oat_option;
   std::string boot_image_option;
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index dcf8c70..85b4e6d 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -26,6 +26,7 @@
 #include "base/stringprintf.h"
 #include "elf_utils.h"
 #include "elf_file.h"
+#include "gc/space/image_space.h"
 #include "image.h"
 #include "instruction_set.h"
 #include "mirror/art_field.h"
@@ -92,7 +93,7 @@
   }
 
   // Set up the runtime
-  Runtime::Options options;
+  RuntimeOptions options;
   NoopCompilerCallbacks callbacks;
   options.push_back(std::make_pair("compilercallbacks", &callbacks));
   std::string img = "-Ximage:" + image_location;
@@ -176,7 +177,7 @@
   }
 
   // Set up the runtime
-  Runtime::Options options;
+  RuntimeOptions options;
   NoopCompilerCallbacks callbacks;
   options.push_back(std::make_pair("compilercallbacks", &callbacks));
   std::string img = "-Ximage:" + image_location;
diff --git a/runtime/Android.mk b/runtime/Android.mk
index b0c1a9c..f2d3c8e 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -19,290 +19,294 @@
 include art/build/Android.common_build.mk
 
 LIBART_COMMON_SRC_FILES := \
-	atomic.cc.arm \
-	barrier.cc \
-	base/allocator.cc \
-	base/bit_vector.cc \
-	base/hex_dump.cc \
-	base/logging.cc \
-	base/mutex.cc \
-	base/scoped_flock.cc \
-	base/stringpiece.cc \
-	base/stringprintf.cc \
-	base/timing_logger.cc \
-	base/unix_file/fd_file.cc \
-	base/unix_file/mapped_file.cc \
-	base/unix_file/null_file.cc \
-	base/unix_file/random_access_file_utils.cc \
-	base/unix_file/string_file.cc \
-	check_jni.cc \
-	class_linker.cc \
-	common_throws.cc \
-	debugger.cc \
-	dex_file.cc \
-	dex_file_verifier.cc \
-	dex_instruction.cc \
-	elf_file.cc \
-	gc/allocator/dlmalloc.cc \
-	gc/allocator/rosalloc.cc \
-	gc/accounting/card_table.cc \
-	gc/accounting/gc_allocator.cc \
-	gc/accounting/heap_bitmap.cc \
-	gc/accounting/mod_union_table.cc \
-	gc/accounting/remembered_set.cc \
-	gc/accounting/space_bitmap.cc \
-	gc/collector/concurrent_copying.cc \
-	gc/collector/garbage_collector.cc \
-	gc/collector/immune_region.cc \
-	gc/collector/mark_compact.cc \
-	gc/collector/mark_sweep.cc \
-	gc/collector/partial_mark_sweep.cc \
-	gc/collector/semi_space.cc \
-	gc/collector/sticky_mark_sweep.cc \
-	gc/gc_cause.cc \
-	gc/heap.cc \
-	gc/reference_processor.cc \
-	gc/reference_queue.cc \
-	gc/space/bump_pointer_space.cc \
-	gc/space/dlmalloc_space.cc \
-	gc/space/image_space.cc \
-	gc/space/large_object_space.cc \
-	gc/space/malloc_space.cc \
-	gc/space/rosalloc_space.cc \
-	gc/space/space.cc \
-	gc/space/zygote_space.cc \
-	hprof/hprof.cc \
-	image.cc \
-	indirect_reference_table.cc \
-	instruction_set.cc \
-	instrumentation.cc \
-	intern_table.cc \
-	interpreter/interpreter.cc \
-	interpreter/interpreter_common.cc \
-	interpreter/interpreter_switch_impl.cc \
-	jdwp/jdwp_event.cc \
-	jdwp/jdwp_expand_buf.cc \
-	jdwp/jdwp_handler.cc \
-	jdwp/jdwp_main.cc \
-	jdwp/jdwp_request.cc \
-	jdwp/jdwp_socket.cc \
-	jdwp/object_registry.cc \
-	jni_internal.cc \
-	jobject_comparator.cc \
-	mem_map.cc \
-	memory_region.cc \
-	mirror/art_field.cc \
-	mirror/art_method.cc \
-	mirror/array.cc \
-	mirror/class.cc \
-	mirror/dex_cache.cc \
-	mirror/object.cc \
-	mirror/stack_trace_element.cc \
-	mirror/string.cc \
-	mirror/throwable.cc \
-	monitor.cc \
-	native/dalvik_system_DexFile.cc \
-	native/dalvik_system_VMDebug.cc \
-	native/dalvik_system_VMRuntime.cc \
-	native/dalvik_system_VMStack.cc \
-	native/dalvik_system_ZygoteHooks.cc \
-	native/java_lang_Class.cc \
-	native/java_lang_DexCache.cc \
-	native/java_lang_Object.cc \
-	native/java_lang_Runtime.cc \
-	native/java_lang_String.cc \
-	native/java_lang_System.cc \
-	native/java_lang_Thread.cc \
-	native/java_lang_Throwable.cc \
-	native/java_lang_VMClassLoader.cc \
-	native/java_lang_ref_Reference.cc \
-	native/java_lang_reflect_Array.cc \
-	native/java_lang_reflect_Constructor.cc \
-	native/java_lang_reflect_Field.cc \
-	native/java_lang_reflect_Method.cc \
-	native/java_lang_reflect_Proxy.cc \
-	native/java_util_concurrent_atomic_AtomicLong.cc \
-	native/org_apache_harmony_dalvik_ddmc_DdmServer.cc \
-	native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc \
-	native/sun_misc_Unsafe.cc \
-	oat.cc \
-	oat_file.cc \
-	offsets.cc \
-	os_linux.cc \
-	parsed_options.cc \
-	primitive.cc \
-	quick_exception_handler.cc \
-	quick/inline_method_analyser.cc \
-	reference_table.cc \
-	reflection.cc \
-	runtime.cc \
-	signal_catcher.cc \
-	stack.cc \
-	thread.cc \
-	thread_list.cc \
-	thread_pool.cc \
-	throw_location.cc \
-	trace.cc \
-	transaction.cc \
-	profiler.cc \
-	fault_handler.cc \
-	utf.cc \
-	utils.cc \
-	verifier/dex_gc_map.cc \
-	verifier/instruction_flags.cc \
-	verifier/method_verifier.cc \
-	verifier/reg_type.cc \
-	verifier/reg_type_cache.cc \
-	verifier/register_line.cc \
-	well_known_classes.cc \
-	zip_archive.cc
+  atomic.cc.arm \
+  barrier.cc \
+  base/allocator.cc \
+  base/bit_vector.cc \
+  base/hex_dump.cc \
+  base/logging.cc \
+  base/mutex.cc \
+  base/scoped_flock.cc \
+  base/stringpiece.cc \
+  base/stringprintf.cc \
+  base/timing_logger.cc \
+  base/unix_file/fd_file.cc \
+  base/unix_file/mapped_file.cc \
+  base/unix_file/null_file.cc \
+  base/unix_file/random_access_file_utils.cc \
+  base/unix_file/string_file.cc \
+  check_jni.cc \
+  class_linker.cc \
+  common_throws.cc \
+  debugger.cc \
+  dex_file.cc \
+  dex_file_verifier.cc \
+  dex_instruction.cc \
+  elf_file.cc \
+  field_helper.cc \
+  gc/allocator/dlmalloc.cc \
+  gc/allocator/rosalloc.cc \
+  gc/accounting/card_table.cc \
+  gc/accounting/gc_allocator.cc \
+  gc/accounting/heap_bitmap.cc \
+  gc/accounting/mod_union_table.cc \
+  gc/accounting/remembered_set.cc \
+  gc/accounting/space_bitmap.cc \
+  gc/collector/concurrent_copying.cc \
+  gc/collector/garbage_collector.cc \
+  gc/collector/immune_region.cc \
+  gc/collector/mark_compact.cc \
+  gc/collector/mark_sweep.cc \
+  gc/collector/partial_mark_sweep.cc \
+  gc/collector/semi_space.cc \
+  gc/collector/sticky_mark_sweep.cc \
+  gc/gc_cause.cc \
+  gc/heap.cc \
+  gc/reference_processor.cc \
+  gc/reference_queue.cc \
+  gc/space/bump_pointer_space.cc \
+  gc/space/dlmalloc_space.cc \
+  gc/space/image_space.cc \
+  gc/space/large_object_space.cc \
+  gc/space/malloc_space.cc \
+  gc/space/rosalloc_space.cc \
+  gc/space/space.cc \
+  gc/space/zygote_space.cc \
+  hprof/hprof.cc \
+  image.cc \
+  indirect_reference_table.cc \
+  instruction_set.cc \
+  instrumentation.cc \
+  intern_table.cc \
+  interpreter/interpreter.cc \
+  interpreter/interpreter_common.cc \
+  interpreter/interpreter_switch_impl.cc \
+  jdwp/jdwp_event.cc \
+  jdwp/jdwp_expand_buf.cc \
+  jdwp/jdwp_handler.cc \
+  jdwp/jdwp_main.cc \
+  jdwp/jdwp_request.cc \
+  jdwp/jdwp_socket.cc \
+  jdwp/object_registry.cc \
+  jni_internal.cc \
+  jobject_comparator.cc \
+  mem_map.cc \
+  memory_region.cc \
+  method_helper.cc \
+  mirror/art_field.cc \
+  mirror/art_method.cc \
+  mirror/array.cc \
+  mirror/class.cc \
+  mirror/dex_cache.cc \
+  mirror/object.cc \
+  mirror/reference.cc \
+  mirror/stack_trace_element.cc \
+  mirror/string.cc \
+  mirror/throwable.cc \
+  monitor.cc \
+  native/dalvik_system_DexFile.cc \
+  native/dalvik_system_VMDebug.cc \
+  native/dalvik_system_VMRuntime.cc \
+  native/dalvik_system_VMStack.cc \
+  native/dalvik_system_ZygoteHooks.cc \
+  native/java_lang_Class.cc \
+  native/java_lang_DexCache.cc \
+  native/java_lang_Object.cc \
+  native/java_lang_Runtime.cc \
+  native/java_lang_String.cc \
+  native/java_lang_System.cc \
+  native/java_lang_Thread.cc \
+  native/java_lang_Throwable.cc \
+  native/java_lang_VMClassLoader.cc \
+  native/java_lang_ref_Reference.cc \
+  native/java_lang_reflect_Array.cc \
+  native/java_lang_reflect_Constructor.cc \
+  native/java_lang_reflect_Field.cc \
+  native/java_lang_reflect_Method.cc \
+  native/java_lang_reflect_Proxy.cc \
+  native/java_util_concurrent_atomic_AtomicLong.cc \
+  native/org_apache_harmony_dalvik_ddmc_DdmServer.cc \
+  native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc \
+  native/sun_misc_Unsafe.cc \
+  oat.cc \
+  oat_file.cc \
+  object_lock.cc \
+  offsets.cc \
+  os_linux.cc \
+  parsed_options.cc \
+  primitive.cc \
+  quick_exception_handler.cc \
+  quick/inline_method_analyser.cc \
+  reference_table.cc \
+  reflection.cc \
+  runtime.cc \
+  signal_catcher.cc \
+  stack.cc \
+  thread.cc \
+  thread_list.cc \
+  thread_pool.cc \
+  throw_location.cc \
+  trace.cc \
+  transaction.cc \
+  profiler.cc \
+  fault_handler.cc \
+  utf.cc \
+  utils.cc \
+  verifier/dex_gc_map.cc \
+  verifier/instruction_flags.cc \
+  verifier/method_verifier.cc \
+  verifier/reg_type.cc \
+  verifier/reg_type_cache.cc \
+  verifier/register_line.cc \
+  well_known_classes.cc \
+  zip_archive.cc
 
 LIBART_COMMON_SRC_FILES += \
-	arch/context.cc \
-	arch/memcmp16.cc \
-	arch/arm/registers_arm.cc \
-	arch/arm64/registers_arm64.cc \
-	arch/x86/registers_x86.cc \
-	arch/mips/registers_mips.cc \
-	entrypoints/entrypoint_utils.cc \
-	entrypoints/interpreter/interpreter_entrypoints.cc \
-	entrypoints/jni/jni_entrypoints.cc \
-	entrypoints/math_entrypoints.cc \
-	entrypoints/portable/portable_alloc_entrypoints.cc \
-	entrypoints/portable/portable_cast_entrypoints.cc \
-	entrypoints/portable/portable_dexcache_entrypoints.cc \
-	entrypoints/portable/portable_field_entrypoints.cc \
-	entrypoints/portable/portable_fillarray_entrypoints.cc \
-	entrypoints/portable/portable_invoke_entrypoints.cc \
-	entrypoints/portable/portable_jni_entrypoints.cc \
-	entrypoints/portable/portable_lock_entrypoints.cc \
-	entrypoints/portable/portable_thread_entrypoints.cc \
-	entrypoints/portable/portable_throw_entrypoints.cc \
-	entrypoints/portable/portable_trampoline_entrypoints.cc \
-	entrypoints/quick/quick_alloc_entrypoints.cc \
-	entrypoints/quick/quick_cast_entrypoints.cc \
-	entrypoints/quick/quick_deoptimization_entrypoints.cc \
-	entrypoints/quick/quick_dexcache_entrypoints.cc \
-	entrypoints/quick/quick_field_entrypoints.cc \
-	entrypoints/quick/quick_fillarray_entrypoints.cc \
-	entrypoints/quick/quick_instrumentation_entrypoints.cc \
-	entrypoints/quick/quick_jni_entrypoints.cc \
-	entrypoints/quick/quick_lock_entrypoints.cc \
-	entrypoints/quick/quick_math_entrypoints.cc \
-	entrypoints/quick/quick_thread_entrypoints.cc \
-	entrypoints/quick/quick_throw_entrypoints.cc \
-	entrypoints/quick/quick_trampoline_entrypoints.cc
+  arch/context.cc \
+  arch/memcmp16.cc \
+  arch/arm/registers_arm.cc \
+  arch/arm64/registers_arm64.cc \
+  arch/x86/registers_x86.cc \
+  arch/mips/registers_mips.cc \
+  entrypoints/entrypoint_utils.cc \
+  entrypoints/interpreter/interpreter_entrypoints.cc \
+  entrypoints/jni/jni_entrypoints.cc \
+  entrypoints/math_entrypoints.cc \
+  entrypoints/portable/portable_alloc_entrypoints.cc \
+  entrypoints/portable/portable_cast_entrypoints.cc \
+  entrypoints/portable/portable_dexcache_entrypoints.cc \
+  entrypoints/portable/portable_field_entrypoints.cc \
+  entrypoints/portable/portable_fillarray_entrypoints.cc \
+  entrypoints/portable/portable_invoke_entrypoints.cc \
+  entrypoints/portable/portable_jni_entrypoints.cc \
+  entrypoints/portable/portable_lock_entrypoints.cc \
+  entrypoints/portable/portable_thread_entrypoints.cc \
+  entrypoints/portable/portable_throw_entrypoints.cc \
+  entrypoints/portable/portable_trampoline_entrypoints.cc \
+  entrypoints/quick/quick_alloc_entrypoints.cc \
+  entrypoints/quick/quick_cast_entrypoints.cc \
+  entrypoints/quick/quick_deoptimization_entrypoints.cc \
+  entrypoints/quick/quick_dexcache_entrypoints.cc \
+  entrypoints/quick/quick_field_entrypoints.cc \
+  entrypoints/quick/quick_fillarray_entrypoints.cc \
+  entrypoints/quick/quick_instrumentation_entrypoints.cc \
+  entrypoints/quick/quick_jni_entrypoints.cc \
+  entrypoints/quick/quick_lock_entrypoints.cc \
+  entrypoints/quick/quick_math_entrypoints.cc \
+  entrypoints/quick/quick_thread_entrypoints.cc \
+  entrypoints/quick/quick_throw_entrypoints.cc \
+  entrypoints/quick/quick_trampoline_entrypoints.cc
 
 # Source files that only compile with GCC.
 LIBART_GCC_ONLY_SRC_FILES := \
-	interpreter/interpreter_goto_table_impl.cc
+  interpreter/interpreter_goto_table_impl.cc
 
 LIBART_TARGET_LDFLAGS :=
 LIBART_HOST_LDFLAGS :=
 
 LIBART_TARGET_SRC_FILES := \
-	$(LIBART_COMMON_SRC_FILES) \
-	base/logging_android.cc \
-	jdwp/jdwp_adb.cc \
-	monitor_android.cc \
-	runtime_android.cc \
-	thread_android.cc
+  $(LIBART_COMMON_SRC_FILES) \
+  base/logging_android.cc \
+  jdwp/jdwp_adb.cc \
+  monitor_android.cc \
+  runtime_android.cc \
+  thread_android.cc
 
 LIBART_TARGET_SRC_FILES_arm := \
-	arch/arm/context_arm.cc.arm \
-	arch/arm/entrypoints_init_arm.cc \
-	arch/arm/jni_entrypoints_arm.S \
-	arch/arm/memcmp16_arm.S \
-	arch/arm/portable_entrypoints_arm.S \
-	arch/arm/quick_entrypoints_arm.S \
-	arch/arm/arm_sdiv.S \
-	arch/arm/thread_arm.cc \
-	arch/arm/fault_handler_arm.cc
+  arch/arm/context_arm.cc.arm \
+  arch/arm/entrypoints_init_arm.cc \
+  arch/arm/jni_entrypoints_arm.S \
+  arch/arm/memcmp16_arm.S \
+  arch/arm/portable_entrypoints_arm.S \
+  arch/arm/quick_entrypoints_arm.S \
+  arch/arm/arm_sdiv.S \
+  arch/arm/thread_arm.cc \
+  arch/arm/fault_handler_arm.cc
 
 LIBART_TARGET_SRC_FILES_arm64 := \
-	arch/arm64/context_arm64.cc \
-	arch/arm64/entrypoints_init_arm64.cc \
-	arch/arm64/jni_entrypoints_arm64.S \
-	arch/arm64/memcmp16_arm64.S \
-	arch/arm64/portable_entrypoints_arm64.S \
-	arch/arm64/quick_entrypoints_arm64.S \
-	arch/arm64/thread_arm64.cc \
-	monitor_pool.cc \
-	arch/arm64/fault_handler_arm64.cc
+  arch/arm64/context_arm64.cc \
+  arch/arm64/entrypoints_init_arm64.cc \
+  arch/arm64/jni_entrypoints_arm64.S \
+  arch/arm64/memcmp16_arm64.S \
+  arch/arm64/portable_entrypoints_arm64.S \
+  arch/arm64/quick_entrypoints_arm64.S \
+  arch/arm64/thread_arm64.cc \
+  monitor_pool.cc \
+  arch/arm64/fault_handler_arm64.cc
 
 LIBART_SRC_FILES_x86 := \
-	arch/x86/context_x86.cc \
-	arch/x86/entrypoints_init_x86.cc \
-	arch/x86/jni_entrypoints_x86.S \
-	arch/x86/portable_entrypoints_x86.S \
-	arch/x86/quick_entrypoints_x86.S \
-	arch/x86/thread_x86.cc \
-	arch/x86/fault_handler_x86.cc
+  arch/x86/context_x86.cc \
+  arch/x86/entrypoints_init_x86.cc \
+  arch/x86/jni_entrypoints_x86.S \
+  arch/x86/portable_entrypoints_x86.S \
+  arch/x86/quick_entrypoints_x86.S \
+  arch/x86/thread_x86.cc \
+  arch/x86/fault_handler_x86.cc
 
 LIBART_TARGET_SRC_FILES_x86 := \
-	$(LIBART_SRC_FILES_x86)
+  $(LIBART_SRC_FILES_x86)
 
 LIBART_SRC_FILES_x86_64 := \
-	arch/x86_64/context_x86_64.cc \
-	arch/x86_64/entrypoints_init_x86_64.cc \
-	arch/x86_64/jni_entrypoints_x86_64.S \
-	arch/x86_64/portable_entrypoints_x86_64.S \
-	arch/x86_64/quick_entrypoints_x86_64.S \
-	arch/x86_64/thread_x86_64.cc \
-	monitor_pool.cc \
-	arch/x86_64/fault_handler_x86_64.cc
+  arch/x86_64/context_x86_64.cc \
+  arch/x86_64/entrypoints_init_x86_64.cc \
+  arch/x86_64/jni_entrypoints_x86_64.S \
+  arch/x86_64/portable_entrypoints_x86_64.S \
+  arch/x86_64/quick_entrypoints_x86_64.S \
+  arch/x86_64/thread_x86_64.cc \
+  monitor_pool.cc \
+  arch/x86_64/fault_handler_x86_64.cc
 
 LIBART_TARGET_SRC_FILES_x86_64 := \
-	$(LIBART_SRC_FILES_x86_64) \
+  $(LIBART_SRC_FILES_x86_64) \
 
 LIBART_TARGET_SRC_FILES_mips := \
-	arch/mips/context_mips.cc \
-	arch/mips/entrypoints_init_mips.cc \
-	arch/mips/jni_entrypoints_mips.S \
-	arch/mips/memcmp16_mips.S \
-	arch/mips/portable_entrypoints_mips.S \
-	arch/mips/quick_entrypoints_mips.S \
-	arch/mips/thread_mips.cc \
-	arch/mips/fault_handler_mips.cc
+  arch/mips/context_mips.cc \
+  arch/mips/entrypoints_init_mips.cc \
+  arch/mips/jni_entrypoints_mips.S \
+  arch/mips/memcmp16_mips.S \
+  arch/mips/portable_entrypoints_mips.S \
+  arch/mips/quick_entrypoints_mips.S \
+  arch/mips/thread_mips.cc \
+  arch/mips/fault_handler_mips.cc
 
 ifeq ($(TARGET_ARCH),mips64)
 $(info TODOMips64: $(LOCAL_PATH)/Android.mk Add mips64 specific runtime files)
 endif # TARGET_ARCH != mips64
 
 LIBART_HOST_SRC_FILES := \
-	$(LIBART_COMMON_SRC_FILES) \
-	base/logging_linux.cc \
-	monitor_linux.cc \
-	runtime_linux.cc \
-	thread_linux.cc
+  $(LIBART_COMMON_SRC_FILES) \
+  base/logging_linux.cc \
+  monitor_linux.cc \
+  runtime_linux.cc \
+  thread_linux.cc
 
 LIBART_HOST_SRC_FILES_32 := \
-	$(LIBART_SRC_FILES_x86)
+  $(LIBART_SRC_FILES_x86)
 
 LIBART_HOST_SRC_FILES_64 := \
-	$(LIBART_SRC_FILES_x86_64)
+  $(LIBART_SRC_FILES_x86_64)
 
 LIBART_ENUM_OPERATOR_OUT_HEADER_FILES := \
-	arch/x86_64/registers_x86_64.h \
-	base/mutex.h \
-	dex_file.h \
-	dex_instruction.h \
-	gc/collector/gc_type.h \
-	gc/space/space.h \
-	gc/heap.h \
-	indirect_reference_table.h \
-	instruction_set.h \
-	invoke_type.h \
-	jdwp/jdwp.h \
-	jdwp/jdwp_constants.h \
-	lock_word.h \
-	mirror/class.h \
-	oat.h \
-	object_callbacks.h \
-	quick/inline_method_analyser.h \
-	thread.h \
-	thread_state.h \
-	verifier/method_verifier.h
+  arch/x86_64/registers_x86_64.h \
+  base/mutex.h \
+  dex_file.h \
+  dex_instruction.h \
+  gc/collector/gc_type.h \
+  gc/space/space.h \
+  gc/heap.h \
+  indirect_reference_table.h \
+  instruction_set.h \
+  invoke_type.h \
+  jdwp/jdwp.h \
+  jdwp/jdwp_constants.h \
+  lock_word.h \
+  mirror/class.h \
+  oat.h \
+  object_callbacks.h \
+  quick/inline_method_analyser.h \
+  thread.h \
+  thread_state.h \
+  verifier/method_verifier.h
 
 LIBART_CFLAGS :=
 ifeq ($(ART_USE_PORTABLE_COMPILER),true)
diff --git a/runtime/arch/arm/entrypoints_init_arm.cc b/runtime/arch/arm/entrypoints_init_arm.cc
index cf68c65..8c6afd6 100644
--- a/runtime/arch/arm/entrypoints_init_arm.cc
+++ b/runtime/arch/arm/entrypoints_init_arm.cc
@@ -26,11 +26,11 @@
 
 // Interpreter entrypoints.
 extern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper& mh,
-                                                 const DexFile::CodeItem* code_item,
-                                                 ShadowFrame* shadow_frame, JValue* result);
+                                                  const DexFile::CodeItem* code_item,
+                                                  ShadowFrame* shadow_frame, JValue* result);
 extern "C" void artInterpreterToCompiledCodeBridge(Thread* self, MethodHelper& mh,
-                                           const DexFile::CodeItem* code_item,
-                                           ShadowFrame* shadow_frame, JValue* result);
+                                                   const DexFile::CodeItem* code_item,
+                                                   ShadowFrame* shadow_frame, JValue* result);
 
 // Portable entrypoints.
 extern "C" void art_portable_resolution_trampoline(mirror::ArtMethod*);
diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc
index ce8faea..25f9a5a 100644
--- a/runtime/arch/stub_test.cc
+++ b/runtime/arch/stub_test.cc
@@ -14,13 +14,14 @@
  * limitations under the License.
  */
 
+#include <cstdio>
+
 #include "common_runtime_test.h"
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/string-inl.h"
-
-#include <cstdio>
+#include "scoped_thread_state_change.h"
 
 namespace art {
 
@@ -45,7 +46,7 @@
     }
   }
 
-  void SetUpRuntimeOptions(Runtime::Options *options) OVERRIDE {
+  void SetUpRuntimeOptions(RuntimeOptions *options) OVERRIDE {
     // Use a smaller heap
     for (std::pair<std::string, const void*>& pair : *options) {
       if (pair.first.find("-Xmx") == 0) {
diff --git a/runtime/barrier_test.cc b/runtime/barrier_test.cc
index 086ef44..de348dc 100644
--- a/runtime/barrier_test.cc
+++ b/runtime/barrier_test.cc
@@ -22,6 +22,7 @@
 #include "common_runtime_test.h"
 #include "mirror/object_array-inl.h"
 #include "thread_pool.h"
+#include "thread-inl.h"
 
 namespace art {
 class CheckWaitTask : public Task {
diff --git a/runtime/base/mutex_test.cc b/runtime/base/mutex_test.cc
index ee0b1be..289d3ef 100644
--- a/runtime/base/mutex_test.cc
+++ b/runtime/base/mutex_test.cc
@@ -17,6 +17,7 @@
 #include "mutex.h"
 
 #include "common_runtime_test.h"
+#include "thread-inl.h"
 
 namespace art {
 
diff --git a/runtime/base/scoped_flock_test.cc b/runtime/base/scoped_flock_test.cc
index 8fa181a..1fa7a12 100644
--- a/runtime/base/scoped_flock_test.cc
+++ b/runtime/base/scoped_flock_test.cc
@@ -15,9 +15,8 @@
  */
 
 #include "scoped_flock.h"
-#include "common_runtime_test.h"
 
-#include "gtest/gtest.h"
+#include "common_runtime_test.h"
 
 namespace art {
 
diff --git a/runtime/check_jni.cc b/runtime/check_jni.cc
index b70041c..a530594 100644
--- a/runtime/check_jni.cc
+++ b/runtime/check_jni.cc
@@ -23,6 +23,7 @@
 #include "class_linker.h"
 #include "class_linker-inl.h"
 #include "dex_file-inl.h"
+#include "field_helper.h"
 #include "gc/space/space.h"
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method-inl.h"
@@ -31,7 +32,6 @@
 #include "mirror/object_array-inl.h"
 #include "mirror/string-inl.h"
 #include "mirror/throwable.h"
-#include "object_utils.h"
 #include "runtime.h"
 #include "scoped_thread_state_change.h"
 #include "thread.h"
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index a40a2e4..25eb3a3 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -24,7 +24,6 @@
 #include "mirror/dex_cache-inl.h"
 #include "mirror/iftable.h"
 #include "mirror/object_array.h"
-#include "object_utils.h"
 #include "handle_scope-inl.h"
 
 namespace art {
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 1436810..2c11f8b 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -42,8 +42,10 @@
 #include "intern_table.h"
 #include "interpreter/interpreter.h"
 #include "leb128.h"
+#include "method_helper.h"
 #include "oat.h"
 #include "oat_file.h"
+#include "object_lock.h"
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class.h"
@@ -54,9 +56,9 @@
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/proxy.h"
+#include "mirror/reference-inl.h"
 #include "mirror/stack_trace_element.h"
 #include "mirror/string-inl.h"
-#include "object_utils.h"
 #include "os.h"
 #include "runtime.h"
 #include "entrypoints/entrypoint_utils.h"
@@ -257,6 +259,13 @@
   java_lang_String->SetObjectSize(mirror::String::InstanceSize());
   java_lang_String->SetStatus(mirror::Class::kStatusResolved, self);
 
+  // Setup Reference.
+  Handle<mirror::Class> java_lang_ref_Reference(hs.NewHandle(
+      AllocClass(self, java_lang_Class.Get(), mirror::Reference::ClassSize())));
+  mirror::Reference::SetClass(java_lang_ref_Reference.Get());
+  java_lang_ref_Reference->SetObjectSize(mirror::Reference::InstanceSize());
+  java_lang_ref_Reference->SetStatus(mirror::Class::kStatusResolved, self);
+
   // Create storage for root classes, save away our work so far (requires descriptors).
   class_roots_ = mirror::ObjectArray<mirror::Class>::Alloc(self, object_array_class.Get(),
                                                            kClassRootsMax);
@@ -267,6 +276,7 @@
   SetClassRoot(kObjectArrayClass, object_array_class.Get());
   SetClassRoot(kCharArrayClass, char_array_class.Get());
   SetClassRoot(kJavaLangString, java_lang_String.Get());
+  SetClassRoot(kJavaLangRefReference, java_lang_ref_Reference.Get());
 
   // Setup the primitive type classes.
   SetClassRoot(kPrimitiveBoolean, CreatePrimitiveClass(self, Primitive::kPrimBoolean));
@@ -461,8 +471,12 @@
   SetClassRoot(kJavaLangReflectProxy, java_lang_reflect_Proxy);
 
   // java.lang.ref classes need to be specially flagged, but otherwise are normal classes
-  mirror::Class* java_lang_ref_Reference = FindSystemClass(self, "Ljava/lang/ref/Reference;");
-  SetClassRoot(kJavaLangRefReference, java_lang_ref_Reference);
+  // finish initializing Reference class
+  java_lang_ref_Reference->SetStatus(mirror::Class::kStatusNotReady, self);
+  mirror::Class* Reference_class = FindSystemClass(self, "Ljava/lang/ref/Reference;");
+  CHECK_EQ(java_lang_ref_Reference.Get(), Reference_class);
+  CHECK_EQ(java_lang_ref_Reference->GetObjectSize(), mirror::Reference::InstanceSize());
+  CHECK_EQ(java_lang_ref_Reference->GetClassSize(), mirror::Reference::ClassSize());
   mirror::Class* java_lang_ref_FinalizerReference =
       FindSystemClass(self, "Ljava/lang/ref/FinalizerReference;");
   java_lang_ref_FinalizerReference->SetAccessFlags(
@@ -811,9 +825,20 @@
       }
     } else {
       // TODO: What to lock here?
+      bool obsolete_file_cleanup_failed;
       open_oat_file.reset(FindOatFileContainingDexFileFromDexLocation(dex_location,
                                                                       dex_location_checksum_pointer,
-                                                                      kRuntimeISA, error_msgs));
+                                                                      kRuntimeISA, error_msgs,
+                                                                      &obsolete_file_cleanup_failed));
+      // There's no point in going forward and eventually try to regenerate the
+      // file if we couldn't remove the obsolete one. Mostly likely we will fail
+      // with the same error when trying to write the new file.
+      // In case the clean up failure is due to permission issues it's *mandatory*
+      // to stop to avoid regenerating under the wrong user.
+      // TODO: should we maybe do this only when we get permission issues? (i.e. EACCESS).
+      if (obsolete_file_cleanup_failed) {
+        return false;
+      }
     }
     needs_registering = true;
   }
@@ -1071,7 +1096,9 @@
     const char* dex_location,
     const uint32_t* const dex_location_checksum,
     InstructionSet isa,
-    std::vector<std::string>* error_msgs) {
+    std::vector<std::string>* error_msgs,
+    bool* obsolete_file_cleanup_failed) {
+  *obsolete_file_cleanup_failed = false;
   // Look for an existing file next to dex. for example, for
   // /foo/bar/baz.jar, look for /foo/bar/<isa>/baz.odex.
   std::string odex_filename(DexFilenameToOdexFilename(dex_location, isa));
@@ -1098,9 +1125,18 @@
   if (oat_file != nullptr) {
     return oat_file;
   }
+
   if (!open_failed && TEMP_FAILURE_RETRY(unlink(cache_location.c_str())) != 0) {
-    PLOG(FATAL) << "Failed to remove obsolete oat file from " << cache_location;
+    std::string error_msg = StringPrintf("Failed to remove obsolete file from %s when searching"
+                                         "for dex file %s: %s",
+                                         cache_location.c_str(), dex_location, strerror(errno));
+    error_msgs->push_back(error_msg);
+    VLOG(class_linker) << error_msg;
+    // Let the caller know that we couldn't remove the obsolete file.
+    // This is a good indication that further writes may fail as well.
+    *obsolete_file_cleanup_failed = true;
   }
+
   std::string compound_msg = StringPrintf("Failed to open oat file from %s (error '%s') or %s "
                                           "(error '%s').", odex_filename.c_str(), error_msg.c_str(),
                                           cache_location.c_str(), cache_error_msg.c_str());
@@ -1231,6 +1267,7 @@
   array_iftable_ = GetClassRoot(kObjectArrayClass)->GetIfTable();
   DCHECK(array_iftable_ == GetClassRoot(kBooleanArrayClass)->GetIfTable());
   // String class root was set above
+  mirror::Reference::SetClass(GetClassRoot(kJavaLangRefReference));
   mirror::ArtField::SetClass(GetClassRoot(kJavaLangReflectArtField));
   mirror::BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
   mirror::ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
@@ -1354,6 +1391,7 @@
 ClassLinker::~ClassLinker() {
   mirror::Class::ResetClass();
   mirror::String::ResetClass();
+  mirror::Reference::ResetClass();
   mirror::ArtField::ResetClass();
   mirror::ArtMethod::ResetClass();
   mirror::BooleanArray::ResetArrayClass();
@@ -1600,6 +1638,8 @@
       klass.Assign(GetClassRoot(kJavaLangClass));
     } else if (strcmp(descriptor, "Ljava/lang/String;") == 0) {
       klass.Assign(GetClassRoot(kJavaLangString));
+    } else if (strcmp(descriptor, "Ljava/lang/ref/Reference;") == 0) {
+      klass.Assign(GetClassRoot(kJavaLangRefReference));
     } else if (strcmp(descriptor, "Ljava/lang/DexCache;") == 0) {
       klass.Assign(GetClassRoot(kJavaLangDexCache));
     } else if (strcmp(descriptor, "Ljava/lang/reflect/ArtField;") == 0) {
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index d6cceff..c17f88d 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -571,7 +571,8 @@
   const OatFile* FindOatFileContainingDexFileFromDexLocation(const char* location,
                                                              const uint32_t* const location_checksum,
                                                              InstructionSet isa,
-                                                             std::vector<std::string>* error_msgs)
+                                                             std::vector<std::string>* error_msgs,
+                                                             bool* obsolete_file_cleanup_failed)
       LOCKS_EXCLUDED(dex_lock_, Locks::mutator_lock_);
 
   // Find a verify an oat file with the given dex file. Will return nullptr when the oat file
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 7b5a502..21fe006 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -23,6 +23,7 @@
 #include "common_runtime_test.h"
 #include "dex_file.h"
 #include "entrypoints/entrypoint_utils-inl.h"
+#include "field_helper.h"
 #include "gc/heap.h"
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method.h"
@@ -36,6 +37,8 @@
 #include "mirror/stack_trace_element.h"
 #include "mirror/string-inl.h"
 #include "handle_scope-inl.h"
+#include "scoped_thread_state_change.h"
+#include "thread-inl.h"
 
 namespace art {
 
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index 0ed8b63..f47f13d 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -14,8 +14,31 @@
  * limitations under the License.
  */
 
+#include "common_runtime_test.h"
+
+#include <dirent.h>
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <ScopedLocalRef.h>
+
+#include "../../external/icu/icu4c/source/common/unicode/uvernum.h"
 #include "base/logging.h"
+#include "base/stl_util.h"
+#include "base/stringprintf.h"
+#include "base/unix_file/fd_file.h"
+#include "class_linker.h"
+#include "compiler_callbacks.h"
+#include "dex_file.h"
+#include "gc/heap.h"
 #include "gtest/gtest.h"
+#include "jni_internal.h"
+#include "mirror/class_loader.h"
+#include "noop_compiler_callbacks.h"
+#include "os.h"
+#include "runtime-inl.h"
+#include "scoped_thread_state_change.h"
+#include "thread.h"
+#include "well_known_classes.h"
 
 int main(int argc, char **argv) {
   art::InitLogging(argv);
@@ -23,3 +46,293 @@
   testing::InitGoogleTest(&argc, argv);
   return RUN_ALL_TESTS();
 }
+
+namespace art {
+
+ScratchFile::ScratchFile() {
+  // ANDROID_DATA needs to be set
+  CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) <<
+      "Are you subclassing RuntimeTest?";
+  filename_ = getenv("ANDROID_DATA");
+  filename_ += "/TmpFile-XXXXXX";
+  int fd = mkstemp(&filename_[0]);
+  CHECK_NE(-1, fd);
+  file_.reset(new File(fd, GetFilename()));
+}
+
+ScratchFile::ScratchFile(const ScratchFile& other, const char* suffix) {
+  filename_ = other.GetFilename();
+  filename_ += suffix;
+  int fd = open(filename_.c_str(), O_RDWR | O_CREAT, 0666);
+  CHECK_NE(-1, fd);
+  file_.reset(new File(fd, GetFilename()));
+}
+
+ScratchFile::ScratchFile(File* file) {
+  CHECK(file != NULL);
+  filename_ = file->GetPath();
+  file_.reset(file);
+}
+
+ScratchFile::~ScratchFile() {
+  Unlink();
+}
+
+int ScratchFile::GetFd() const {
+  return file_->Fd();
+}
+
+void ScratchFile::Unlink() {
+  if (!OS::FileExists(filename_.c_str())) {
+    return;
+  }
+  int unlink_result = unlink(filename_.c_str());
+  CHECK_EQ(0, unlink_result);
+}
+
+CommonRuntimeTest::CommonRuntimeTest() {}
+CommonRuntimeTest::~CommonRuntimeTest() {}
+
+void CommonRuntimeTest::SetEnvironmentVariables(std::string& android_data) {
+  if (IsHost()) {
+    // $ANDROID_ROOT is set on the device, but not necessarily on the host.
+    // But it needs to be set so that icu4c can find its locale data.
+    const char* android_root_from_env = getenv("ANDROID_ROOT");
+    if (android_root_from_env == nullptr) {
+      // Use ANDROID_HOST_OUT for ANDROID_ROOT if it is set.
+      const char* android_host_out = getenv("ANDROID_HOST_OUT");
+      if (android_host_out != nullptr) {
+        setenv("ANDROID_ROOT", android_host_out, 1);
+      } else {
+        // Build it from ANDROID_BUILD_TOP or cwd
+        std::string root;
+        const char* android_build_top = getenv("ANDROID_BUILD_TOP");
+        if (android_build_top != nullptr) {
+          root += android_build_top;
+        } else {
+          // Not set by build server, so default to current directory
+          char* cwd = getcwd(nullptr, 0);
+          setenv("ANDROID_BUILD_TOP", cwd, 1);
+          root += cwd;
+          free(cwd);
+        }
+#if defined(__linux__)
+        root += "/out/host/linux-x86";
+#elif defined(__APPLE__)
+        root += "/out/host/darwin-x86";
+#else
+#error unsupported OS
+#endif
+        setenv("ANDROID_ROOT", root.c_str(), 1);
+      }
+    }
+    setenv("LD_LIBRARY_PATH", ":", 0);  // Required by java.lang.System.<clinit>.
+
+    // Not set by build server, so default
+    if (getenv("ANDROID_HOST_OUT") == nullptr) {
+      setenv("ANDROID_HOST_OUT", getenv("ANDROID_ROOT"), 1);
+    }
+  }
+
+  // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
+  android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/dalvik-cache/art-data-XXXXXX");
+  if (mkdtemp(&android_data[0]) == nullptr) {
+    PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
+  }
+  setenv("ANDROID_DATA", android_data.c_str(), 1);
+}
+
+const DexFile* CommonRuntimeTest::LoadExpectSingleDexFile(const char* location) {
+  std::vector<const DexFile*> dex_files;
+  std::string error_msg;
+  if (!DexFile::Open(location, location, &error_msg, &dex_files)) {
+    LOG(FATAL) << "Could not open .dex file '" << location << "': " << error_msg << "\n";
+    return nullptr;
+  } else {
+    CHECK_EQ(1U, dex_files.size()) << "Expected only one dex file in " << location;
+    return dex_files[0];
+  }
+}
+
+void CommonRuntimeTest::SetUp() {
+  SetEnvironmentVariables(android_data_);
+  dalvik_cache_.append(android_data_.c_str());
+  dalvik_cache_.append("/dalvik-cache");
+  int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
+  ASSERT_EQ(mkdir_result, 0);
+
+  std::string error_msg;
+  java_lang_dex_file_ = LoadExpectSingleDexFile(GetLibCoreDexFileName().c_str());
+  boot_class_path_.push_back(java_lang_dex_file_);
+
+  std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
+  std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
+
+  callbacks_.reset(new NoopCompilerCallbacks());
+
+  RuntimeOptions options;
+  options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
+  options.push_back(std::make_pair("-Xcheck:jni", nullptr));
+  options.push_back(std::make_pair(min_heap_string.c_str(), nullptr));
+  options.push_back(std::make_pair(max_heap_string.c_str(), nullptr));
+  options.push_back(std::make_pair("compilercallbacks", callbacks_.get()));
+  SetUpRuntimeOptions(&options);
+  if (!Runtime::Create(options, false)) {
+    LOG(FATAL) << "Failed to create runtime";
+    return;
+  }
+  runtime_.reset(Runtime::Current());
+  class_linker_ = runtime_->GetClassLinker();
+  class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
+  class_linker_->RunRootClinits();
+
+  // Runtime::Create acquired the mutator_lock_ that is normally given away when we
+  // Runtime::Start, give it away now and then switch to a more managable ScopedObjectAccess.
+  Thread::Current()->TransitionFromRunnableToSuspended(kNative);
+
+  // We're back in native, take the opportunity to initialize well known classes.
+  WellKnownClasses::Init(Thread::Current()->GetJniEnv());
+
+  // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
+  // pool is created by the runtime.
+  runtime_->GetHeap()->CreateThreadPool();
+  runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption before the test
+}
+
+void CommonRuntimeTest::TearDown() {
+  const char* android_data = getenv("ANDROID_DATA");
+  ASSERT_TRUE(android_data != nullptr);
+  DIR* dir = opendir(dalvik_cache_.c_str());
+  ASSERT_TRUE(dir != nullptr);
+  dirent* e;
+  while ((e = readdir(dir)) != nullptr) {
+    if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
+      continue;
+    }
+    std::string filename(dalvik_cache_);
+    filename.push_back('/');
+    filename.append(e->d_name);
+    int unlink_result = unlink(filename.c_str());
+    ASSERT_EQ(0, unlink_result);
+  }
+  closedir(dir);
+  int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
+  ASSERT_EQ(0, rmdir_cache_result);
+  int rmdir_data_result = rmdir(android_data_.c_str());
+  ASSERT_EQ(0, rmdir_data_result);
+
+  // icu4c has a fixed 10-element array "gCommonICUDataArray".
+  // If we run > 10 tests, we fill that array and u_setCommonData fails.
+  // There's a function to clear the array, but it's not public...
+  typedef void (*IcuCleanupFn)();
+  void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
+  CHECK(sym != nullptr) << dlerror();
+  IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
+  (*icu_cleanup_fn)();
+
+  STLDeleteElements(&opened_dex_files_);
+
+  Runtime::Current()->GetHeap()->VerifyHeap();  // Check for heap corruption after the test
+}
+
+std::string CommonRuntimeTest::GetLibCoreDexFileName() {
+  return GetDexFileName("core-libart");
+}
+
+std::string CommonRuntimeTest::GetDexFileName(const std::string& jar_prefix) {
+  if (IsHost()) {
+    const char* host_dir = getenv("ANDROID_HOST_OUT");
+    CHECK(host_dir != nullptr);
+    return StringPrintf("%s/framework/%s-hostdex.jar", host_dir, jar_prefix.c_str());
+  }
+  return StringPrintf("%s/framework/%s.jar", GetAndroidRoot(), jar_prefix.c_str());
+}
+
+std::string CommonRuntimeTest::GetTestAndroidRoot() {
+  if (IsHost()) {
+    const char* host_dir = getenv("ANDROID_HOST_OUT");
+    CHECK(host_dir != nullptr);
+    return host_dir;
+  }
+  return GetAndroidRoot();
+}
+
+std::vector<const DexFile*> CommonRuntimeTest::OpenTestDexFiles(const char* name) {
+  CHECK(name != nullptr);
+  std::string filename;
+  if (IsHost()) {
+    filename += getenv("ANDROID_HOST_OUT");
+    filename += "/framework/";
+  } else {
+    filename += "/data/nativetest/art/";
+  }
+  filename += "art-gtest-";
+  filename += name;
+  filename += ".jar";
+  std::string error_msg;
+  std::vector<const DexFile*> dex_files;
+  bool success = DexFile::Open(filename.c_str(), filename.c_str(), &error_msg, &dex_files);
+  CHECK(success) << "Failed to open '" << filename << "': " << error_msg;
+  for (const DexFile* dex_file : dex_files) {
+    CHECK_EQ(PROT_READ, dex_file->GetPermissions());
+    CHECK(dex_file->IsReadOnly());
+  }
+  opened_dex_files_.insert(opened_dex_files_.end(), dex_files.begin(), dex_files.end());
+  return dex_files;
+}
+
+const DexFile* CommonRuntimeTest::OpenTestDexFile(const char* name) {
+  std::vector<const DexFile*> vector = OpenTestDexFiles(name);
+  EXPECT_EQ(1U, vector.size());
+  return vector[0];
+}
+
+jobject CommonRuntimeTest::LoadDex(const char* dex_name) {
+  std::vector<const DexFile*> dex_files = OpenTestDexFiles(dex_name);
+  CHECK_NE(0U, dex_files.size());
+  for (const DexFile* dex_file : dex_files) {
+    class_linker_->RegisterDexFile(*dex_file);
+  }
+  ScopedObjectAccessUnchecked soa(Thread::Current());
+  ScopedLocalRef<jobject> class_loader_local(soa.Env(),
+      soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
+  jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
+  soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
+  Runtime::Current()->SetCompileTimeClassPath(class_loader, dex_files);
+  return class_loader;
+}
+
+CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
+  vm_->check_jni_abort_hook = Hook;
+  vm_->check_jni_abort_hook_data = &actual_;
+}
+
+CheckJniAbortCatcher::~CheckJniAbortCatcher() {
+  vm_->check_jni_abort_hook = nullptr;
+  vm_->check_jni_abort_hook_data = nullptr;
+  EXPECT_TRUE(actual_.empty()) << actual_;
+}
+
+void CheckJniAbortCatcher::Check(const char* expected_text) {
+  EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
+      << "Expected to find: " << expected_text << "\n"
+      << "In the output   : " << actual_;
+  actual_.clear();
+}
+
+void CheckJniAbortCatcher::Hook(void* data, const std::string& reason) {
+  // We use += because when we're hooking the aborts like this, multiple problems can be found.
+  *reinterpret_cast<std::string*>(data) += reason;
+}
+
+}  // namespace art
+
+namespace std {
+
+template <typename T>
+std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
+os << ::art::ToString(rhs);
+return os;
+}
+
+}  // namespace std
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index ac6d44b..d045031 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -17,73 +17,33 @@
 #ifndef ART_RUNTIME_COMMON_RUNTIME_TEST_H_
 #define ART_RUNTIME_COMMON_RUNTIME_TEST_H_
 
-#include <dirent.h>
-#include <dlfcn.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fstream>
-#include <memory>
+#include <gtest/gtest.h>
+#include <jni.h>
 
-#include "../../external/icu/icu4c/source/common/unicode/uvernum.h"
-#include "base/macros.h"
-#include "base/stl_util.h"
-#include "base/stringprintf.h"
-#include "base/unix_file/fd_file.h"
-#include "class_linker.h"
-#include "dex_file-inl.h"
-#include "entrypoints/entrypoint_utils.h"
-#include "gc/heap.h"
-#include "gtest/gtest.h"
-#include "instruction_set.h"
-#include "interpreter/interpreter.h"
-#include "mirror/class_loader.h"
-#include "noop_compiler_callbacks.h"
-#include "oat_file.h"
-#include "object_utils.h"
+#include <string>
+
+#include "base/mutex.h"
+#include "globals.h"
 #include "os.h"
-#include "runtime.h"
-#include "scoped_thread_state_change.h"
-#include "ScopedLocalRef.h"
-#include "thread.h"
-#include "utils.h"
-#include "verifier/method_verifier.h"
-#include "verifier/method_verifier-inl.h"
-#include "well_known_classes.h"
 
 namespace art {
 
+class ClassLinker;
+class CompilerCallbacks;
+class DexFile;
+class JavaVMExt;
+class Runtime;
+typedef std::vector<std::pair<std::string, const void*>> RuntimeOptions;
+
 class ScratchFile {
  public:
-  ScratchFile() {
-    // ANDROID_DATA needs to be set
-    CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) <<
-        "Are you subclassing RuntimeTest?";
-    filename_ = getenv("ANDROID_DATA");
-    filename_ += "/TmpFile-XXXXXX";
-    int fd = mkstemp(&filename_[0]);
-    CHECK_NE(-1, fd);
-    file_.reset(new File(fd, GetFilename()));
-  }
+  ScratchFile();
 
-  ScratchFile(const ScratchFile& other, const char* suffix) {
-    filename_ = other.GetFilename();
-    filename_ += suffix;
-    int fd = open(filename_.c_str(), O_RDWR | O_CREAT, 0666);
-    CHECK_NE(-1, fd);
-    file_.reset(new File(fd, GetFilename()));
-  }
+  ScratchFile(const ScratchFile& other, const char* suffix);
 
-  explicit ScratchFile(File* file) {
-    CHECK(file != NULL);
-    filename_ = file->GetPath();
-    file_.reset(file);
-  }
+  explicit ScratchFile(File* file);
 
-  ~ScratchFile() {
-    Unlink();
-  }
+  ~ScratchFile();
 
   const std::string& GetFilename() const {
     return filename_;
@@ -93,17 +53,9 @@
     return file_.get();
   }
 
-  int GetFd() const {
-    return file_->Fd();
-  }
+  int GetFd() const;
 
-  void Unlink() {
-    if (!OS::FileExists(filename_.c_str())) {
-      return;
-    }
-    int unlink_result = unlink(filename_.c_str());
-    CHECK_EQ(0, unlink_result);
-  }
+  void Unlink();
 
  private:
   std::string filename_;
@@ -112,222 +64,37 @@
 
 class CommonRuntimeTest : public testing::Test {
  public:
-  static void SetEnvironmentVariables(std::string& android_data) {
-    if (IsHost()) {
-      // $ANDROID_ROOT is set on the device, but not necessarily on the host.
-      // But it needs to be set so that icu4c can find its locale data.
-      const char* android_root_from_env = getenv("ANDROID_ROOT");
-      if (android_root_from_env == nullptr) {
-        // Use ANDROID_HOST_OUT for ANDROID_ROOT if it is set.
-        const char* android_host_out = getenv("ANDROID_HOST_OUT");
-        if (android_host_out != nullptr) {
-          setenv("ANDROID_ROOT", android_host_out, 1);
-        } else {
-          // Build it from ANDROID_BUILD_TOP or cwd
-          std::string root;
-          const char* android_build_top = getenv("ANDROID_BUILD_TOP");
-          if (android_build_top != nullptr) {
-            root += android_build_top;
-          } else {
-            // Not set by build server, so default to current directory
-            char* cwd = getcwd(nullptr, 0);
-            setenv("ANDROID_BUILD_TOP", cwd, 1);
-            root += cwd;
-            free(cwd);
-          }
-#if defined(__linux__)
-          root += "/out/host/linux-x86";
-#elif defined(__APPLE__)
-          root += "/out/host/darwin-x86";
-#else
-#error unsupported OS
-#endif
-          setenv("ANDROID_ROOT", root.c_str(), 1);
-        }
-      }
-      setenv("LD_LIBRARY_PATH", ":", 0);  // Required by java.lang.System.<clinit>.
+  static void SetEnvironmentVariables(std::string& android_data);
 
-      // Not set by build server, so default
-      if (getenv("ANDROID_HOST_OUT") == nullptr) {
-        setenv("ANDROID_HOST_OUT", getenv("ANDROID_ROOT"), 1);
-      }
-    }
-
-    // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
-    android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/dalvik-cache/art-data-XXXXXX");
-    if (mkdtemp(&android_data[0]) == nullptr) {
-      PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
-    }
-    setenv("ANDROID_DATA", android_data.c_str(), 1);
-  }
+  CommonRuntimeTest();
+  ~CommonRuntimeTest();
 
  protected:
   static bool IsHost() {
     return !kIsTargetBuild;
   }
 
-  const DexFile* LoadExpectSingleDexFile(const char* location) {
-    std::vector<const DexFile*> dex_files;
-    std::string error_msg;
-    if (!DexFile::Open(location, location, &error_msg, &dex_files)) {
-      LOG(FATAL) << "Could not open .dex file '" << location << "': " << error_msg << "\n";
-      return nullptr;
-    } else {
-      CHECK_EQ(1U, dex_files.size()) << "Expected only one dex file in " << location;
-      return dex_files[0];
-    }
-  }
+  const DexFile* LoadExpectSingleDexFile(const char* location);
 
-  virtual void SetUp() {
-    SetEnvironmentVariables(android_data_);
-    dalvik_cache_.append(android_data_.c_str());
-    dalvik_cache_.append("/dalvik-cache");
-    int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
-    ASSERT_EQ(mkdir_result, 0);
-
-    std::string error_msg;
-    java_lang_dex_file_ = LoadExpectSingleDexFile(GetLibCoreDexFileName().c_str());
-    boot_class_path_.push_back(java_lang_dex_file_);
-
-    std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
-    std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
-
-    Runtime::Options options;
-    options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
-    options.push_back(std::make_pair("-Xcheck:jni", nullptr));
-    options.push_back(std::make_pair(min_heap_string.c_str(), nullptr));
-    options.push_back(std::make_pair(max_heap_string.c_str(), nullptr));
-    options.push_back(std::make_pair("compilercallbacks", &callbacks_));
-    SetUpRuntimeOptions(&options);
-    if (!Runtime::Create(options, false)) {
-      LOG(FATAL) << "Failed to create runtime";
-      return;
-    }
-    runtime_.reset(Runtime::Current());
-    class_linker_ = runtime_->GetClassLinker();
-    class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
-    class_linker_->RunRootClinits();
-
-    // Runtime::Create acquired the mutator_lock_ that is normally given away when we
-    // Runtime::Start, give it away now and then switch to a more managable ScopedObjectAccess.
-    Thread::Current()->TransitionFromRunnableToSuspended(kNative);
-
-    // We're back in native, take the opportunity to initialize well known classes.
-    WellKnownClasses::Init(Thread::Current()->GetJniEnv());
-
-    // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
-    // pool is created by the runtime.
-    runtime_->GetHeap()->CreateThreadPool();
-    runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption before the test
-  }
+  virtual void SetUp();
 
   // Allow subclases such as CommonCompilerTest to add extra options.
-  virtual void SetUpRuntimeOptions(Runtime::Options *options) {}
+  virtual void SetUpRuntimeOptions(RuntimeOptions* options) {}
 
-  virtual void TearDown() {
-    const char* android_data = getenv("ANDROID_DATA");
-    ASSERT_TRUE(android_data != nullptr);
-    DIR* dir = opendir(dalvik_cache_.c_str());
-    ASSERT_TRUE(dir != nullptr);
-    dirent* e;
-    while ((e = readdir(dir)) != nullptr) {
-      if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
-        continue;
-      }
-      std::string filename(dalvik_cache_);
-      filename.push_back('/');
-      filename.append(e->d_name);
-      int unlink_result = unlink(filename.c_str());
-      ASSERT_EQ(0, unlink_result);
-    }
-    closedir(dir);
-    int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
-    ASSERT_EQ(0, rmdir_cache_result);
-    int rmdir_data_result = rmdir(android_data_.c_str());
-    ASSERT_EQ(0, rmdir_data_result);
+  virtual void TearDown();
 
-    // icu4c has a fixed 10-element array "gCommonICUDataArray".
-    // If we run > 10 tests, we fill that array and u_setCommonData fails.
-    // There's a function to clear the array, but it's not public...
-    typedef void (*IcuCleanupFn)();
-    void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
-    CHECK(sym != nullptr) << dlerror();
-    IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
-    (*icu_cleanup_fn)();
+  std::string GetLibCoreDexFileName();
 
-    STLDeleteElements(&opened_dex_files_);
+  std::string GetDexFileName(const std::string& jar_prefix);
 
-    Runtime::Current()->GetHeap()->VerifyHeap();  // Check for heap corruption after the test
-  }
-
-  std::string GetLibCoreDexFileName() {
-    return GetDexFileName("core-libart");
-  }
-
-  std::string GetDexFileName(const std::string& jar_prefix) {
-    if (IsHost()) {
-      const char* host_dir = getenv("ANDROID_HOST_OUT");
-      CHECK(host_dir != nullptr);
-      return StringPrintf("%s/framework/%s-hostdex.jar", host_dir, jar_prefix.c_str());
-    }
-    return StringPrintf("%s/framework/%s.jar", GetAndroidRoot(), jar_prefix.c_str());
-  }
-
-  std::string GetTestAndroidRoot() {
-    if (IsHost()) {
-      const char* host_dir = getenv("ANDROID_HOST_OUT");
-      CHECK(host_dir != nullptr);
-      return host_dir;
-    }
-    return GetAndroidRoot();
-  }
+  std::string GetTestAndroidRoot();
 
   std::vector<const DexFile*> OpenTestDexFiles(const char* name)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    CHECK(name != nullptr);
-    std::string filename;
-    if (IsHost()) {
-      filename += getenv("ANDROID_HOST_OUT");
-      filename += "/framework/";
-    } else {
-      filename += "/data/nativetest/art/";
-    }
-    filename += "art-gtest-";
-    filename += name;
-    filename += ".jar";
-    std::string error_msg;
-    std::vector<const DexFile*> dex_files;
-    bool success = DexFile::Open(filename.c_str(), filename.c_str(), &error_msg, &dex_files);
-    CHECK(success) << "Failed to open '" << filename << "': " << error_msg;
-    for (const DexFile* dex_file : dex_files) {
-      CHECK_EQ(PROT_READ, dex_file->GetPermissions());
-      CHECK(dex_file->IsReadOnly());
-    }
-    opened_dex_files_.insert(opened_dex_files_.end(), dex_files.begin(), dex_files.end());
-    return dex_files;
-  }
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  const DexFile* OpenTestDexFile(const char* name)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    std::vector<const DexFile*> vector = OpenTestDexFiles(name);
-    EXPECT_EQ(1U, vector.size());
-    return vector[0];
-  }
+  const DexFile* OpenTestDexFile(const char* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  jobject LoadDex(const char* dex_name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    std::vector<const DexFile*> dex_files = OpenTestDexFiles(dex_name);
-    CHECK_NE(0U, dex_files.size());
-    for (const DexFile* dex_file : dex_files) {
-      class_linker_->RegisterDexFile(*dex_file);
-    }
-    ScopedObjectAccessUnchecked soa(Thread::Current());
-    ScopedLocalRef<jobject> class_loader_local(soa.Env(),
-        soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
-    jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
-    soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
-    Runtime::Current()->SetCompileTimeClassPath(class_loader, dex_files);
-    return class_loader;
-  }
+  jobject LoadDex(const char* dex_name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   std::string android_data_;
   std::string dalvik_cache_;
@@ -338,7 +105,7 @@
   ClassLinker* class_linker_;
 
  private:
-  NoopCompilerCallbacks callbacks_;
+  std::unique_ptr<CompilerCallbacks> callbacks_;
   std::vector<const DexFile*> opened_dex_files_;
 };
 
@@ -346,29 +113,14 @@
 // rather than aborting, so be careful!
 class CheckJniAbortCatcher {
  public:
-  CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
-    vm_->check_jni_abort_hook = Hook;
-    vm_->check_jni_abort_hook_data = &actual_;
-  }
+  CheckJniAbortCatcher();
 
-  ~CheckJniAbortCatcher() {
-    vm_->check_jni_abort_hook = nullptr;
-    vm_->check_jni_abort_hook_data = nullptr;
-    EXPECT_TRUE(actual_.empty()) << actual_;
-  }
+  ~CheckJniAbortCatcher();
 
-  void Check(const char* expected_text) {
-    EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
-        << "Expected to find: " << expected_text << "\n"
-        << "In the output   : " << actual_;
-    actual_.clear();
-  }
+  void Check(const char* expected_text);
 
  private:
-  static void Hook(void* data, const std::string& reason) {
-    // We use += because when we're hooking the aborts like this, multiple problems can be found.
-    *reinterpret_cast<std::string*>(data) += reason;
-  }
+  static void Hook(void* data, const std::string& reason);
 
   JavaVMExt* vm_;
   std::string actual_;
@@ -399,10 +151,7 @@
 
 // TODO: isn't gtest supposed to be able to print STL types for itself?
 template <typename T>
-std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
-  os << ::art::ToString(rhs);
-  return os;
-}
+std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs);
 
 }  // namespace std
 
diff --git a/runtime/common_throws.cc b/runtime/common_throws.cc
index 8de3068..970593d 100644
--- a/runtime/common_throws.cc
+++ b/runtime/common_throws.cc
@@ -16,6 +16,8 @@
 
 #include "common_throws.h"
 
+#include <sstream>
+
 #include "base/logging.h"
 #include "class_linker-inl.h"
 #include "dex_file-inl.h"
@@ -25,12 +27,9 @@
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
-#include "object_utils.h"
 #include "thread.h"
 #include "verifier/method_verifier.h"
 
-#include <sstream>
-
 namespace art {
 
 static void AddReferrerLocation(std::ostream& os, mirror::Class* referrer)
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index c95be01..4cf4c09 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -25,11 +25,13 @@
 #include "class_linker-inl.h"
 #include "dex_file-inl.h"
 #include "dex_instruction.h"
+#include "field_helper.h"
 #include "gc/accounting/card_table-inl.h"
 #include "gc/space/large_object_space.h"
 #include "gc/space/space-inl.h"
 #include "handle_scope.h"
 #include "jdwp/object_registry.h"
+#include "method_helper.h"
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class.h"
@@ -39,7 +41,6 @@
 #include "mirror/object_array-inl.h"
 #include "mirror/string-inl.h"
 #include "mirror/throwable.h"
-#include "object_utils.h"
 #include "quick/inline_method_analyser.h"
 #include "reflection.h"
 #include "safe_map.h"
diff --git a/runtime/dex_file_test.cc b/runtime/dex_file_test.cc
index c1e00fc..284aa89 100644
--- a/runtime/dex_file_test.cc
+++ b/runtime/dex_file_test.cc
@@ -18,7 +18,12 @@
 
 #include <memory>
 
+#include "base/stl_util.h"
+#include "base/unix_file/fd_file.h"
 #include "common_runtime_test.h"
+#include "os.h"
+#include "scoped_thread_state_change.h"
+#include "thread-inl.h"
 
 namespace art {
 
diff --git a/runtime/dex_file_verifier_test.cc b/runtime/dex_file_verifier_test.cc
index 93faeae..d475d42 100644
--- a/runtime/dex_file_verifier_test.cc
+++ b/runtime/dex_file_verifier_test.cc
@@ -16,11 +16,15 @@
 
 #include "dex_file_verifier.h"
 
-#include <memory>
+#include "sys/mman.h"
 #include "zlib.h"
+#include <memory>
 
-#include "common_runtime_test.h"
+#include "base/unix_file/fd_file.h"
 #include "base/macros.h"
+#include "common_runtime_test.h"
+#include "scoped_thread_state_change.h"
+#include "thread-inl.h"
 
 namespace art {
 
diff --git a/runtime/dex_method_iterator_test.cc b/runtime/dex_method_iterator_test.cc
index 0d00cc3..b8f180b 100644
--- a/runtime/dex_method_iterator_test.cc
+++ b/runtime/dex_method_iterator_test.cc
@@ -16,7 +16,10 @@
 
 #include "dex_method_iterator.h"
 
+#include "base/stl_util.h"
 #include "common_runtime_test.h"
+#include "scoped_thread_state_change.h"
+#include "thread-inl.h"
 
 namespace art {
 
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 482ad47..90c8fcf 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -30,7 +30,6 @@
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
 #include "mirror/throwable.h"
-#include "object_utils.h"
 #include "handle_scope-inl.h"
 #include "thread.h"
 
@@ -38,10 +37,9 @@
 
 // TODO: Fix no thread safety analysis when GCC can handle template specialization.
 template <const bool kAccessCheck>
-ALWAYS_INLINE static inline mirror::Class* CheckObjectAlloc(uint32_t type_idx,
-                                                            mirror::ArtMethod* method,
-                                                            Thread* self, bool* slow_path)
-    NO_THREAD_SAFETY_ANALYSIS {
+static inline mirror::Class* CheckObjectAlloc(uint32_t type_idx,
+                                              mirror::ArtMethod* method,
+                                              Thread* self, bool* slow_path) {
   mirror::Class* klass = method->GetDexCacheResolvedTypes()->GetWithoutChecks(type_idx);
   if (UNLIKELY(klass == NULL)) {
     klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
@@ -88,9 +86,9 @@
 }
 
 // TODO: Fix no thread safety analysis when annotalysis is smarter.
-ALWAYS_INLINE static inline mirror::Class* CheckClassInitializedForObjectAlloc(mirror::Class* klass,
-                                                                               Thread* self, bool* slow_path)
-    NO_THREAD_SAFETY_ANALYSIS {
+static inline mirror::Class* CheckClassInitializedForObjectAlloc(mirror::Class* klass,
+                                                                 Thread* self,
+                                                                 bool* slow_path) {
   if (UNLIKELY(!klass->IsInitialized())) {
     StackHandleScope<1> hs(self);
     Handle<mirror::Class> h_class(hs.NewHandle(klass));
@@ -118,11 +116,10 @@
 // check.
 // TODO: Fix NO_THREAD_SAFETY_ANALYSIS when GCC is smarter.
 template <bool kAccessCheck, bool kInstrumented>
-ALWAYS_INLINE static inline mirror::Object* AllocObjectFromCode(uint32_t type_idx,
-                                                                mirror::ArtMethod* method,
-                                                                Thread* self,
-                                                                gc::AllocatorType allocator_type)
-    NO_THREAD_SAFETY_ANALYSIS {
+static inline mirror::Object* AllocObjectFromCode(uint32_t type_idx,
+                                                  mirror::ArtMethod* method,
+                                                  Thread* self,
+                                                  gc::AllocatorType allocator_type) {
   bool slow_path = false;
   mirror::Class* klass = CheckObjectAlloc<kAccessCheck>(type_idx, method, self, &slow_path);
   if (UNLIKELY(slow_path)) {
@@ -138,11 +135,10 @@
 // Given the context of a calling Method and a resolved class, create an instance.
 // TODO: Fix NO_THREAD_SAFETY_ANALYSIS when GCC is smarter.
 template <bool kInstrumented>
-ALWAYS_INLINE static inline mirror::Object* AllocObjectFromCodeResolved(mirror::Class* klass,
-                                                                        mirror::ArtMethod* method,
-                                                                        Thread* self,
-                                                                        gc::AllocatorType allocator_type)
-    NO_THREAD_SAFETY_ANALYSIS {
+static inline mirror::Object* AllocObjectFromCodeResolved(mirror::Class* klass,
+                                                          mirror::ArtMethod* method,
+                                                          Thread* self,
+                                                          gc::AllocatorType allocator_type) {
   DCHECK(klass != nullptr);
   bool slow_path = false;
   klass = CheckClassInitializedForObjectAlloc(klass, self, &slow_path);
@@ -161,11 +157,10 @@
 // Given the context of a calling Method and an initialized class, create an instance.
 // TODO: Fix NO_THREAD_SAFETY_ANALYSIS when GCC is smarter.
 template <bool kInstrumented>
-ALWAYS_INLINE static inline mirror::Object* AllocObjectFromCodeInitialized(mirror::Class* klass,
-                                                                           mirror::ArtMethod* method,
-                                                                           Thread* self,
-                                                                           gc::AllocatorType allocator_type)
-    NO_THREAD_SAFETY_ANALYSIS {
+static inline mirror::Object* AllocObjectFromCodeInitialized(mirror::Class* klass,
+                                                             mirror::ArtMethod* method,
+                                                             Thread* self,
+                                                             gc::AllocatorType allocator_type) {
   DCHECK(klass != nullptr);
   // Pass in false since the object can not be finalizable.
   return klass->Alloc<kInstrumented, false>(self, allocator_type);
@@ -174,11 +169,10 @@
 
 // TODO: Fix no thread safety analysis when GCC can handle template specialization.
 template <bool kAccessCheck>
-ALWAYS_INLINE static inline mirror::Class* CheckArrayAlloc(uint32_t type_idx,
-                                                           mirror::ArtMethod* method,
-                                                           int32_t component_count,
-                                                           bool* slow_path)
-    NO_THREAD_SAFETY_ANALYSIS {
+static inline mirror::Class* CheckArrayAlloc(uint32_t type_idx,
+                                             mirror::ArtMethod* method,
+                                             int32_t component_count,
+                                             bool* slow_path) {
   if (UNLIKELY(component_count < 0)) {
     ThrowNegativeArraySizeException(component_count);
     *slow_path = true;
@@ -211,12 +205,11 @@
 // check.
 // TODO: Fix no thread safety analysis when GCC can handle template specialization.
 template <bool kAccessCheck, bool kInstrumented>
-ALWAYS_INLINE static inline mirror::Array* AllocArrayFromCode(uint32_t type_idx,
-                                                              mirror::ArtMethod* method,
-                                                              int32_t component_count,
-                                                              Thread* self,
-                                                              gc::AllocatorType allocator_type)
-    NO_THREAD_SAFETY_ANALYSIS {
+static inline mirror::Array* AllocArrayFromCode(uint32_t type_idx,
+                                                mirror::ArtMethod* method,
+                                                int32_t component_count,
+                                                Thread* self,
+                                                gc::AllocatorType allocator_type) {
   bool slow_path = false;
   mirror::Class* klass = CheckArrayAlloc<kAccessCheck>(type_idx, method, component_count,
                                                        &slow_path);
@@ -234,12 +227,11 @@
 }
 
 template <bool kAccessCheck, bool kInstrumented>
-ALWAYS_INLINE static inline mirror::Array* AllocArrayFromCodeResolved(mirror::Class* klass,
-                                                                      mirror::ArtMethod* method,
-                                                                      int32_t component_count,
-                                                                      Thread* self,
-                                                                      gc::AllocatorType allocator_type)
-    NO_THREAD_SAFETY_ANALYSIS {
+static inline mirror::Array* AllocArrayFromCodeResolved(mirror::Class* klass,
+                                                        mirror::ArtMethod* method,
+                                                        int32_t component_count,
+                                                        Thread* self,
+                                                        gc::AllocatorType allocator_type) {
   DCHECK(klass != nullptr);
   if (UNLIKELY(component_count < 0)) {
     ThrowNegativeArraySizeException(component_count);
@@ -476,8 +468,7 @@
 // Fast path field resolution that can't initialize classes or throw exceptions.
 static inline mirror::ArtField* FindFieldFast(uint32_t field_idx,
                                               mirror::ArtMethod* referrer,
-                                              FindFieldType type, size_t expected_size)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+                                              FindFieldType type, size_t expected_size) {
   mirror::ArtField* resolved_field =
       referrer->GetDeclaringClass()->GetDexCache()->GetResolvedField(field_idx);
   if (UNLIKELY(resolved_field == nullptr)) {
@@ -534,8 +525,7 @@
 static inline mirror::ArtMethod* FindMethodFast(uint32_t method_idx,
                                                 mirror::Object* this_object,
                                                 mirror::ArtMethod* referrer,
-                                                bool access_check, InvokeType type)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+                                                bool access_check, InvokeType type) {
   bool is_direct = type == kStatic || type == kDirect;
   if (UNLIKELY(this_object == NULL && !is_direct)) {
     return NULL;
@@ -576,8 +566,7 @@
 static inline mirror::Class* ResolveVerifyAndClinit(uint32_t type_idx,
                                                     mirror::ArtMethod* referrer,
                                                     Thread* self, bool can_run_clinit,
-                                                    bool verify_access)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+                                                    bool verify_access) {
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   mirror::Class* klass = class_linker->ResolveType(type_idx, referrer);
   if (UNLIKELY(klass == nullptr)) {
@@ -611,14 +600,12 @@
 }
 
 static inline mirror::String* ResolveStringFromCode(mirror::ArtMethod* referrer,
-                                                    uint32_t string_idx)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+                                                    uint32_t string_idx) {
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   return class_linker->ResolveString(string_idx, referrer);
 }
 
-static inline void UnlockJniSynchronizedMethod(jobject locked, Thread* self)
-    NO_THREAD_SAFETY_ANALYSIS /* SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) */ {
+static inline void UnlockJniSynchronizedMethod(jobject locked, Thread* self) {
   // Save any pending exception over monitor exit call.
   mirror::Throwable* saved_exception = NULL;
   ThrowLocation saved_throw_location;
@@ -642,27 +629,7 @@
   }
 }
 
-static inline void CheckReferenceResult(mirror::Object* o, Thread* self)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  if (o == NULL) {
-    return;
-  }
-  mirror::ArtMethod* m = self->GetCurrentMethod(NULL);
-  if (o == kInvalidIndirectRefObject) {
-    JniAbortF(NULL, "invalid reference returned from %s", PrettyMethod(m).c_str());
-  }
-  // Make sure that the result is an instance of the type this method was expected to return.
-  StackHandleScope<1> hs(self);
-  Handle<mirror::ArtMethod> h_m(hs.NewHandle(m));
-  mirror::Class* return_type = MethodHelper(h_m).GetReturnType();
-
-  if (!o->InstanceOf(return_type)) {
-    JniAbortF(NULL, "attempt to return an instance of %s from %s", PrettyTypeOf(o).c_str(),
-              PrettyMethod(h_m.Get()).c_str());
-  }
-}
-
-static inline void CheckSuspend(Thread* thread) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+static inline void CheckSuspend(Thread* thread) {
   for (;;) {
     if (thread->ReadFlag(kCheckpointRequest)) {
       thread->RunCheckpointFunction();
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index d029df2..0fa0e41 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -20,11 +20,11 @@
 #include "class_linker-inl.h"
 #include "dex_file-inl.h"
 #include "gc/accounting/card_table-inl.h"
+#include "method_helper-inl.h"
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "mirror/object_array-inl.h"
 #include "reflection.h"
 #include "scoped_thread_state_change.h"
@@ -139,6 +139,25 @@
   self->ResetDefaultStackEnd(!explicit_overflow_check);  // Return to default stack size.
 }
 
+void CheckReferenceResult(mirror::Object* o, Thread* self) {
+  if (o == NULL) {
+    return;
+  }
+  mirror::ArtMethod* m = self->GetCurrentMethod(NULL);
+  if (o == kInvalidIndirectRefObject) {
+    JniAbortF(NULL, "invalid reference returned from %s", PrettyMethod(m).c_str());
+  }
+  // Make sure that the result is an instance of the type this method was expected to return.
+  StackHandleScope<1> hs(self);
+  Handle<mirror::ArtMethod> h_m(hs.NewHandle(m));
+  mirror::Class* return_type = MethodHelper(h_m).GetReturnType();
+
+  if (!o->InstanceOf(return_type)) {
+    JniAbortF(NULL, "attempt to return an instance of %s from %s", PrettyTypeOf(o).c_str(),
+              PrettyMethod(h_m.Get()).c_str());
+  }
+}
+
 JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, const char* shorty,
                                     jobject rcvr_jobj, jobject interface_method_jobj,
                                     std::vector<jvalue>& args) {
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index 11a67ac..c5d67aa 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -45,12 +45,12 @@
 ALWAYS_INLINE static inline mirror::Class* CheckObjectAlloc(uint32_t type_idx,
                                                             mirror::ArtMethod* method,
                                                             Thread* self, bool* slow_path)
-    NO_THREAD_SAFETY_ANALYSIS;
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 // TODO: Fix no thread safety analysis when annotalysis is smarter.
 ALWAYS_INLINE static inline mirror::Class* CheckClassInitializedForObjectAlloc(mirror::Class* klass,
                                                                                Thread* self, bool* slow_path)
-    NO_THREAD_SAFETY_ANALYSIS;
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 // Given the context of a calling Method, use its DexCache to resolve a type to a Class. If it
 // cannot be resolved, throw an error. If it can, use it to create an instance.
@@ -61,7 +61,8 @@
 ALWAYS_INLINE static inline mirror::Object* AllocObjectFromCode(uint32_t type_idx,
                                                                 mirror::ArtMethod* method,
                                                                 Thread* self,
-                                                                gc::AllocatorType allocator_type);
+                                                                gc::AllocatorType allocator_type)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 // Given the context of a calling Method and a resolved class, create an instance.
 // TODO: Fix NO_THREAD_SAFETY_ANALYSIS when GCC is smarter.
@@ -70,7 +71,7 @@
                                                                         mirror::ArtMethod* method,
                                                                         Thread* self,
                                                                         gc::AllocatorType allocator_type)
-    NO_THREAD_SAFETY_ANALYSIS;
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 // Given the context of a calling Method and an initialized class, create an instance.
 // TODO: Fix NO_THREAD_SAFETY_ANALYSIS when GCC is smarter.
@@ -78,7 +79,8 @@
 ALWAYS_INLINE static inline mirror::Object* AllocObjectFromCodeInitialized(mirror::Class* klass,
                                                                            mirror::ArtMethod* method,
                                                                            Thread* self,
-                                                                           gc::AllocatorType allocator_type);
+                                                                           gc::AllocatorType allocator_type)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 
 // TODO: Fix no thread safety analysis when GCC can handle template specialization.
@@ -87,7 +89,7 @@
                                                            mirror::ArtMethod* method,
                                                            int32_t component_count,
                                                            bool* slow_path)
-    NO_THREAD_SAFETY_ANALYSIS;
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 // Given the context of a calling Method, use its DexCache to resolve a type to an array Class. If
 // it cannot be resolved, throw an error. If it can, use it to create an array.
@@ -100,7 +102,7 @@
                                                               int32_t component_count,
                                                               Thread* self,
                                                               gc::AllocatorType allocator_type)
-    NO_THREAD_SAFETY_ANALYSIS;
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 template <bool kAccessCheck, bool kInstrumented>
 ALWAYS_INLINE static inline mirror::Array* AllocArrayFromCodeResolved(mirror::Class* klass,
@@ -108,7 +110,7 @@
                                                                       int32_t component_count,
                                                                       Thread* self,
                                                                       gc::AllocatorType allocator_type)
-    NO_THREAD_SAFETY_ANALYSIS;
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 extern mirror::Array* CheckAndAllocArrayFromCode(uint32_t type_idx, mirror::ArtMethod* method,
                                                  int32_t component_count, Thread* self,
@@ -171,10 +173,11 @@
                                                     uint32_t string_idx)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
+// TODO: annotalysis disabled as monitor semantics are maintained in Java code.
 static inline void UnlockJniSynchronizedMethod(jobject locked, Thread* self)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+    NO_THREAD_SAFETY_ANALYSIS;
 
-static inline void CheckReferenceResult(mirror::Object* o, Thread* self)
+void CheckReferenceResult(mirror::Object* o, Thread* self)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 static inline void CheckSuspend(Thread* thread) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/entrypoints/interpreter/interpreter_entrypoints.cc b/runtime/entrypoints/interpreter/interpreter_entrypoints.cc
index 329c175..64faf76 100644
--- a/runtime/entrypoints/interpreter/interpreter_entrypoints.cc
+++ b/runtime/entrypoints/interpreter/interpreter_entrypoints.cc
@@ -18,7 +18,6 @@
 #include "interpreter/interpreter.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "reflection.h"
 #include "runtime.h"
 #include "stack.h"
diff --git a/runtime/entrypoints/jni/jni_entrypoints.cc b/runtime/entrypoints/jni/jni_entrypoints.cc
index bae4023..edb3b72 100644
--- a/runtime/entrypoints/jni/jni_entrypoints.cc
+++ b/runtime/entrypoints/jni/jni_entrypoints.cc
@@ -18,7 +18,6 @@
 #include "entrypoints/entrypoint_utils.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "scoped_thread_state_change.h"
 #include "thread.h"
 
diff --git a/runtime/entrypoints/portable/portable_throw_entrypoints.cc b/runtime/entrypoints/portable/portable_throw_entrypoints.cc
index 9e36a05..be6231c 100644
--- a/runtime/entrypoints/portable/portable_throw_entrypoints.cc
+++ b/runtime/entrypoints/portable/portable_throw_entrypoints.cc
@@ -80,7 +80,6 @@
   }
   mirror::Class* exception_type = exception->GetClass();
   StackHandleScope<1> hs(self);
-  MethodHelper mh(hs.NewHandle(current_method));
   const DexFile::CodeItem* code_item = current_method->GetCodeItem();
   DCHECK_LT(ti_offset, code_item->tries_size_);
   const DexFile::TryItem* try_item = DexFile::GetTryItems(*code_item, ti_offset);
@@ -98,7 +97,8 @@
       break;
     }
     // Does this catch exception type apply?
-    mirror::Class* iter_exception_type = mh.GetDexCacheResolvedType(iter_type_idx);
+    mirror::Class* iter_exception_type =
+        current_method->GetDexCacheResolvedTypes()->Get(iter_type_idx);
     if (UNLIKELY(iter_exception_type == NULL)) {
       // TODO: check, the verifier (class linker?) should take care of resolving all exception
       //       classes early.
diff --git a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc b/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
index 7ee869b..9f75b0f 100644
--- a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
@@ -22,7 +22,6 @@
 #include "interpreter/interpreter.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "scoped_thread_state_change.h"
 
 namespace art {
diff --git a/runtime/entrypoints/quick/quick_deoptimization_entrypoints.cc b/runtime/entrypoints/quick/quick_deoptimization_entrypoints.cc
index 47fb9d6..f9f62c2 100644
--- a/runtime/entrypoints/quick/quick_deoptimization_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_deoptimization_entrypoints.cc
@@ -21,7 +21,6 @@
 #include "mirror/class-inl.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "stack.h"
 #include "thread.h"
 #include "verifier/method_verifier.h"
diff --git a/runtime/entrypoints/quick/quick_jni_entrypoints.cc b/runtime/entrypoints/quick/quick_jni_entrypoints.cc
index 30e8609..6537249 100644
--- a/runtime/entrypoints/quick/quick_jni_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_jni_entrypoints.cc
@@ -21,7 +21,6 @@
 #include "mirror/object.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
-#include "object_utils.h"
 #include "scoped_thread_state_change.h"
 #include "thread.h"
 #include "verify_object-inl.h"
diff --git a/runtime/entrypoints/quick/quick_throw_entrypoints.cc b/runtime/entrypoints/quick/quick_throw_entrypoints.cc
index 4dcb1c8..879010e 100644
--- a/runtime/entrypoints/quick/quick_throw_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_throw_entrypoints.cc
@@ -18,7 +18,6 @@
 #include "common_throws.h"
 #include "entrypoints/entrypoint_utils-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "thread.h"
 #include "well_known_classes.h"
 
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index f7cb126..338bd06 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -27,7 +27,6 @@
 #include "mirror/dex_cache-inl.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
-#include "object_utils.h"
 #include "runtime.h"
 #include "scoped_thread_state_change.h"
 
diff --git a/runtime/entrypoints_order_test.cc b/runtime/entrypoints_order_test.cc
index c572baf..79c68a2 100644
--- a/runtime/entrypoints_order_test.cc
+++ b/runtime/entrypoints_order_test.cc
@@ -121,7 +121,7 @@
     EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, thread_local_end, thread_local_objects, kPointerSize);
     EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, thread_local_objects, rosalloc_runs, kPointerSize);
     EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, rosalloc_runs, thread_local_alloc_stack_top,
-                        kPointerSize * gc::allocator::RosAlloc::kNumThreadLocalSizeBrackets);
+                        kPointerSize * kNumRosAllocThreadLocalSizeBrackets);
     EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, thread_local_alloc_stack_top, thread_local_alloc_stack_end,
                         kPointerSize);
     EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, thread_local_alloc_stack_end, held_mutexes, kPointerSize);
diff --git a/runtime/fault_handler.cc b/runtime/fault_handler.cc
index 3112bc0..b4355ca 100644
--- a/runtime/fault_handler.cc
+++ b/runtime/fault_handler.cc
@@ -15,23 +15,16 @@
  */
 
 #include "fault_handler.h"
+
 #include <sys/mman.h>
 #include <sys/ucontext.h>
-#include "base/macros.h"
-#include "globals.h"
-#include "base/logging.h"
-#include "base/hex_dump.h"
-#include "thread.h"
-#include "mirror/art_method-inl.h"
-#include "mirror/class-inl.h"
-#include "mirror/dex_cache.h"
-#include "mirror/object_array-inl.h"
-#include "mirror/object-inl.h"
-#include "object_utils.h"
-#include "scoped_thread_state_change.h"
+
+#include "mirror/art_method.h"
+#include "mirror/class.h"
 #ifdef HAVE_ANDROID_OS
 #include "sigchain.h"
 #endif
+#include "thread-inl.h"
 #include "verify_object-inl.h"
 
 namespace art {
diff --git a/runtime/field_helper.cc b/runtime/field_helper.cc
new file mode 100644
index 0000000..40daa6d
--- /dev/null
+++ b/runtime/field_helper.cc
@@ -0,0 +1,57 @@
+/*
+ * 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 "field_helper.h"
+
+#include "class_linker-inl.h"
+#include "dex_file.h"
+#include "mirror/dex_cache.h"
+#include "runtime.h"
+#include "thread-inl.h"
+
+namespace art {
+
+mirror::Class* FieldHelper::GetType(bool resolve) {
+  uint32_t field_index = field_->GetDexFieldIndex();
+  if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
+    return Runtime::Current()->GetClassLinker()->FindSystemClass(Thread::Current(),
+                                                                 field_->GetTypeDescriptor());
+  }
+  const DexFile* dex_file = field_->GetDexFile();
+  const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index);
+  mirror::Class* type = field_->GetDexCache()->GetResolvedType(field_id.type_idx_);
+  if (resolve && (type == nullptr)) {
+    type = Runtime::Current()->GetClassLinker()->ResolveType(field_id.type_idx_, field_.Get());
+    CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
+  }
+  return type;
+}
+
+const char* FieldHelper::GetDeclaringClassDescriptor() {
+  uint32_t field_index = field_->GetDexFieldIndex();
+  if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
+    DCHECK(field_->IsStatic());
+    DCHECK_LT(field_index, 2U);
+    // 0 == Class[] interfaces; 1 == Class[][] throws;
+    declaring_class_descriptor_ = field_->GetDeclaringClass()->GetDescriptor();
+    return declaring_class_descriptor_.c_str();
+  }
+  const DexFile* dex_file = field_->GetDexFile();
+  const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index);
+  return dex_file->GetFieldDeclaringClassDescriptor(field_id);
+}
+
+}  // namespace art
diff --git a/runtime/field_helper.h b/runtime/field_helper.h
new file mode 100644
index 0000000..5eae55e
--- /dev/null
+++ b/runtime/field_helper.h
@@ -0,0 +1,54 @@
+/*
+ * 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_FIELD_HELPER_H_
+#define ART_RUNTIME_FIELD_HELPER_H_
+
+#include "base/macros.h"
+#include "handle.h"
+#include "mirror/art_field.h"
+
+namespace art {
+
+class FieldHelper {
+ public:
+  explicit FieldHelper(Handle<mirror::ArtField> f) : field_(f) {}
+
+  void ChangeField(mirror::ArtField* new_f) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    DCHECK(new_f != nullptr);
+    field_.Assign(new_f);
+  }
+
+  mirror::ArtField* GetField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    return field_.Get();
+  }
+
+  mirror::Class* GetType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  // The returned const char* is only guaranteed to be valid for the lifetime of the FieldHelper.
+  // If you need it longer, copy it into a std::string.
+  const char* GetDeclaringClassDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ private:
+  Handle<mirror::ArtField> field_;
+  std::string declaring_class_descriptor_;
+
+  DISALLOW_COPY_AND_ASSIGN(FieldHelper);
+};
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_FIELD_HELPER_H_
diff --git a/runtime/gc/accounting/space_bitmap-inl.h b/runtime/gc/accounting/space_bitmap-inl.h
index 1e9556a..fc4213e 100644
--- a/runtime/gc/accounting/space_bitmap-inl.h
+++ b/runtime/gc/accounting/space_bitmap-inl.h
@@ -23,14 +23,6 @@
 
 #include "atomic.h"
 #include "base/logging.h"
-#include "dex_file-inl.h"
-#include "heap_bitmap.h"
-#include "mirror/art_field-inl.h"
-#include "mirror/class-inl.h"
-#include "mirror/object-inl.h"
-#include "mirror/object_array-inl.h"
-#include "object_utils.h"
-#include "space_bitmap-inl.h"
 #include "utils.h"
 
 namespace art {
diff --git a/runtime/gc/accounting/space_bitmap.cc b/runtime/gc/accounting/space_bitmap.cc
index c0aa43e..39d1f9e 100644
--- a/runtime/gc/accounting/space_bitmap.cc
+++ b/runtime/gc/accounting/space_bitmap.cc
@@ -16,6 +16,13 @@
 
 #include "space_bitmap-inl.h"
 
+#include "base/stringprintf.h"
+#include "mem_map.h"
+#include "mirror/object-inl.h"
+#include "mirror/class.h"
+#include "mirror/art_field.h"
+#include "mirror/object_array.h"
+
 namespace art {
 namespace gc {
 namespace accounting {
@@ -46,6 +53,9 @@
 }
 
 template<size_t kAlignment>
+SpaceBitmap<kAlignment>::~SpaceBitmap() {}
+
+template<size_t kAlignment>
 SpaceBitmap<kAlignment>* SpaceBitmap<kAlignment>::Create(
     const std::string& name, byte* heap_begin, size_t heap_capacity) {
   // Round up since heap_capacity is not necessarily a multiple of kAlignment * kBitsPerWord.
diff --git a/runtime/gc/accounting/space_bitmap.h b/runtime/gc/accounting/space_bitmap.h
index 6d1ba87..a3073bd 100644
--- a/runtime/gc/accounting/space_bitmap.h
+++ b/runtime/gc/accounting/space_bitmap.h
@@ -54,8 +54,7 @@
   static SpaceBitmap* CreateFromMemMap(const std::string& name, MemMap* mem_map,
                                        byte* heap_begin, size_t heap_capacity);
 
-  ~SpaceBitmap() {
-  }
+  ~SpaceBitmap();
 
   // <offset> is the difference from .base to a pointer address.
   // <index> is the index of .bits that contains the bit representing
diff --git a/runtime/gc/allocator/rosalloc.h b/runtime/gc/allocator/rosalloc.h
index c0ab151..b2a5a3c 100644
--- a/runtime/gc/allocator/rosalloc.h
+++ b/runtime/gc/allocator/rosalloc.h
@@ -30,6 +30,7 @@
 #include "base/logging.h"
 #include "globals.h"
 #include "mem_map.h"
+#include "thread.h"
 #include "utils.h"
 
 namespace art {
@@ -261,7 +262,7 @@
   // The magic number for free pages.
   static const byte kMagicNumFree = 43;
   // The number of size brackets. Sync this with the length of Thread::rosalloc_runs_.
-  static const size_t kNumOfSizeBrackets = 34;
+  static const size_t kNumOfSizeBrackets = kNumRosAllocThreadLocalSizeBrackets;
   // The number of smaller size brackets that are 16 bytes apart.
   static const size_t kNumOfQuantumSizeBrackets = 32;
   // The sizes (the slot sizes, in bytes) of the size brackets.
diff --git a/runtime/gc/collector/immune_region.h b/runtime/gc/collector/immune_region.h
index 0c0a89b..277525e 100644
--- a/runtime/gc/collector/immune_region.h
+++ b/runtime/gc/collector/immune_region.h
@@ -19,7 +19,6 @@
 
 #include "base/macros.h"
 #include "base/mutex.h"
-#include "gc/space/space-inl.h"
 
 namespace art {
 namespace mirror {
diff --git a/runtime/gc/collector/mark_compact.h b/runtime/gc/collector/mark_compact.h
index 25cfe0f..bb85fa0 100644
--- a/runtime/gc/collector/mark_compact.h
+++ b/runtime/gc/collector/mark_compact.h
@@ -49,6 +49,7 @@
 }  // namespace accounting
 
 namespace space {
+  class BumpPointerSpace;
   class ContinuousMemMapAllocSpace;
   class ContinuousSpace;
 }  // namespace space
diff --git a/runtime/gc/collector/semi_space.h b/runtime/gc/collector/semi_space.h
index c5d25f3..71a83f2 100644
--- a/runtime/gc/collector/semi_space.h
+++ b/runtime/gc/collector/semi_space.h
@@ -25,6 +25,7 @@
 #include "garbage_collector.h"
 #include "gc/accounting/heap_bitmap.h"
 #include "immune_region.h"
+#include "mirror/object_reference.h"
 #include "object_callbacks.h"
 #include "offsets.h"
 
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 696df32..0934921 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -58,7 +58,6 @@
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/reference-inl.h"
-#include "object_utils.h"
 #include "os.h"
 #include "reflection.h"
 #include "runtime.h"
diff --git a/runtime/gc/heap_test.cc b/runtime/gc/heap_test.cc
index 4176f4a..e6b5c75 100644
--- a/runtime/gc/heap_test.cc
+++ b/runtime/gc/heap_test.cc
@@ -17,10 +17,11 @@
 #include "common_runtime_test.h"
 #include "gc/accounting/card_table-inl.h"
 #include "gc/accounting/space_bitmap-inl.h"
+#include "handle_scope-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
-#include "handle_scope-inl.h"
+#include "scoped_thread_state_change.h"
 
 namespace art {
 namespace gc {
diff --git a/runtime/gc/reference_processor-inl.h b/runtime/gc/reference_processor-inl.h
new file mode 100644
index 0000000..f619a15
--- /dev/null
+++ b/runtime/gc/reference_processor-inl.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 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_GC_REFERENCE_PROCESSOR_INL_H_
+#define ART_RUNTIME_GC_REFERENCE_PROCESSOR_INL_H_
+
+#include "reference_processor.h"
+
+namespace art {
+namespace gc {
+
+inline bool ReferenceProcessor::SlowPathEnabled() {
+  return mirror::Reference::GetJavaLangRefReference()->GetSlowPathEnabled();
+}
+
+}  // namespace gc
+}  // namespace art
+
+#endif  // ART_RUNTIME_GC_REFERENCE_PROCESSOR_INL_H_
diff --git a/runtime/gc/reference_processor.cc b/runtime/gc/reference_processor.cc
index e52bc1f..d3641d1 100644
--- a/runtime/gc/reference_processor.cc
+++ b/runtime/gc/reference_processor.cc
@@ -17,7 +17,9 @@
 #include "reference_processor.h"
 
 #include "mirror/object-inl.h"
+#include "mirror/reference.h"
 #include "mirror/reference-inl.h"
+#include "reference_processor-inl.h"
 #include "reflection.h"
 #include "ScopedLocalRef.h"
 #include "scoped_thread_state_change.h"
@@ -27,18 +29,17 @@
 namespace gc {
 
 ReferenceProcessor::ReferenceProcessor()
-    : process_references_args_(nullptr, nullptr, nullptr), slow_path_enabled_(false),
+    : process_references_args_(nullptr, nullptr, nullptr),
       preserving_references_(false), lock_("reference processor lock", kReferenceProcessorLock),
       condition_("reference processor condition", lock_) {
 }
 
 void ReferenceProcessor::EnableSlowPath() {
-  Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
-  slow_path_enabled_ = true;
+  mirror::Reference::GetJavaLangRefReference()->SetSlowPath(true);
 }
 
 void ReferenceProcessor::DisableSlowPath(Thread* self) {
-  slow_path_enabled_ = false;
+  mirror::Reference::GetJavaLangRefReference()->SetSlowPath(false);
   condition_.Broadcast(self);
 }
 
@@ -46,11 +47,11 @@
   mirror::Object* const referent = reference->GetReferent();
   // If the referent is null then it is already cleared, we can just return null since there is no
   // scenario where it becomes non-null during the reference processing phase.
-  if (LIKELY(!slow_path_enabled_) || referent == nullptr) {
+  if (UNLIKELY(!SlowPathEnabled()) || referent == nullptr) {
     return referent;
   }
   MutexLock mu(self, lock_);
-  while (slow_path_enabled_) {
+  while (SlowPathEnabled()) {
     mirror::HeapReference<mirror::Object>* const referent_addr =
         reference->GetReferentReferenceAddr();
     // If the referent became cleared, return it. Don't need barrier since thread roots can't get
@@ -117,7 +118,7 @@
     process_references_args_.is_marked_callback_ = is_marked_callback;
     process_references_args_.mark_callback_ = mark_object_callback;
     process_references_args_.arg_ = arg;
-    CHECK_EQ(slow_path_enabled_, concurrent) << "Slow path must be enabled iff concurrent";
+    CHECK_EQ(SlowPathEnabled(), concurrent) << "Slow path must be enabled iff concurrent";
   }
   // Unless required to clear soft references with white references, preserve some white referents.
   if (!clear_soft_references) {
@@ -182,7 +183,7 @@
                                                 void* arg) {
   // klass can be the class of the old object if the visitor already updated the class of ref.
   DCHECK(klass != nullptr);
-  DCHECK(klass->IsReferenceClass());
+  DCHECK(klass->IsTypeOfReferenceClass());
   mirror::HeapReference<mirror::Object>* referent = ref->GetReferentReferenceAddr();
   if (referent->AsMirrorPtr() != nullptr && !is_marked_callback(referent, arg)) {
     Thread* self = Thread::Current();
diff --git a/runtime/gc/reference_processor.h b/runtime/gc/reference_processor.h
index 2771ea8..7274457 100644
--- a/runtime/gc/reference_processor.h
+++ b/runtime/gc/reference_processor.h
@@ -49,6 +49,7 @@
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
       EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
       LOCKS_EXCLUDED(lock_);
+  // The slow path bool is contained in the reference class object, can only be set once
   // Only allow setting this with mutators suspended so that we can avoid using a lock in the
   // GetReferent fast path as an optimization.
   void EnableSlowPath() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -60,7 +61,7 @@
                               IsHeapReferenceMarkedCallback* is_marked_callback, void* arg)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   void UpdateRoots(IsMarkedCallback* callback, void* arg)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_);
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_);
 
  private:
   class ProcessReferencesArgs {
@@ -75,8 +76,10 @@
     MarkObjectCallback* mark_callback_;
     void* arg_;
   };
+  bool SlowPathEnabled() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   // Called by ProcessReferences.
-  void DisableSlowPath(Thread* self) EXCLUSIVE_LOCKS_REQUIRED(lock_);
+  void DisableSlowPath(Thread* self) EXCLUSIVE_LOCKS_REQUIRED(lock_)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   // If we are preserving references it means that some dead objects may become live, we use start
   // and stop preserving to block mutators using GetReferrent from getting access to these
   // referents.
@@ -84,8 +87,6 @@
   void StopPreservingReferences(Thread* self) LOCKS_EXCLUDED(lock_);
   // Process args, used by the GetReferent to return referents which are already marked.
   ProcessReferencesArgs process_references_args_ GUARDED_BY(lock_);
-  // Boolean for whether or not we need to go slow path in GetReferent.
-  volatile bool slow_path_enabled_;
   // Boolean for whether or not we are preserving references (either soft references or finalizers).
   // If this is true, then we cannot return a referent (see comment in GetReferent).
   bool preserving_references_ GUARDED_BY(lock_);
diff --git a/runtime/gc/space/dlmalloc_space_base_test.cc b/runtime/gc/space/dlmalloc_space_base_test.cc
index 129eace..02fc4a5 100644
--- a/runtime/gc/space/dlmalloc_space_base_test.cc
+++ b/runtime/gc/space/dlmalloc_space_base_test.cc
@@ -15,7 +15,9 @@
  */
 
 #include "space_test.h"
+
 #include "dlmalloc_space.h"
+#include "scoped_thread_state_change.h"
 
 namespace art {
 namespace gc {
diff --git a/runtime/gc/space/dlmalloc_space_random_test.cc b/runtime/gc/space/dlmalloc_space_random_test.cc
index c4f8bae..4b1a1b1 100644
--- a/runtime/gc/space/dlmalloc_space_random_test.cc
+++ b/runtime/gc/space/dlmalloc_space_random_test.cc
@@ -15,6 +15,7 @@
  */
 
 #include "space_test.h"
+
 #include "dlmalloc_space.h"
 
 namespace art {
diff --git a/runtime/gc/space/dlmalloc_space_static_test.cc b/runtime/gc/space/dlmalloc_space_static_test.cc
index edaa198..d17d0a7 100644
--- a/runtime/gc/space/dlmalloc_space_static_test.cc
+++ b/runtime/gc/space/dlmalloc_space_static_test.cc
@@ -15,6 +15,7 @@
  */
 
 #include "space_test.h"
+
 #include "dlmalloc_space.h"
 
 namespace art {
diff --git a/runtime/gc/space/space_test.h b/runtime/gc/space/space_test.h
index a2d4942..0291155 100644
--- a/runtime/gc/space/space_test.h
+++ b/runtime/gc/space/space_test.h
@@ -17,8 +17,6 @@
 #ifndef ART_RUNTIME_GC_SPACE_SPACE_TEST_H_
 #define ART_RUNTIME_GC_SPACE_SPACE_TEST_H_
 
-#include "zygote_space.h"
-
 #include <stdint.h>
 #include <memory>
 
@@ -26,6 +24,8 @@
 #include "globals.h"
 #include "mirror/array-inl.h"
 #include "mirror/object-inl.h"
+#include "scoped_thread_state_change.h"
+#include "zygote_space.h"
 
 namespace art {
 namespace gc {
diff --git a/runtime/globals.h b/runtime/globals.h
index 3a906f1..1d9f22c 100644
--- a/runtime/globals.h
+++ b/runtime/globals.h
@@ -105,6 +105,19 @@
 // If true, references within the heap are poisoned (negated).
 static constexpr bool kPoisonHeapReferences = false;
 
+// Kinds of tracing clocks.
+enum TraceClockSource {
+  kTraceClockSourceThreadCpu,
+  kTraceClockSourceWall,
+  kTraceClockSourceDual,  // Both wall and thread CPU clocks.
+};
+
+#if defined(HAVE_POSIX_CLOCKS)
+static constexpr TraceClockSource kDefaultTraceClockSource = kTraceClockSourceDual;
+#else
+static constexpr TraceClockSource kDefaultTraceClockSource = kTraceClockSourceWall;
+#endif
+
 }  // namespace art
 
 #endif  // ART_RUNTIME_GLOBALS_H_
diff --git a/runtime/handle.h b/runtime/handle.h
index 7e13601..f70faf4 100644
--- a/runtime/handle.h
+++ b/runtime/handle.h
@@ -28,29 +28,40 @@
 
 template<class T> class Handle;
 
+// Handles are memory locations that contain GC roots. As the mirror::Object*s within a handle are
+// GC visible then the GC may move the references within them, something that couldn't be done with
+// a wrap pointer. Handles are generally allocated within HandleScopes. ConstHandle is a super-class
+// of Handle and doesn't support assignment operations.
 template<class T>
 class ConstHandle {
  public:
   ConstHandle() : reference_(nullptr) {
   }
-  ConstHandle(const ConstHandle<T>& handle) ALWAYS_INLINE : reference_(handle.reference_) {
+
+  ALWAYS_INLINE ConstHandle(const ConstHandle<T>& handle) : reference_(handle.reference_) {
   }
-  ConstHandle<T>& operator=(const ConstHandle<T>& handle) ALWAYS_INLINE {
+
+  ALWAYS_INLINE ConstHandle<T>& operator=(const ConstHandle<T>& handle) {
     reference_ = handle.reference_;
     return *this;
   }
-  explicit ConstHandle(StackReference<T>* reference) ALWAYS_INLINE : reference_(reference) {
+
+  ALWAYS_INLINE explicit ConstHandle(StackReference<T>* reference) : reference_(reference) {
   }
-  T& operator*() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
+
+  ALWAYS_INLINE T& operator*() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return *Get();
   }
-  T* operator->() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
+
+  ALWAYS_INLINE T* operator->() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return Get();
   }
-  T* Get() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
+
+  ALWAYS_INLINE T* Get() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return reference_->AsMirrorPtr();
   }
-  jobject ToJObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
+
+  ALWAYS_INLINE jobject ToJObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     if (UNLIKELY(reference_->AsMirrorPtr() == nullptr)) {
       // Special case so that we work with NullHandles.
       return nullptr;
@@ -73,8 +84,8 @@
   StackReference<T>* GetReference() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
     return reference_;
   }
-  const StackReference<T>* GetReference() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-      ALWAYS_INLINE {
+  ALWAYS_INLINE const StackReference<T>* GetReference() const
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return reference_;
   }
 
@@ -86,47 +97,54 @@
   template<size_t kNumReferences> friend class StackHandleScope;
 };
 
+// Handles that support assignment.
 template<class T>
 class Handle : public ConstHandle<T> {
  public:
   Handle() {
   }
-  Handle(const Handle<T>& handle) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE
+
+  ALWAYS_INLINE Handle(const Handle<T>& handle) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
       : ConstHandle<T>(handle.reference_) {
   }
-  Handle<T>& operator=(const Handle<T>& handle) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-      ALWAYS_INLINE {
+
+  ALWAYS_INLINE Handle<T>& operator=(const Handle<T>& handle)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     ConstHandle<T>::operator=(handle);
     return *this;
   }
-  explicit Handle(StackReference<T>* reference) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-      ALWAYS_INLINE : ConstHandle<T>(reference) {
+
+  ALWAYS_INLINE explicit Handle(StackReference<T>* reference)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+      : ConstHandle<T>(reference) {
   }
-  T* Assign(T* reference) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
+
+  ALWAYS_INLINE T* Assign(T* reference) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     StackReference<T>* ref = ConstHandle<T>::GetReference();
     T* const old = ref->AsMirrorPtr();
     ref->Assign(reference);
     return old;
   }
 
+  template<typename S>
+  explicit Handle(const Handle<S>& handle) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+      : ConstHandle<T>(handle) {
+  }
+
  protected:
   template<typename S>
   explicit Handle(StackReference<S>* reference) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
       : ConstHandle<T>(reference) {
   }
-  template<typename S>
-  explicit Handle(const Handle<S>& handle) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-      : ConstHandle<T>(handle) {
-  }
 
  private:
   friend class BuildGenericJniFrameVisitor;
-  template<class S> friend class Handle;
   friend class HandleScope;
   template<class S> friend class HandleWrapper;
   template<size_t kNumReferences> friend class StackHandleScope;
 };
 
+// A special case of Handle that only holds references to null.
 template<class T>
 class NullHandle : public Handle<T> {
  public:
diff --git a/runtime/handle_scope-inl.h b/runtime/handle_scope-inl.h
index 62c7614..7bc811d 100644
--- a/runtime/handle_scope-inl.h
+++ b/runtime/handle_scope-inl.h
@@ -17,7 +17,7 @@
 #ifndef ART_RUNTIME_HANDLE_SCOPE_INL_H_
 #define ART_RUNTIME_HANDLE_SCOPE_INL_H_
 
-#include "handle_scope-inl.h"
+#include "handle_scope.h"
 
 #include "handle.h"
 #include "thread.h"
diff --git a/runtime/handle_scope.h b/runtime/handle_scope.h
index 629e4ec..42ef779 100644
--- a/runtime/handle_scope.h
+++ b/runtime/handle_scope.h
@@ -27,10 +27,12 @@
 namespace mirror {
 class Object;
 }
+
 class Thread;
 
-// HandleScopes can be allocated within the bridge frame between managed and native code backed by
-// stack storage or manually allocated in native.
+// HandleScopes are scoped objects containing a number of Handles. They are used to allocate
+// handles, for these handles (and the objects contained within them) to be visible/roots for the
+// GC. It is most common to stack allocate HandleScopes using StackHandleScope.
 class PACKED(4) HandleScope {
  public:
   ~HandleScope() {}
@@ -130,6 +132,7 @@
 
  private:
   template<size_t kNumReferences> friend class StackHandleScope;
+
   DISALLOW_COPY_AND_ASSIGN(HandleScope);
 };
 
@@ -152,7 +155,7 @@
 
 // Scoped handle storage of a fixed size that is usually stack allocated.
 template<size_t kNumReferences>
-class PACKED(4) StackHandleScope : public HandleScope {
+class PACKED(4) StackHandleScope FINAL : public HandleScope {
  public:
   explicit StackHandleScope(Thread* self);
   ~StackHandleScope();
@@ -181,20 +184,29 @@
   template<class T>
   Handle<T> NewHandle(T* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     SetReference(pos_, object);
-    return Handle<T>(GetHandle(pos_++));
+    Handle<T> h(GetHandle(pos_));
+    pos_++;
+    return h;
   }
 
   template<class T>
   HandleWrapper<T> NewHandleWrapper(T** object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     SetReference(pos_, *object);
-    Handle<T> h(GetHandle(pos_++));
+    Handle<T> h(GetHandle(pos_));
+    pos_++;
     return HandleWrapper<T>(object, h);
   }
 
  private:
-  // references_storage_ needs to be first so that it matches the address of references_.
+  // References_storage_ needs to be first so that it appears in the same location as
+  // HandleScope::references_.
   StackReference<mirror::Object> references_storage_[kNumReferences];
+
+  // The thread that the stack handle scope is a linked list upon. The stack handle scope will
+  // push and pop itself from this thread.
   Thread* const self_;
+
+  // Position new handles will be created.
   size_t pos_;
 
   template<size_t kNumRefs> friend class StackHandleScope;
diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc
index 33339f8..7e3b6ba 100644
--- a/runtime/hprof/hprof.cc
+++ b/runtime/hprof/hprof.cc
@@ -52,7 +52,6 @@
 #include "mirror/class.h"
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "os.h"
 #include "safe_map.h"
 #include "scoped_thread_state_change.h"
diff --git a/runtime/indirect_reference_table_test.cc b/runtime/indirect_reference_table_test.cc
index 449817a..a33a981 100644
--- a/runtime/indirect_reference_table_test.cc
+++ b/runtime/indirect_reference_table_test.cc
@@ -18,6 +18,7 @@
 
 #include "common_runtime_test.h"
 #include "mirror/object-inl.h"
+#include "scoped_thread_state_change.h"
 
 namespace art {
 
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 05320ce..f4eaa61 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -18,6 +18,7 @@
 
 #include <sys/uio.h>
 
+#include "arch/context.h"
 #include "atomic.h"
 #include "base/unix_file/fd_file.h"
 #include "class_linker.h"
@@ -34,7 +35,6 @@
 #if !defined(ART_USE_PORTABLE_COMPILER)
 #include "entrypoints/quick/quick_entrypoints.h"
 #endif
-#include "object_utils.h"
 #include "os.h"
 #include "scoped_thread_state_change.h"
 #include "thread.h"
diff --git a/runtime/intern_table_test.cc b/runtime/intern_table_test.cc
index 5995d9e..d462e14 100644
--- a/runtime/intern_table_test.cc
+++ b/runtime/intern_table_test.cc
@@ -19,6 +19,8 @@
 #include "common_runtime_test.h"
 #include "mirror/object.h"
 #include "handle_scope-inl.h"
+#include "mirror/string.h"
+#include "scoped_thread_state_change.h"
 
 namespace art {
 
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 5a03601..b35da0c 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -15,6 +15,8 @@
  */
 
 #include "interpreter_common.h"
+
+#include "field_helper.h"
 #include "mirror/array-inl.h"
 
 namespace art {
@@ -35,7 +37,6 @@
     CHECK(self->IsExceptionPending());
     return false;
   }
-  f->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self);
   Object* obj;
   if (is_static) {
     obj = f->GetDeclaringClass();
@@ -46,6 +47,7 @@
       return false;
     }
   }
+  f->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self);
   // Report this field access to instrumentation if needed.
   instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
   if (UNLIKELY(instrumentation->HasFieldReadListeners())) {
@@ -211,7 +213,6 @@
     CHECK(self->IsExceptionPending());
     return false;
   }
-  f->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self);
   Object* obj;
   if (is_static) {
     obj = f->GetDeclaringClass();
@@ -223,6 +224,7 @@
       return false;
     }
   }
+  f->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self);
   uint32_t vregA = is_static ? inst->VRegA_21c(inst_data) : inst->VRegA_22c(inst_data);
   // Report this field access to instrumentation if needed. Since we only have the offset of
   // the field from the base of the object, we need to look for it first.
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index db42eb0..1bcd27e 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -30,6 +30,7 @@
 #include "entrypoints/entrypoint_utils-inl.h"
 #include "gc/accounting/card_table-inl.h"
 #include "handle_scope-inl.h"
+#include "method_helper-inl.h"
 #include "nth_caller_visitor.h"
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method.h"
@@ -39,7 +40,6 @@
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/string-inl.h"
-#include "object_utils.h"
 #include "ScopedLocalRef.h"
 #include "scoped_thread_state_change.h"
 #include "thread.h"
diff --git a/runtime/jdwp/object_registry.cc b/runtime/jdwp/object_registry.cc
index 29d3c8a..ad18d8a 100644
--- a/runtime/jdwp/object_registry.cc
+++ b/runtime/jdwp/object_registry.cc
@@ -16,6 +16,7 @@
 
 #include "object_registry.h"
 
+#include "mirror/class.h"
 #include "scoped_thread_state_change.h"
 
 namespace art {
diff --git a/runtime/jdwp/object_registry.h b/runtime/jdwp/object_registry.h
index e1a6875..f0314a3 100644
--- a/runtime/jdwp/object_registry.h
+++ b/runtime/jdwp/object_registry.h
@@ -17,20 +17,21 @@
 #ifndef ART_RUNTIME_JDWP_OBJECT_REGISTRY_H_
 #define ART_RUNTIME_JDWP_OBJECT_REGISTRY_H_
 
+#include <jni.h>
 #include <stdint.h>
 
 #include <map>
 
 #include "jdwp/jdwp.h"
-#include "mirror/art_field-inl.h"
-#include "mirror/class.h"
-#include "mirror/class-inl.h"
-#include "mirror/object-inl.h"
-#include "object_callbacks.h"
 #include "safe_map.h"
 
 namespace art {
 
+namespace mirror {
+  class Object;
+  class Class;
+}  // namespace mirror
+
 struct ObjectRegistryEntry {
   // Is jni_reference a weak global or a regular global reference?
   jobjectRefType jni_reference_type;
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 845691d..f9c7ec6 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -41,7 +41,6 @@
 #include "mirror/object_array-inl.h"
 #include "mirror/string-inl.h"
 #include "mirror/throwable.h"
-#include "object_utils.h"
 #include "parsed_options.h"
 #include "reflection.h"
 #include "runtime.h"
@@ -3002,7 +3001,7 @@
     LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version;
     return JNI_EVERSION;
   }
-  Runtime::Options options;
+  RuntimeOptions options;
   for (int i = 0; i < args->nOptions; ++i) {
     JavaVMOption* option = &args->options[i];
     options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo));
diff --git a/runtime/jni_internal_test.cc b/runtime/jni_internal_test.cc
index 8ef1cb6..7c7e60c 100644
--- a/runtime/jni_internal_test.cc
+++ b/runtime/jni_internal_test.cc
@@ -19,6 +19,7 @@
 #include "common_compiler_test.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/string-inl.h"
+#include "scoped_thread_state_change.h"
 #include "ScopedLocalRef.h"
 
 namespace art {
diff --git a/runtime/method_helper-inl.h b/runtime/method_helper-inl.h
new file mode 100644
index 0000000..4f95a28
--- /dev/null
+++ b/runtime/method_helper-inl.h
@@ -0,0 +1,62 @@
+/*
+ * 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_METHOD_HELPER_INL_H_
+#define ART_RUNTIME_METHOD_HELPER_INL_H_
+
+#include "method_helper.h"
+
+#include "class_linker.h"
+#include "mirror/object_array.h"
+#include "runtime.h"
+#include "thread-inl.h"
+
+namespace art {
+
+inline mirror::Class* MethodHelper::GetClassFromTypeIdx(uint16_t type_idx, bool resolve) {
+  mirror::ArtMethod* method = GetMethod();
+  mirror::Class* type = method->GetDexCacheResolvedTypes()->Get(type_idx);
+  if (type == nullptr && resolve) {
+    type = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
+    CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
+  }
+  return type;
+}
+
+inline mirror::Class* MethodHelper::GetReturnType(bool resolve) {
+  mirror::ArtMethod* method = GetMethod();
+  const DexFile* dex_file = method->GetDexFile();
+  const DexFile::MethodId& method_id = dex_file->GetMethodId(method->GetDexMethodIndex());
+  const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id);
+  uint16_t return_type_idx = proto_id.return_type_idx_;
+  return GetClassFromTypeIdx(return_type_idx, resolve);
+}
+
+inline mirror::String* MethodHelper::ResolveString(uint32_t string_idx) {
+  mirror::ArtMethod* method = GetMethod();
+  mirror::String* s = method->GetDexCacheStrings()->Get(string_idx);
+  if (UNLIKELY(s == nullptr)) {
+    StackHandleScope<1> hs(Thread::Current());
+    Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
+    s = Runtime::Current()->GetClassLinker()->ResolveString(*method->GetDexFile(), string_idx,
+                                                            dex_cache);
+  }
+  return s;
+}
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_METHOD_HELPER_INL_H_
diff --git a/runtime/method_helper.cc b/runtime/method_helper.cc
new file mode 100644
index 0000000..1bd2f90
--- /dev/null
+++ b/runtime/method_helper.cc
@@ -0,0 +1,153 @@
+/*
+ * 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 "method_helper-inl.h"
+
+#include "class_linker.h"
+#include "dex_file-inl.h"
+#include "handle_scope-inl.h"
+#include "mirror/art_method-inl.h"
+#include "mirror/dex_cache.h"
+#include "runtime.h"
+
+namespace art {
+
+mirror::String* MethodHelper::GetNameAsString(Thread* self) {
+  const DexFile* dex_file = method_->GetDexFile();
+  mirror::ArtMethod* method = method_->GetInterfaceMethodIfProxy();
+  uint32_t dex_method_idx = method->GetDexMethodIndex();
+  const DexFile::MethodId& method_id = dex_file->GetMethodId(dex_method_idx);
+  StackHandleScope<1> hs(self);
+  Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
+  return Runtime::Current()->GetClassLinker()->ResolveString(*dex_file, method_id.name_idx_,
+                                                             dex_cache);
+}
+
+bool MethodHelper::HasSameNameAndSignature(MethodHelper* other) {
+  const DexFile* dex_file = method_->GetDexFile();
+  const DexFile::MethodId& mid = dex_file->GetMethodId(GetMethod()->GetDexMethodIndex());
+  if (method_->GetDexCache() == other->method_->GetDexCache()) {
+    const DexFile::MethodId& other_mid =
+        dex_file->GetMethodId(other->GetMethod()->GetDexMethodIndex());
+    return mid.name_idx_ == other_mid.name_idx_ && mid.proto_idx_ == other_mid.proto_idx_;
+  }
+  const DexFile* other_dex_file = other->method_->GetDexFile();
+  const DexFile::MethodId& other_mid =
+      other_dex_file->GetMethodId(other->GetMethod()->GetDexMethodIndex());
+  if (!DexFileStringEquals(dex_file, mid.name_idx_, other_dex_file, other_mid.name_idx_)) {
+    return false;  // Name mismatch.
+  }
+  return dex_file->GetMethodSignature(mid) == other_dex_file->GetMethodSignature(other_mid);
+}
+
+bool MethodHelper::HasSameSignatureWithDifferentClassLoaders(MethodHelper* other) {
+  if (UNLIKELY(GetReturnType() != other->GetReturnType())) {
+    return false;
+  }
+  const DexFile::TypeList* types = method_->GetParameterTypeList();
+  const DexFile::TypeList* other_types = other->method_->GetParameterTypeList();
+  if (types == nullptr) {
+    return (other_types == nullptr) || (other_types->Size() == 0);
+  } else if (UNLIKELY(other_types == nullptr)) {
+    return types->Size() == 0;
+  }
+  uint32_t num_types = types->Size();
+  if (UNLIKELY(num_types != other_types->Size())) {
+    return false;
+  }
+  for (uint32_t i = 0; i < num_types; ++i) {
+    mirror::Class* param_type = GetClassFromTypeIdx(types->GetTypeItem(i).type_idx_);
+    mirror::Class* other_param_type =
+        other->GetClassFromTypeIdx(other_types->GetTypeItem(i).type_idx_);
+    if (UNLIKELY(param_type != other_param_type)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+uint32_t MethodHelper::FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  mirror::ArtMethod* method = GetMethod();
+  const DexFile* dexfile = method->GetDexFile();
+  if (dexfile == &other_dexfile) {
+    return method->GetDexMethodIndex();
+  }
+  const DexFile::MethodId& mid = dexfile->GetMethodId(method->GetDexMethodIndex());
+  const char* mid_declaring_class_descriptor = dexfile->StringByTypeIdx(mid.class_idx_);
+  const DexFile::StringId* other_descriptor =
+      other_dexfile.FindStringId(mid_declaring_class_descriptor);
+  if (other_descriptor != nullptr) {
+    const DexFile::TypeId* other_type_id =
+        other_dexfile.FindTypeId(other_dexfile.GetIndexForStringId(*other_descriptor));
+    if (other_type_id != nullptr) {
+      const char* mid_name = dexfile->GetMethodName(mid);
+      const DexFile::StringId* other_name = other_dexfile.FindStringId(mid_name);
+      if (other_name != nullptr) {
+        uint16_t other_return_type_idx;
+        std::vector<uint16_t> other_param_type_idxs;
+        bool success = other_dexfile.CreateTypeList(
+            dexfile->GetMethodSignature(mid).ToString(), &other_return_type_idx,
+            &other_param_type_idxs);
+        if (success) {
+          const DexFile::ProtoId* other_sig =
+              other_dexfile.FindProtoId(other_return_type_idx, other_param_type_idxs);
+          if (other_sig != nullptr) {
+            const  DexFile::MethodId* other_mid = other_dexfile.FindMethodId(
+                *other_type_id, *other_name, *other_sig);
+            if (other_mid != nullptr) {
+              return other_dexfile.GetIndexForMethodId(*other_mid);
+            }
+          }
+        }
+      }
+    }
+  }
+  return DexFile::kDexNoIndex;
+}
+
+uint32_t MethodHelper::FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile,
+                                                        uint32_t name_and_signature_idx)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  mirror::ArtMethod* method = GetMethod();
+  const DexFile* dexfile = method->GetDexFile();
+  const uint32_t dex_method_idx = method->GetDexMethodIndex();
+  const DexFile::MethodId& mid = dexfile->GetMethodId(dex_method_idx);
+  const DexFile::MethodId& name_and_sig_mid = other_dexfile.GetMethodId(name_and_signature_idx);
+  DCHECK_STREQ(dexfile->GetMethodName(mid), other_dexfile.GetMethodName(name_and_sig_mid));
+  DCHECK_EQ(dexfile->GetMethodSignature(mid), other_dexfile.GetMethodSignature(name_and_sig_mid));
+  if (dexfile == &other_dexfile) {
+    return dex_method_idx;
+  }
+  const char* mid_declaring_class_descriptor = dexfile->StringByTypeIdx(mid.class_idx_);
+  const DexFile::StringId* other_descriptor =
+      other_dexfile.FindStringId(mid_declaring_class_descriptor);
+  if (other_descriptor != nullptr) {
+    const DexFile::TypeId* other_type_id =
+        other_dexfile.FindTypeId(other_dexfile.GetIndexForStringId(*other_descriptor));
+    if (other_type_id != nullptr) {
+      const DexFile::MethodId* other_mid = other_dexfile.FindMethodId(
+          *other_type_id, other_dexfile.GetStringId(name_and_sig_mid.name_idx_),
+          other_dexfile.GetProtoId(name_and_sig_mid.proto_idx_));
+      if (other_mid != nullptr) {
+        return other_dexfile.GetIndexForMethodId(*other_mid);
+      }
+    }
+  }
+  return DexFile::kDexNoIndex;
+}
+
+}  // namespace art
diff --git a/runtime/method_helper.h b/runtime/method_helper.h
new file mode 100644
index 0000000..62465be
--- /dev/null
+++ b/runtime/method_helper.h
@@ -0,0 +1,143 @@
+/*
+ * 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_METHOD_HELPER_H_
+#define ART_RUNTIME_METHOD_HELPER_H_
+
+#include "base/macros.h"
+#include "handle.h"
+#include "mirror/art_method.h"
+#include "primitive.h"
+
+namespace art {
+
+class MethodHelper {
+ public:
+  explicit MethodHelper(Handle<mirror::ArtMethod> m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+      : method_(m), shorty_(nullptr), shorty_len_(0) {
+    SetMethod(m.Get());
+  }
+
+  void ChangeMethod(mirror::ArtMethod* new_m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    DCHECK(new_m != nullptr);
+    SetMethod(new_m);
+    shorty_ = nullptr;
+  }
+
+  mirror::ArtMethod* GetMethod() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    return method_->GetInterfaceMethodIfProxy();
+  }
+
+  mirror::String* GetNameAsString(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  const char* GetShorty() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    const char* result = shorty_;
+    if (result == nullptr) {
+      result = method_->GetShorty(&shorty_len_);
+      shorty_ = result;
+    }
+    return result;
+  }
+
+  uint32_t GetShortyLength() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    if (shorty_ == nullptr) {
+      GetShorty();
+    }
+    return shorty_len_;
+  }
+
+  // Counts the number of references in the parameter list of the corresponding method.
+  // Note: Thus does _not_ include "this" for non-static methods.
+  uint32_t GetNumberOfReferenceArgsWithoutReceiver() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    const char* shorty = GetShorty();
+    uint32_t refs = 0;
+    for (uint32_t i = 1; i < shorty_len_ ; ++i) {
+      if (shorty[i] == 'L') {
+        refs++;
+      }
+    }
+
+    return refs;
+  }
+
+  // May cause thread suspension due to GetClassFromTypeIdx calling ResolveType this caused a large
+  // number of bugs at call sites.
+  mirror::Class* GetReturnType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  size_t NumArgs() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    // "1 +" because the first in Args is the receiver.
+    // "- 1" because we don't count the return type.
+    return (method_->IsStatic() ? 0 : 1) + GetShortyLength() - 1;
+  }
+
+  // Get the primitive type associated with the given parameter.
+  Primitive::Type GetParamPrimitiveType(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    CHECK_LT(param, NumArgs());
+    if (GetMethod()->IsStatic()) {
+      param++;  // 0th argument must skip return value at start of the shorty
+    } else if (param == 0) {
+      return Primitive::kPrimNot;
+    }
+    return Primitive::GetType(GetShorty()[param]);
+  }
+
+  // Is the specified parameter a long or double, where parameter 0 is 'this' for instance methods.
+  bool IsParamALongOrDouble(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    Primitive::Type type = GetParamPrimitiveType(param);
+    return type == Primitive::kPrimLong || type == Primitive::kPrimDouble;
+  }
+
+  // Is the specified parameter a reference, where parameter 0 is 'this' for instance methods.
+  bool IsParamAReference(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    return GetParamPrimitiveType(param) == Primitive::kPrimNot;
+  }
+
+  bool HasSameNameAndSignature(MethodHelper* other) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  bool HasSameSignatureWithDifferentClassLoaders(MethodHelper* other)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  mirror::Class* GetClassFromTypeIdx(uint16_t type_idx, bool resolve = true)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  mirror::String* ResolveString(uint32_t string_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  uint32_t FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  // The name_and_signature_idx MUST point to a MethodId with the same name and signature in the
+  // other_dexfile, such as the method index used to resolve this method in the other_dexfile.
+  uint32_t FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile,
+                                            uint32_t name_and_signature_idx)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ private:
+  // Set the method_ field, for proxy methods looking up the interface method via the resolved
+  // methods table.
+  void SetMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    method_.Assign(method);
+  }
+
+  Handle<mirror::ArtMethod> method_;
+  const char* shorty_;
+  uint32_t shorty_len_;
+
+  DISALLOW_COPY_AND_ASSIGN(MethodHelper);
+};
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_METHOD_HELPER_H_
diff --git a/runtime/mirror/array.cc b/runtime/mirror/array.cc
index f7b5737..63f9860 100644
--- a/runtime/mirror/array.cc
+++ b/runtime/mirror/array.cc
@@ -25,7 +25,6 @@
 #include "object-inl.h"
 #include "object_array.h"
 #include "object_array-inl.h"
-#include "object_utils.h"
 #include "handle_scope-inl.h"
 #include "thread.h"
 #include "utils.h"
diff --git a/runtime/mirror/art_field-inl.h b/runtime/mirror/art_field-inl.h
index 90247ed..00bed92 100644
--- a/runtime/mirror/art_field-inl.h
+++ b/runtime/mirror/art_field-inl.h
@@ -20,10 +20,10 @@
 #include "art_field.h"
 
 #include "base/logging.h"
+#include "dex_cache.h"
 #include "gc/accounting/card_table-inl.h"
 #include "jvalue.h"
 #include "object-inl.h"
-#include "object_utils.h"
 #include "primitive.h"
 
 namespace art {
diff --git a/runtime/mirror/art_field.cc b/runtime/mirror/art_field.cc
index f2729f6..da21dfe 100644
--- a/runtime/mirror/art_field.cc
+++ b/runtime/mirror/art_field.cc
@@ -20,7 +20,6 @@
 #include "gc/accounting/card_table-inl.h"
 #include "object-inl.h"
 #include "object_array-inl.h"
-#include "object_utils.h"
 #include "runtime.h"
 #include "scoped_thread_state_change.h"
 #include "utils.h"
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index a5b5df6..01b05a6 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -19,11 +19,13 @@
 
 #include "art_method.h"
 
+#include "class_linker.h"
+#include "dex_cache.h"
 #include "dex_file.h"
 #include "entrypoints/entrypoint_utils.h"
+#include "method_helper.h"
 #include "object-inl.h"
 #include "object_array.h"
-#include "object_utils.h"
 #include "oat.h"
 #include "quick/quick_method_frame_info.h"
 #include "read_barrier-inl.h"
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index 1fa680d..167f848 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -16,6 +16,7 @@
 
 #include "art_method.h"
 
+#include "arch/context.h"
 #include "art_field-inl.h"
 #include "art_method-inl.h"
 #include "base/stringpiece.h"
@@ -26,12 +27,12 @@
 #include "interpreter/interpreter.h"
 #include "jni_internal.h"
 #include "mapping_table.h"
-#include "object-inl.h"
-#include "object_array.h"
+#include "method_helper.h"
 #include "object_array-inl.h"
+#include "object_array.h"
+#include "object-inl.h"
 #include "scoped_thread_state_change.h"
 #include "string.h"
-#include "object_utils.h"
 #include "well_known_classes.h"
 
 namespace art {
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 349d4a3..329a984 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -30,6 +30,7 @@
 #include "iftable.h"
 #include "object_array-inl.h"
 #include "read_barrier-inl.h"
+#include "reference-inl.h"
 #include "runtime.h"
 #include "string.h"
 
@@ -591,6 +592,11 @@
   return this == ArtMethod::GetJavaLangReflectArtMethod<kReadBarrierOption>();
 }
 
+template<ReadBarrierOption kReadBarrierOption>
+inline bool Class::IsReferenceClass() const {
+  return this == Reference::GetJavaLangRefReference<kReadBarrierOption>();
+}
+
 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
 inline bool Class::IsClassClass() {
   Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
@@ -642,6 +648,30 @@
   return GetFieldObject<ObjectArray<ObjectArray<Class>>>(field_offset);
 }
 
+inline MemberOffset Class::GetDisableIntrinsicFlagOffset() {
+  CHECK(IsReferenceClass());
+  // First static field
+  DCHECK(GetSFields()->Get(0)->IsArtField());
+  DCHECK_STREQ(GetSFields()->Get(0)->GetName(), "disableIntrinsic");
+  return GetSFields()->Get(0)->GetOffset();
+}
+
+inline MemberOffset Class::GetSlowPathFlagOffset() {
+  CHECK(IsReferenceClass());
+  // Second static field
+  DCHECK(GetSFields()->Get(1)->IsArtField());
+  DCHECK_STREQ(GetSFields()->Get(1)->GetName(), "slowPathEnabled");
+  return GetSFields()->Get(1)->GetOffset();
+}
+
+inline bool Class::GetSlowPathEnabled() {
+  return GetField32(GetSlowPathFlagOffset());
+}
+
+inline void Class::SetSlowPath(bool enabled) {
+  SetField32<false>(GetSlowPathFlagOffset(), enabled);
+}
+
 inline void Class::InitializeClassVisitor::operator()(
     mirror::Object* obj, size_t usable_size) const {
   DCHECK_LE(class_size_, usable_size);
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index be05fb8..fadf80e 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -18,17 +18,16 @@
 
 #include "art_field-inl.h"
 #include "art_method-inl.h"
-#include "class-inl.h"
 #include "class_linker.h"
 #include "class_loader.h"
+#include "class-inl.h"
 #include "dex_cache.h"
 #include "dex_file-inl.h"
 #include "gc/accounting/card_table-inl.h"
-#include "object-inl.h"
-#include "object_array-inl.h"
-#include "object_utils.h"
-#include "runtime.h"
 #include "handle_scope-inl.h"
+#include "object_array-inl.h"
+#include "object-inl.h"
+#include "runtime.h"
 #include "thread.h"
 #include "throwable.h"
 #include "utils.h"
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 0f42044..648bdde 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -261,7 +261,7 @@
   }
 
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
-  bool IsReferenceClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  bool IsTypeOfReferenceClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return (GetAccessFlags<kVerifyFlags>() & kAccClassIsReference) != 0;
   }
 
@@ -419,6 +419,9 @@
   template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
   bool IsArtMethodClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
+  template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+  bool IsReferenceClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
   static MemberOffset ComponentTypeOffset() {
     return OFFSET_OF_OBJECT_MEMBER(Class, component_type_);
   }
@@ -976,6 +979,12 @@
   // For proxy class only.
   ObjectArray<ObjectArray<Class>>* GetThrows() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
+  // For reference class only.
+  MemberOffset GetDisableIntrinsicFlagOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  MemberOffset GetSlowPathFlagOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  bool GetSlowPathEnabled() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void SetSlowPath(bool enabled) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
   // Used to initialize a class in the allocation code path to ensure it is guarded by a StoreStore
   // fence.
   class InitializeClassVisitor {
diff --git a/runtime/mirror/dex_cache_test.cc b/runtime/mirror/dex_cache_test.cc
index 3d28dc6..ef6fc67 100644
--- a/runtime/mirror/dex_cache_test.cc
+++ b/runtime/mirror/dex_cache_test.cc
@@ -24,6 +24,7 @@
 #include "mirror/object_array-inl.h"
 #include "mirror/object-inl.h"
 #include "handle_scope-inl.h"
+#include "scoped_thread_state_change.h"
 
 namespace art {
 namespace mirror {
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index 3d45683..9dbfb56 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -249,7 +249,7 @@
 
 template<VerifyObjectFlags kVerifyFlags>
 inline bool Object::IsReferenceInstance() {
-  return GetClass<kVerifyFlags>()->IsReferenceClass();
+  return GetClass<kVerifyFlags>()->IsTypeOfReferenceClass();
 }
 
 template<VerifyObjectFlags kVerifyFlags>
@@ -806,7 +806,7 @@
   } else {
     DCHECK(!klass->IsVariableSize());
     VisitInstanceFieldsReferences<kVisitClass>(klass, visitor);
-    if (UNLIKELY(klass->IsReferenceClass<kVerifyNone>())) {
+    if (UNLIKELY(klass->IsTypeOfReferenceClass<kVerifyNone>())) {
       ref_visitor(klass, AsReference());
     }
   }
diff --git a/runtime/mirror/object.cc b/runtime/mirror/object.cc
index 5f88d54f..961bc64 100644
--- a/runtime/mirror/object.cc
+++ b/runtime/mirror/object.cc
@@ -24,13 +24,13 @@
 #include "class.h"
 #include "class-inl.h"
 #include "class_linker-inl.h"
+#include "field_helper.h"
 #include "gc/accounting/card_table-inl.h"
 #include "gc/heap.h"
 #include "iftable-inl.h"
 #include "monitor.h"
 #include "object-inl.h"
 #include "object_array-inl.h"
-#include "object_utils.h"
 #include "runtime.h"
 #include "handle_scope-inl.h"
 #include "throwable.h"
@@ -57,7 +57,7 @@
       ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     // Copy java.lang.ref.Reference.referent which isn't visited in
     // Object::VisitReferences().
-    DCHECK(klass->IsReferenceClass());
+    DCHECK(klass->IsTypeOfReferenceClass());
     this->operator()(ref, mirror::Reference::ReferentOffset(), false);
   }
 
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index 7e1de5d..a7ea6c9 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -36,6 +36,7 @@
 #include "object-inl.h"
 #include "object_array-inl.h"
 #include "handle_scope-inl.h"
+#include "scoped_thread_state_change.h"
 #include "string-inl.h"
 
 namespace art {
diff --git a/runtime/mirror/reference-inl.h b/runtime/mirror/reference-inl.h
index 43767c8..b353402 100644
--- a/runtime/mirror/reference-inl.h
+++ b/runtime/mirror/reference-inl.h
@@ -22,6 +22,11 @@
 namespace art {
 namespace mirror {
 
+inline uint32_t Reference::ClassSize() {
+  uint32_t vtable_entries = Object::kVTableLength + 5;
+  return Class::ComputeClassSize(false, vtable_entries, 2, 0, 0);
+}
+
 inline bool Reference::IsEnqueuable() {
   // Not using volatile reads as an optimization since this is only called with all the mutators
   // suspended.
diff --git a/runtime/mirror/reference.cc b/runtime/mirror/reference.cc
new file mode 100644
index 0000000..077cd4b
--- /dev/null
+++ b/runtime/mirror/reference.cc
@@ -0,0 +1,43 @@
+/*
+ * 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 "reference.h"
+
+namespace art {
+namespace mirror {
+
+Class* Reference::java_lang_ref_Reference_ = nullptr;
+
+void Reference::SetClass(Class* java_lang_ref_Reference) {
+  CHECK(java_lang_ref_Reference_ == nullptr);
+  CHECK(java_lang_ref_Reference != nullptr);
+  java_lang_ref_Reference_ = java_lang_ref_Reference;
+}
+
+void Reference::ResetClass() {
+  CHECK(java_lang_ref_Reference_ != nullptr);
+  java_lang_ref_Reference_ = nullptr;
+}
+
+void Reference::VisitRoots(RootCallback* callback, void* arg) {
+  if (java_lang_ref_Reference_ != nullptr) {
+    callback(reinterpret_cast<mirror::Object**>(&java_lang_ref_Reference_),
+             arg, 0, kRootStickyClass);
+  }
+}
+
+}  // namespace mirror
+}  // namespace art
diff --git a/runtime/mirror/reference.h b/runtime/mirror/reference.h
index 9c9d87b..07d47d3 100644
--- a/runtime/mirror/reference.h
+++ b/runtime/mirror/reference.h
@@ -17,7 +17,11 @@
 #ifndef ART_RUNTIME_MIRROR_REFERENCE_H_
 #define ART_RUNTIME_MIRROR_REFERENCE_H_
 
+#include "class.h"
 #include "object.h"
+#include "object_callbacks.h"
+#include "read_barrier.h"
+#include "thread.h"
 
 namespace art {
 
@@ -36,6 +40,14 @@
 // C++ mirror of java.lang.ref.Reference
 class MANAGED Reference : public Object {
  public:
+  // Size of java.lang.ref.Reference.class.
+  static uint32_t ClassSize();
+
+  // Size of an instance of java.lang.ref.Reference.
+  static constexpr uint32_t InstanceSize() {
+    return sizeof(Reference);
+  }
+
   static MemberOffset PendingNextOffset() {
     return OFFSET_OF_OBJECT_MEMBER(Reference, pending_next_);
   }
@@ -80,6 +92,16 @@
 
   bool IsEnqueuable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
+  template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+  static Class* GetJavaLangRefReference() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    DCHECK(java_lang_ref_Reference_ != nullptr);
+    return ReadBarrier::BarrierForRoot<mirror::Class, kReadBarrierOption>(
+        &java_lang_ref_Reference_);
+  }
+  static void SetClass(Class* klass);
+  static void ResetClass(void);
+  static void VisitRoots(RootCallback* callback, void* arg);
+
  private:
   // Note: This avoids a read barrier, it should only be used by the GC.
   HeapReference<Object>* GetReferentReferenceAddr() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -92,6 +114,8 @@
   HeapReference<Reference> queue_next_;  // Note this is Java volatile:
   HeapReference<Object> referent_;  // Note this is Java volatile:
 
+  static Class* java_lang_ref_Reference_;
+
   friend struct art::ReferenceOffsets;  // for verifying offset information
   friend class gc::ReferenceProcessor;
   friend class gc::ReferenceQueue;
diff --git a/runtime/mirror/string.h b/runtime/mirror/string.h
index 8ab4db9..46bdd59 100644
--- a/runtime/mirror/string.h
+++ b/runtime/mirror/string.h
@@ -19,6 +19,7 @@
 
 #include <gtest/gtest.h>
 
+#include "object.h"
 #include "object_callbacks.h"
 #include "read_barrier.h"
 
diff --git a/runtime/mirror/throwable.cc b/runtime/mirror/throwable.cc
index 6efc9e2..1c3f1ed 100644
--- a/runtime/mirror/throwable.cc
+++ b/runtime/mirror/throwable.cc
@@ -23,7 +23,6 @@
 #include "object-inl.h"
 #include "object_array.h"
 #include "object_array-inl.h"
-#include "object_utils.h"
 #include "stack_trace_element.h"
 #include "utils.h"
 #include "well_known_classes.h"
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index 5633a77..4b26eda 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -28,7 +28,6 @@
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
-#include "object_utils.h"
 #include "scoped_thread_state_change.h"
 #include "thread.h"
 #include "thread_list.h"
@@ -746,7 +745,11 @@
           contention_count++;
           Runtime* runtime = Runtime::Current();
           if (contention_count <= runtime->GetMaxSpinsBeforeThinkLockInflation()) {
-            NanoSleep(1000);  // Sleep for 1us and re-attempt.
+            // TODO: Consider switch thread state to kBlocked when we are yielding.
+            // Use sched_yield instead of NanoSleep since NanoSleep can wait much longer than the
+            // parameter you pass in. This can cause thread suspension to take excessively long
+            // make long pauses. See b/16307460.
+            sched_yield();
           } else {
             contention_count = 0;
             InflateThinLocked(self, h_obj, lock_word, 0);
diff --git a/runtime/monitor_pool_test.cc b/runtime/monitor_pool_test.cc
index cddc245..e1837f5 100644
--- a/runtime/monitor_pool_test.cc
+++ b/runtime/monitor_pool_test.cc
@@ -17,6 +17,8 @@
 #include "monitor_pool.h"
 
 #include "common_runtime_test.h"
+#include "scoped_thread_state_change.h"
+#include "thread-inl.h"
 
 namespace art {
 
diff --git a/runtime/monitor_test.cc b/runtime/monitor_test.cc
index bdba494..af24368 100644
--- a/runtime/monitor_test.cc
+++ b/runtime/monitor_test.cc
@@ -24,6 +24,7 @@
 #include "handle_scope-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/string-inl.h"  // Strings are easiest to allocate
+#include "scoped_thread_state_change.h"
 #include "thread_pool.h"
 #include "utils.h"
 
@@ -31,7 +32,7 @@
 
 class MonitorTest : public CommonRuntimeTest {
  protected:
-  void SetUpRuntimeOptions(Runtime::Options *options) OVERRIDE {
+  void SetUpRuntimeOptions(RuntimeOptions *options) OVERRIDE {
     // Use a smaller heap
     for (std::pair<std::string, const void*>& pair : *options) {
       if (pair.first.find("-Xmx") == 0) {
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index f1a987f..b0b64aa 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -30,7 +30,6 @@
 #include "mirror/class-inl.h"
 #include "mirror/dex_cache-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "runtime.h"
 #include "scoped_fast_native_object_access.h"
 #include "scoped_thread_state_change.h"
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index cede1a0..e577c2c 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -21,7 +21,6 @@
 #include "mirror/class-inl.h"
 #include "mirror/class_loader.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "scoped_thread_state_change.h"
 #include "scoped_fast_native_object_access.h"
 #include "ScopedLocalRef.h"
diff --git a/runtime/native/java_lang_reflect_Array.cc b/runtime/native/java_lang_reflect_Array.cc
index eae4584..f94e42b 100644
--- a/runtime/native/java_lang_reflect_Array.cc
+++ b/runtime/native/java_lang_reflect_Array.cc
@@ -20,7 +20,6 @@
 #include "jni_internal.h"
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "scoped_fast_native_object_access.h"
 #include "handle_scope-inl.h"
 
diff --git a/runtime/native/java_lang_reflect_Constructor.cc b/runtime/native/java_lang_reflect_Constructor.cc
index 1981bfd..34cb93a 100644
--- a/runtime/native/java_lang_reflect_Constructor.cc
+++ b/runtime/native/java_lang_reflect_Constructor.cc
@@ -20,7 +20,6 @@
 #include "mirror/art_method-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "reflection.h"
 #include "scoped_fast_native_object_access.h"
 #include "well_known_classes.h"
diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc
index 3564dfdf..3903ffc 100644
--- a/runtime/native/java_lang_reflect_Field.cc
+++ b/runtime/native/java_lang_reflect_Field.cc
@@ -18,11 +18,11 @@
 #include "class_linker-inl.h"
 #include "common_throws.h"
 #include "dex_file-inl.h"
+#include "field_helper.h"
 #include "jni_internal.h"
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class-inl.h"
-#include "object_utils.h"
 #include "reflection.h"
 #include "scoped_fast_native_object_access.h"
 
diff --git a/runtime/native/java_lang_reflect_Method.cc b/runtime/native/java_lang_reflect_Method.cc
index ac602ac..f029b16 100644
--- a/runtime/native/java_lang_reflect_Method.cc
+++ b/runtime/native/java_lang_reflect_Method.cc
@@ -21,7 +21,6 @@
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
-#include "object_utils.h"
 #include "reflection.h"
 #include "scoped_fast_native_object_access.h"
 #include "well_known_classes.h"
diff --git a/runtime/noop_compiler_callbacks.h b/runtime/noop_compiler_callbacks.h
index 702b2e1..65498de 100644
--- a/runtime/noop_compiler_callbacks.h
+++ b/runtime/noop_compiler_callbacks.h
@@ -25,10 +25,15 @@
  public:
   NoopCompilerCallbacks() {}
   ~NoopCompilerCallbacks() {}
+
   bool MethodVerified(verifier::MethodVerifier* verifier) OVERRIDE {
     return true;
   }
+
   void ClassRejected(ClassReference ref) OVERRIDE {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NoopCompilerCallbacks);
 };
 
 }  // namespace art
diff --git a/runtime/object_lock.cc b/runtime/object_lock.cc
new file mode 100644
index 0000000..f7accc0
--- /dev/null
+++ b/runtime/object_lock.cc
@@ -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.
+ */
+
+#include "object_lock.h"
+
+#include "mirror/object-inl.h"
+#include "monitor.h"
+
+namespace art {
+
+template <typename T>
+ObjectLock<T>::ObjectLock(Thread* self, Handle<T> object) : self_(self), obj_(object) {
+  CHECK(object.Get() != nullptr);
+  obj_->MonitorEnter(self_);
+}
+
+template <typename T>
+ObjectLock<T>::~ObjectLock() {
+  obj_->MonitorExit(self_);
+}
+
+template <typename T>
+void ObjectLock<T>::WaitIgnoringInterrupts() {
+  Monitor::Wait(self_, obj_.Get(), 0, 0, false, kWaiting);
+}
+
+template <typename T>
+void ObjectLock<T>::Notify() {
+  obj_->Notify(self_);
+}
+
+template <typename T>
+void ObjectLock<T>::NotifyAll() {
+  obj_->NotifyAll(self_);
+}
+
+template class ObjectLock<mirror::Class>;
+template class ObjectLock<mirror::Object>;
+
+}  // namespace art
diff --git a/runtime/object_lock.h b/runtime/object_lock.h
new file mode 100644
index 0000000..acddc03
--- /dev/null
+++ b/runtime/object_lock.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_OBJECT_LOCK_H_
+#define ART_RUNTIME_OBJECT_LOCK_H_
+
+#include "base/macros.h"
+#include "base/mutex.h"
+#include "handle.h"
+
+namespace art {
+
+class Thread;
+
+template <typename T>
+class ObjectLock {
+ public:
+  ObjectLock(Thread* self, Handle<T> object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  ~ObjectLock() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  void WaitIgnoringInterrupts() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  void Notify() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  void NotifyAll() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ private:
+  Thread* const self_;
+  Handle<T> const obj_;
+
+  DISALLOW_COPY_AND_ASSIGN(ObjectLock);
+};
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_OBJECT_LOCK_H_
diff --git a/runtime/object_utils.h b/runtime/object_utils.h
deleted file mode 100644
index 4379b4a..0000000
--- a/runtime/object_utils.h
+++ /dev/null
@@ -1,379 +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_OBJECT_UTILS_H_
-#define ART_RUNTIME_OBJECT_UTILS_H_
-
-#include "class_linker.h"
-#include "dex_file.h"
-#include "monitor.h"
-#include "mirror/art_field.h"
-#include "mirror/art_method.h"
-#include "mirror/class.h"
-#include "mirror/dex_cache.h"
-#include "mirror/iftable.h"
-#include "mirror/string.h"
-
-#include "runtime.h"
-#include "handle_scope-inl.h"
-
-#include <string>
-
-namespace art {
-
-template <typename T>
-class ObjectLock {
- public:
-  ObjectLock(Thread* self, Handle<T> object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-      : self_(self), obj_(object) {
-    CHECK(object.Get() != nullptr);
-    obj_->MonitorEnter(self_);
-  }
-
-  ~ObjectLock() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    obj_->MonitorExit(self_);
-  }
-
-  void WaitIgnoringInterrupts() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    Monitor::Wait(self_, obj_.Get(), 0, 0, false, kWaiting);
-  }
-
-  void Notify() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    obj_->Notify(self_);
-  }
-
-  void NotifyAll() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    obj_->NotifyAll(self_);
-  }
-
- private:
-  Thread* const self_;
-  Handle<T> const obj_;
-  DISALLOW_COPY_AND_ASSIGN(ObjectLock);
-};
-
-class FieldHelper {
- public:
-  explicit FieldHelper(Handle<mirror::ArtField> f) : field_(f) {}
-
-  void ChangeField(mirror::ArtField* new_f) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    DCHECK(new_f != nullptr);
-    field_.Assign(new_f);
-  }
-
-  mirror::ArtField* GetField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return field_.Get();
-  }
-
-  mirror::Class* GetType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    uint32_t field_index = field_->GetDexFieldIndex();
-    if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
-      return Runtime::Current()->GetClassLinker()->FindSystemClass(Thread::Current(),
-                                                                   field_->GetTypeDescriptor());
-    }
-    const DexFile* dex_file = field_->GetDexFile();
-    const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index);
-    mirror::Class* type = field_->GetDexCache()->GetResolvedType(field_id.type_idx_);
-    if (resolve && (type == nullptr)) {
-      type = Runtime::Current()->GetClassLinker()->ResolveType(field_id.type_idx_, field_.Get());
-      CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
-    }
-    return type;
-  }
-
-  // The returned const char* is only guaranteed to be valid for the lifetime of the FieldHelper.
-  // If you need it longer, copy it into a std::string.
-  const char* GetDeclaringClassDescriptor()
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    uint32_t field_index = field_->GetDexFieldIndex();
-    if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
-      DCHECK(field_->IsStatic());
-      DCHECK_LT(field_index, 2U);
-      // 0 == Class[] interfaces; 1 == Class[][] throws;
-      declaring_class_descriptor_ = field_->GetDeclaringClass()->GetDescriptor();
-      return declaring_class_descriptor_.c_str();
-    }
-    const DexFile* dex_file = field_->GetDexFile();
-    const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index);
-    return dex_file->GetFieldDeclaringClassDescriptor(field_id);
-  }
-
- private:
-  Handle<mirror::ArtField> field_;
-  std::string declaring_class_descriptor_;
-
-  DISALLOW_COPY_AND_ASSIGN(FieldHelper);
-};
-
-class MethodHelper {
- public:
-  explicit MethodHelper(Handle<mirror::ArtMethod> m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-      : method_(m), shorty_(nullptr), shorty_len_(0) {
-    SetMethod(m.Get());
-  }
-
-  void ChangeMethod(mirror::ArtMethod* new_m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    DCHECK(new_m != nullptr);
-    SetMethod(new_m);
-    shorty_ = nullptr;
-  }
-
-  mirror::ArtMethod* GetMethod() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return method_->GetInterfaceMethodIfProxy();
-  }
-
-  mirror::String* GetNameAsString(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    const DexFile* dex_file = method_->GetDexFile();
-    mirror::ArtMethod* method = method_->GetInterfaceMethodIfProxy();
-    uint32_t dex_method_idx = method->GetDexMethodIndex();
-    const DexFile::MethodId& method_id = dex_file->GetMethodId(dex_method_idx);
-    StackHandleScope<1> hs(self);
-    Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
-    return Runtime::Current()->GetClassLinker()->ResolveString(*dex_file, method_id.name_idx_,
-                                                               dex_cache);
-  }
-
-  const char* GetShorty() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    const char* result = shorty_;
-    if (result == nullptr) {
-      result = method_->GetShorty(&shorty_len_);
-      shorty_ = result;
-    }
-    return result;
-  }
-
-  uint32_t GetShortyLength() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    if (shorty_ == nullptr) {
-      GetShorty();
-    }
-    return shorty_len_;
-  }
-
-  // Counts the number of references in the parameter list of the corresponding method.
-  // Note: Thus does _not_ include "this" for non-static methods.
-  uint32_t GetNumberOfReferenceArgsWithoutReceiver() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    const char* shorty = GetShorty();
-    uint32_t refs = 0;
-    for (uint32_t i = 1; i < shorty_len_ ; ++i) {
-      if (shorty[i] == 'L') {
-        refs++;
-      }
-    }
-
-    return refs;
-  }
-
-  // May cause thread suspension due to GetClassFromTypeIdx calling ResolveType this caused a large
-  // number of bugs at call sites.
-  mirror::Class* GetReturnType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    mirror::ArtMethod* method = GetMethod();
-    const DexFile* dex_file = method->GetDexFile();
-    const DexFile::MethodId& method_id = dex_file->GetMethodId(method->GetDexMethodIndex());
-    const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id);
-    uint16_t return_type_idx = proto_id.return_type_idx_;
-    return GetClassFromTypeIdx(return_type_idx, resolve);
-  }
-
-  size_t NumArgs() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    // "1 +" because the first in Args is the receiver.
-    // "- 1" because we don't count the return type.
-    return (method_->IsStatic() ? 0 : 1) + GetShortyLength() - 1;
-  }
-
-  // Get the primitive type associated with the given parameter.
-  Primitive::Type GetParamPrimitiveType(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    CHECK_LT(param, NumArgs());
-    if (GetMethod()->IsStatic()) {
-      param++;  // 0th argument must skip return value at start of the shorty
-    } else if (param == 0) {
-      return Primitive::kPrimNot;
-    }
-    return Primitive::GetType(GetShorty()[param]);
-  }
-
-  // Is the specified parameter a long or double, where parameter 0 is 'this' for instance methods.
-  bool IsParamALongOrDouble(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    Primitive::Type type = GetParamPrimitiveType(param);
-    return type == Primitive::kPrimLong || type == Primitive::kPrimDouble;
-  }
-
-  // Is the specified parameter a reference, where parameter 0 is 'this' for instance methods.
-  bool IsParamAReference(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return GetParamPrimitiveType(param) == Primitive::kPrimNot;
-  }
-
-  bool HasSameNameAndSignature(MethodHelper* other) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    const DexFile* dex_file = method_->GetDexFile();
-    const DexFile::MethodId& mid = dex_file->GetMethodId(GetMethod()->GetDexMethodIndex());
-    if (method_->GetDexCache() == other->method_->GetDexCache()) {
-      const DexFile::MethodId& other_mid =
-          dex_file->GetMethodId(other->GetMethod()->GetDexMethodIndex());
-      return mid.name_idx_ == other_mid.name_idx_ && mid.proto_idx_ == other_mid.proto_idx_;
-    }
-    const DexFile* other_dex_file = other->method_->GetDexFile();
-    const DexFile::MethodId& other_mid =
-        other_dex_file->GetMethodId(other->GetMethod()->GetDexMethodIndex());
-    if (!DexFileStringEquals(dex_file, mid.name_idx_, other_dex_file, other_mid.name_idx_)) {
-      return false;  // Name mismatch.
-    }
-    return dex_file->GetMethodSignature(mid) == other_dex_file->GetMethodSignature(other_mid);
-  }
-
-  bool HasSameSignatureWithDifferentClassLoaders(MethodHelper* other)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    if (UNLIKELY(GetReturnType() != other->GetReturnType())) {
-      return false;
-    }
-    const DexFile::TypeList* types = method_->GetParameterTypeList();
-    const DexFile::TypeList* other_types = other->method_->GetParameterTypeList();
-    if (types == nullptr) {
-      return (other_types == nullptr) || (other_types->Size() == 0);
-    } else if (UNLIKELY(other_types == nullptr)) {
-      return types->Size() == 0;
-    }
-    uint32_t num_types = types->Size();
-    if (UNLIKELY(num_types != other_types->Size())) {
-      return false;
-    }
-    for (uint32_t i = 0; i < num_types; ++i) {
-      mirror::Class* param_type = GetClassFromTypeIdx(types->GetTypeItem(i).type_idx_);
-      mirror::Class* other_param_type =
-          other->GetClassFromTypeIdx(other_types->GetTypeItem(i).type_idx_);
-      if (UNLIKELY(param_type != other_param_type)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  mirror::Class* GetClassFromTypeIdx(uint16_t type_idx, bool resolve = true)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    mirror::ArtMethod* method = GetMethod();
-    mirror::Class* type = method->GetDexCacheResolvedTypes()->Get(type_idx);
-    if (type == nullptr && resolve) {
-      type = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
-      CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
-    }
-    return type;
-  }
-
-  mirror::Class* GetDexCacheResolvedType(uint16_t type_idx)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return GetMethod()->GetDexCacheResolvedTypes()->Get(type_idx);
-  }
-
-  mirror::String* ResolveString(uint32_t string_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    mirror::ArtMethod* method = GetMethod();
-    mirror::String* s = method->GetDexCacheStrings()->Get(string_idx);
-    if (UNLIKELY(s == nullptr)) {
-      StackHandleScope<1> hs(Thread::Current());
-      Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
-      s = Runtime::Current()->GetClassLinker()->ResolveString(*method->GetDexFile(), string_idx,
-                                                              dex_cache);
-    }
-    return s;
-  }
-
-  uint32_t FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    mirror::ArtMethod* method = GetMethod();
-    const DexFile* dexfile = method->GetDexFile();
-    if (dexfile == &other_dexfile) {
-      return method->GetDexMethodIndex();
-    }
-    const DexFile::MethodId& mid = dexfile->GetMethodId(method->GetDexMethodIndex());
-    const char* mid_declaring_class_descriptor = dexfile->StringByTypeIdx(mid.class_idx_);
-    const DexFile::StringId* other_descriptor =
-        other_dexfile.FindStringId(mid_declaring_class_descriptor);
-    if (other_descriptor != nullptr) {
-      const DexFile::TypeId* other_type_id =
-          other_dexfile.FindTypeId(other_dexfile.GetIndexForStringId(*other_descriptor));
-      if (other_type_id != nullptr) {
-        const char* mid_name = dexfile->GetMethodName(mid);
-        const DexFile::StringId* other_name = other_dexfile.FindStringId(mid_name);
-        if (other_name != nullptr) {
-          uint16_t other_return_type_idx;
-          std::vector<uint16_t> other_param_type_idxs;
-          bool success = other_dexfile.CreateTypeList(
-              dexfile->GetMethodSignature(mid).ToString(), &other_return_type_idx,
-              &other_param_type_idxs);
-          if (success) {
-            const DexFile::ProtoId* other_sig =
-                other_dexfile.FindProtoId(other_return_type_idx, other_param_type_idxs);
-            if (other_sig != nullptr) {
-              const  DexFile::MethodId* other_mid = other_dexfile.FindMethodId(
-                  *other_type_id, *other_name, *other_sig);
-              if (other_mid != nullptr) {
-                return other_dexfile.GetIndexForMethodId(*other_mid);
-              }
-            }
-          }
-        }
-      }
-    }
-    return DexFile::kDexNoIndex;
-  }
-
-  // The name_and_signature_idx MUST point to a MethodId with the same name and signature in the
-  // other_dexfile, such as the method index used to resolve this method in the other_dexfile.
-  uint32_t FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile,
-                                            uint32_t name_and_signature_idx)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    mirror::ArtMethod* method = GetMethod();
-    const DexFile* dexfile = method->GetDexFile();
-    const uint32_t dex_method_idx = method->GetDexMethodIndex();
-    const DexFile::MethodId& mid = dexfile->GetMethodId(dex_method_idx);
-    const DexFile::MethodId& name_and_sig_mid = other_dexfile.GetMethodId(name_and_signature_idx);
-    DCHECK_STREQ(dexfile->GetMethodName(mid), other_dexfile.GetMethodName(name_and_sig_mid));
-    DCHECK_EQ(dexfile->GetMethodSignature(mid), other_dexfile.GetMethodSignature(name_and_sig_mid));
-    if (dexfile == &other_dexfile) {
-      return dex_method_idx;
-    }
-    const char* mid_declaring_class_descriptor = dexfile->StringByTypeIdx(mid.class_idx_);
-    const DexFile::StringId* other_descriptor =
-        other_dexfile.FindStringId(mid_declaring_class_descriptor);
-    if (other_descriptor != nullptr) {
-      const DexFile::TypeId* other_type_id =
-          other_dexfile.FindTypeId(other_dexfile.GetIndexForStringId(*other_descriptor));
-      if (other_type_id != nullptr) {
-        const DexFile::MethodId* other_mid = other_dexfile.FindMethodId(
-            *other_type_id, other_dexfile.GetStringId(name_and_sig_mid.name_idx_),
-            other_dexfile.GetProtoId(name_and_sig_mid.proto_idx_));
-        if (other_mid != nullptr) {
-          return other_dexfile.GetIndexForMethodId(*other_mid);
-        }
-      }
-    }
-    return DexFile::kDexNoIndex;
-  }
-
- private:
-  // Set the method_ field, for proxy methods looking up the interface method via the resolved
-  // methods table.
-  void SetMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    method_.Assign(method);
-  }
-
-  Handle<mirror::ArtMethod> method_;
-  const char* shorty_;
-  uint32_t shorty_len_;
-
-  DISALLOW_COPY_AND_ASSIGN(MethodHelper);
-};
-
-}  // namespace art
-
-#endif  // ART_RUNTIME_OBJECT_UTILS_H_
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index a016cc5..577691c 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -24,11 +24,13 @@
 #include "debugger.h"
 #include "gc/heap.h"
 #include "monitor.h"
+#include "runtime.h"
+#include "trace.h"
 #include "utils.h"
 
 namespace art {
 
-ParsedOptions* ParsedOptions::Create(const Runtime::Options& options, bool ignore_unrecognized) {
+ParsedOptions* ParsedOptions::Create(const RuntimeOptions& options, bool ignore_unrecognized) {
   std::unique_ptr<ParsedOptions> parsed(new ParsedOptions());
   if (parsed->Parse(options, ignore_unrecognized)) {
     return parsed.release();
@@ -164,7 +166,7 @@
   return true;
 }
 
-bool ParsedOptions::Parse(const Runtime::Options& options, bool ignore_unrecognized) {
+bool ParsedOptions::Parse(const RuntimeOptions& options, bool ignore_unrecognized) {
   const char* boot_class_path_string = getenv("BOOTCLASSPATH");
   if (boot_class_path_string != NULL) {
     boot_class_path_string_ = boot_class_path_string;
@@ -258,7 +260,7 @@
   method_trace_file_ = "/data/method-trace-file.bin";
   method_trace_file_size_ = 10 * MB;
 
-  profile_clock_source_ = kDefaultProfilerClockSource;
+  profile_clock_source_ = kDefaultTraceClockSource;
 
   verify_ = true;
   image_isa_ = kRuntimeISA;
@@ -542,11 +544,11 @@
         return false;
       }
     } else if (option == "-Xprofile:threadcpuclock") {
-      Trace::SetDefaultClockSource(kProfilerClockSourceThreadCpu);
+      Trace::SetDefaultClockSource(kTraceClockSourceThreadCpu);
     } else if (option == "-Xprofile:wallclock") {
-      Trace::SetDefaultClockSource(kProfilerClockSourceWall);
+      Trace::SetDefaultClockSource(kTraceClockSourceWall);
     } else if (option == "-Xprofile:dualclock") {
-      Trace::SetDefaultClockSource(kProfilerClockSourceDual);
+      Trace::SetDefaultClockSource(kTraceClockSourceDual);
     } else if (option == "-Xenable-profiler") {
       profiler_options_.enabled_ = true;
     } else if (StartsWith(option, "-Xprofile-filename:")) {
diff --git a/runtime/parsed_options.h b/runtime/parsed_options.h
index 4c74be6..b1de62a 100644
--- a/runtime/parsed_options.h
+++ b/runtime/parsed_options.h
@@ -18,17 +18,26 @@
 #define ART_RUNTIME_PARSED_OPTIONS_H_
 
 #include <string>
+#include <vector>
 
+#include <jni.h>
+
+#include "globals.h"
 #include "gc/collector_type.h"
-#include "runtime.h"
-#include "trace.h"
+#include "instruction_set.h"
+#include "profiler_options.h"
 
 namespace art {
 
+class CompilerCallbacks;
+class DexFile;
+
+typedef std::vector<std::pair<std::string, const void*>> RuntimeOptions;
+
 class ParsedOptions {
  public:
   // returns null if problem parsing and ignore_unrecognized is false
-  static ParsedOptions* Create(const Runtime::Options& options, bool ignore_unrecognized);
+  static ParsedOptions* Create(const RuntimeOptions& options, bool ignore_unrecognized);
 
   const std::vector<const DexFile*>* boot_class_path_;
   std::string boot_class_path_string_;
@@ -80,7 +89,7 @@
   std::vector<std::string> image_compiler_options_;
   ProfilerOptions profiler_options_;
   std::string profile_output_filename_;
-  ProfilerClockSource profile_clock_source_;
+  TraceClockSource profile_clock_source_;
   bool verify_;
   InstructionSet image_isa_;
 
@@ -105,7 +114,7 @@
   void Exit(int status);
   void Abort();
 
-  bool Parse(const Runtime::Options& options,  bool ignore_unrecognized);
+  bool Parse(const RuntimeOptions& options,  bool ignore_unrecognized);
   bool ParseXGcOption(const std::string& option);
   bool ParseStringAfterChar(const std::string& option, char after_char, std::string* parsed_value);
   bool ParseInteger(const std::string& option, char after_char, int* parsed_value);
diff --git a/runtime/parsed_options_test.cc b/runtime/parsed_options_test.cc
index b58a29c..5154d69 100644
--- a/runtime/parsed_options_test.cc
+++ b/runtime/parsed_options_test.cc
@@ -36,7 +36,7 @@
   boot_class_path += "-Xbootclasspath:";
   boot_class_path += lib_core;
 
-  Runtime::Options options;
+  RuntimeOptions options;
   options.push_back(std::make_pair(boot_class_path.c_str(), null));
   options.push_back(std::make_pair("-classpath", null));
   options.push_back(std::make_pair(lib_core.c_str(), null));
diff --git a/runtime/profiler.cc b/runtime/profiler.cc
index 7a7a92a..9514448 100644
--- a/runtime/profiler.cc
+++ b/runtime/profiler.cc
@@ -32,7 +32,6 @@
 #include "mirror/dex_cache.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "os.h"
 #include "scoped_thread_state_change.h"
 #include "ScopedLocalRef.h"
diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc
index 093c129..bd6656d 100644
--- a/runtime/proxy_test.cc
+++ b/runtime/proxy_test.cc
@@ -14,12 +14,14 @@
  * limitations under the License.
  */
 
-#include "common_compiler_test.h"
-#include "mirror/art_field-inl.h"
-
 #include <jni.h>
 #include <vector>
 
+#include "common_compiler_test.h"
+#include "field_helper.h"
+#include "mirror/art_field-inl.h"
+#include "scoped_thread_state_change.h"
+
 namespace art {
 
 class ProxyTest : public CommonCompilerTest {
diff --git a/runtime/quick/inline_method_analyser.h b/runtime/quick/inline_method_analyser.h
index 5128b19..982553d 100644
--- a/runtime/quick/inline_method_analyser.h
+++ b/runtime/quick/inline_method_analyser.h
@@ -48,6 +48,7 @@
   kIntrinsicMinMaxFloat,
   kIntrinsicMinMaxDouble,
   kIntrinsicSqrt,
+  kIntrinsicGet,
   kIntrinsicCharAt,
   kIntrinsicCompareTo,
   kIntrinsicIsEmptyOrLength,
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index 49f6fe0..6581f9b 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -16,6 +16,7 @@
 
 #include "quick_exception_handler.h"
 
+#include "arch/context.h"
 #include "dex_instruction.h"
 #include "entrypoints/entrypoint_utils.h"
 #include "handle_scope-inl.h"
diff --git a/runtime/reference_table_test.cc b/runtime/reference_table_test.cc
index 3229039..d2877f9 100644
--- a/runtime/reference_table_test.cc
+++ b/runtime/reference_table_test.cc
@@ -17,6 +17,10 @@
 #include "reference_table.h"
 
 #include "common_runtime_test.h"
+#include "mirror/array.h"
+#include "mirror/string.h"
+#include "scoped_thread_state_change.h"
+#include "thread-inl.h"
 
 namespace art {
 
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index fe5e104..758c1bb 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -20,14 +20,14 @@
 #include "common_throws.h"
 #include "dex_file-inl.h"
 #include "jni_internal.h"
+#include "method_helper-inl.h"
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method-inl.h"
-#include "mirror/class.h"
 #include "mirror/class-inl.h"
-#include "mirror/object_array.h"
+#include "mirror/class.h"
 #include "mirror/object_array-inl.h"
+#include "mirror/object_array.h"
 #include "nth_caller_visitor.h"
-#include "object_utils.h"
 #include "scoped_thread_state_change.h"
 #include "stack.h"
 #include "well_known_classes.h"
@@ -567,6 +567,11 @@
   return true;
 }
 
+static std::string PrettyDescriptor(Primitive::Type type) {
+  std::string descriptor_string(Primitive::Descriptor(type));
+  return PrettyDescriptor(descriptor_string);
+}
+
 bool ConvertPrimitiveValue(const ThrowLocation* throw_location, bool unbox_for_result,
                            Primitive::Type srcType, Primitive::Type dstType,
                            const JValue& src, JValue* dst) {
diff --git a/runtime/reflection_test.cc b/runtime/reflection_test.cc
index abe68ef..9d10daa 100644
--- a/runtime/reflection_test.cc
+++ b/runtime/reflection_test.cc
@@ -18,9 +18,11 @@
 
 #include <float.h>
 #include <limits.h>
+#include "ScopedLocalRef.h"
 
 #include "common_compiler_test.h"
 #include "mirror/art_method-inl.h"
+#include "scoped_thread_state_change.h"
 
 namespace art {
 
diff --git a/runtime/runtime-inl.h b/runtime/runtime-inl.h
index d08e658..f776bcd 100644
--- a/runtime/runtime-inl.h
+++ b/runtime/runtime-inl.h
@@ -19,6 +19,8 @@
 
 #include "runtime.h"
 
+#include "read_barrier-inl.h"
+
 namespace art {
 
 inline QuickMethodFrameInfo Runtime::GetRuntimeMethodFrameInfo(mirror::ArtMethod* method) {
@@ -37,6 +39,36 @@
   }
 }
 
+inline mirror::ArtMethod* Runtime::GetResolutionMethod() {
+  CHECK(HasResolutionMethod());
+  return ReadBarrier::BarrierForRoot<mirror::ArtMethod, kWithReadBarrier>(&resolution_method_);
+}
+
+inline mirror::ArtMethod* Runtime::GetImtConflictMethod() {
+  CHECK(HasImtConflictMethod());
+  return ReadBarrier::BarrierForRoot<mirror::ArtMethod, kWithReadBarrier>(&imt_conflict_method_);
+}
+
+inline mirror::ObjectArray<mirror::ArtMethod>* Runtime::GetDefaultImt()
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  CHECK(HasDefaultImt());
+  return ReadBarrier::BarrierForRoot<mirror::ObjectArray<mirror::ArtMethod>, kWithReadBarrier>(
+      &default_imt_);
+}
+
+inline mirror::ArtMethod* Runtime::GetCalleeSaveMethod(CalleeSaveType type)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  DCHECK(HasCalleeSaveMethod(type));
+  return ReadBarrier::BarrierForRoot<mirror::ArtMethod, kWithReadBarrier>(
+      &callee_save_methods_[type]);
+}
+
+inline mirror::ArtMethod* Runtime::GetCalleeSaveMethodUnchecked(CalleeSaveType type)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  return ReadBarrier::BarrierForRoot<mirror::ArtMethod, kWithReadBarrier>(
+      &callee_save_methods_[type]);
+}
+
 }  // namespace art
 
 #endif  // ART_RUNTIME_RUNTIME_INL_H_
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index c354ad5..0ddd2ae 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -49,6 +49,7 @@
 #include "fault_handler.h"
 #include "gc/accounting/card_table-inl.h"
 #include "gc/heap.h"
+#include "gc/space/image_space.h"
 #include "gc/space/space.h"
 #include "image.h"
 #include "instrumentation.h"
@@ -324,7 +325,7 @@
   GetJavaVM()->SweepJniWeakGlobals(visitor, arg);
 }
 
-bool Runtime::Create(const Options& options, bool ignore_unrecognized) {
+bool Runtime::Create(const RuntimeOptions& options, bool ignore_unrecognized) {
   // TODO: acquire a static mutex on Runtime to avoid racing.
   if (Runtime::instance_ != NULL) {
     return false;
@@ -534,7 +535,7 @@
   VLOG(startup) << "Runtime::StartDaemonThreads exiting";
 }
 
-bool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) {
+bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized) {
   CHECK_EQ(sysconf(_SC_PAGE_SIZE), kPageSize);
 
   std::unique_ptr<ParsedOptions> options(ParsedOptions::Create(raw_options, ignore_unrecognized));
@@ -925,6 +926,7 @@
   mirror::ArtField::VisitRoots(callback, arg);
   mirror::ArtMethod::VisitRoots(callback, arg);
   mirror::Class::VisitRoots(callback, arg);
+  mirror::Reference::VisitRoots(callback, arg);
   mirror::StackTraceElement::VisitRoots(callback, arg);
   mirror::String::VisitRoots(callback, arg);
   mirror::Throwable::VisitRoots(callback, arg);
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 45af437..fccccbd 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -32,7 +32,6 @@
 #include "offsets.h"
 #include "profiler_options.h"
 #include "quick/quick_method_frame_info.h"
-#include "read_barrier-inl.h"
 #include "runtime_stats.h"
 #include "safe_map.h"
 
@@ -69,6 +68,8 @@
 class Trace;
 class Transaction;
 
+typedef std::vector<std::pair<std::string, const void*>> RuntimeOptions;
+
 // Not all combinations of flags are valid. You may not visit all roots as well as the new roots
 // (no logical reason to do this). You also may not start logging new roots and stop logging new
 // roots (also no logical reason to do this).
@@ -82,10 +83,8 @@
 
 class Runtime {
  public:
-  typedef std::vector<std::pair<std::string, const void*>> Options;
-
   // Creates and initializes a new runtime.
-  static bool Create(const Options& options, bool ignore_unrecognized)
+  static bool Create(const RuntimeOptions& options, bool ignore_unrecognized)
       SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_);
 
   bool IsCompiler() const {
@@ -266,13 +265,10 @@
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   // Returns a special method that calls into a trampoline for runtime method resolution
-  mirror::ArtMethod* GetResolutionMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    CHECK(HasResolutionMethod());
-    return ReadBarrier::BarrierForRoot<mirror::ArtMethod, kWithReadBarrier>(&resolution_method_);
-  }
+  mirror::ArtMethod* GetResolutionMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   bool HasResolutionMethod() const {
-    return resolution_method_ != NULL;
+    return resolution_method_ != nullptr;
   }
 
   void SetResolutionMethod(mirror::ArtMethod* method) {
@@ -281,14 +277,11 @@
 
   mirror::ArtMethod* CreateResolutionMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  // Returns a special method that calls into a trampoline for runtime imt conflicts
-  mirror::ArtMethod* GetImtConflictMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    CHECK(HasImtConflictMethod());
-    return ReadBarrier::BarrierForRoot<mirror::ArtMethod, kWithReadBarrier>(&imt_conflict_method_);
-  }
+  // Returns a special method that calls into a trampoline for runtime imt conflicts.
+  mirror::ArtMethod* GetImtConflictMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   bool HasImtConflictMethod() const {
-    return imt_conflict_method_ != NULL;
+    return imt_conflict_method_ != nullptr;
   }
 
   void SetImtConflictMethod(mirror::ArtMethod* method) {
@@ -299,14 +292,10 @@
 
   // Returns an imt with every entry set to conflict, used as default imt for all classes.
   mirror::ObjectArray<mirror::ArtMethod>* GetDefaultImt()
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    CHECK(HasDefaultImt());
-    return ReadBarrier::BarrierForRoot<mirror::ObjectArray<mirror::ArtMethod>, kWithReadBarrier>(
-        &default_imt_);
-  }
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   bool HasDefaultImt() const {
-    return default_imt_ != NULL;
+    return default_imt_ != nullptr;
   }
 
   void SetDefaultImt(mirror::ObjectArray<mirror::ArtMethod>* imt) {
@@ -329,17 +318,10 @@
   }
 
   mirror::ArtMethod* GetCalleeSaveMethod(CalleeSaveType type)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    DCHECK(HasCalleeSaveMethod(type));
-    return ReadBarrier::BarrierForRoot<mirror::ArtMethod, kWithReadBarrier>(
-        &callee_save_methods_[type]);
-  }
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   mirror::ArtMethod* GetCalleeSaveMethodUnchecked(CalleeSaveType type)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return ReadBarrier::BarrierForRoot<mirror::ArtMethod, kWithReadBarrier>(
-        &callee_save_methods_[type]);
-  }
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   QuickMethodFrameInfo GetCalleeSaveMethodFrameInfo(CalleeSaveType type) const {
     return callee_save_method_frame_infos_[type];
@@ -474,7 +456,7 @@
 
   void BlockSignals();
 
-  bool Init(const Options& options, bool ignore_unrecognized)
+  bool Init(const RuntimeOptions& options, bool ignore_unrecognized)
       SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_);
   void InitNativeMethods() LOCKS_EXCLUDED(Locks::mutator_lock_);
   void InitThreadGroups(Thread* self);
diff --git a/runtime/stack.cc b/runtime/stack.cc
index d5405fb..71e566e 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -16,13 +16,13 @@
 
 #include "stack.h"
 
+#include "arch/context.h"
 #include "base/hex_dump.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/object.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
-#include "object_utils.h"
 #include "quick/quick_method_frame_info.h"
 #include "runtime.h"
 #include "thread.h"
@@ -366,9 +366,10 @@
   return result;
 }
 
-instrumentation::InstrumentationStackFrame& StackVisitor::GetInstrumentationStackFrame(uint32_t depth) const {
-  CHECK_LT(depth, thread_->GetInstrumentationStack()->size());
-  return thread_->GetInstrumentationStack()->at(depth);
+static instrumentation::InstrumentationStackFrame& GetInstrumentationStackFrame(Thread* thread,
+                                                                                uint32_t depth) {
+  CHECK_LT(depth, thread->GetInstrumentationStack()->size());
+  return thread->GetInstrumentationStack()->at(depth);
 }
 
 void StackVisitor::SanityCheckFrame() const {
@@ -431,7 +432,7 @@
           // the stack for an exception where the side stack will be unwound in VisitFrame.
           if (GetQuickInstrumentationExitPc() == return_pc) {
             const instrumentation::InstrumentationStackFrame& instrumentation_frame =
-                GetInstrumentationStackFrame(instrumentation_stack_depth);
+                GetInstrumentationStackFrame(thread_, instrumentation_stack_depth);
             instrumentation_stack_depth++;
             if (GetMethod() == Runtime::Current()->GetCalleeSaveMethod(Runtime::kSaveAll)) {
               // Skip runtime save all callee frames which are used to deliver exceptions.
diff --git a/runtime/stack.h b/runtime/stack.h
index 9402cdd..ef498ef 100644
--- a/runtime/stack.h
+++ b/runtime/stack.h
@@ -17,20 +17,16 @@
 #ifndef ART_RUNTIME_STACK_H_
 #define ART_RUNTIME_STACK_H_
 
-#include "dex_file.h"
-#include "instrumentation.h"
-#include "arch/context.h"
-#include "base/casts.h"
-#include "base/macros.h"
-#include "instruction_set.h"
-#include "mirror/object.h"
-#include "mirror/object_reference.h"
-#include "utils.h"
-#include "verify_object.h"
-
 #include <stdint.h>
 #include <string>
 
+#include "dex_file.h"
+#include "instruction_set.h"
+#include "mirror/object_reference.h"
+#include "throw_location.h"
+#include "utils.h"
+#include "verify_object.h"
+
 namespace art {
 
 namespace mirror {
@@ -711,8 +707,6 @@
   bool GetFPR(uint32_t reg, uintptr_t* val) const;
   bool SetFPR(uint32_t reg, uintptr_t value);
 
-  instrumentation::InstrumentationStackFrame& GetInstrumentationStackFrame(uint32_t depth) const;
-
   void SanityCheckFrame() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   Thread* const thread_;
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 7827dfb..9fa158d5e 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -32,27 +32,29 @@
 
 #include "arch/context.h"
 #include "base/mutex.h"
-#include "class_linker.h"
 #include "class_linker-inl.h"
+#include "class_linker.h"
 #include "debugger.h"
 #include "dex_file-inl.h"
 #include "entrypoints/entrypoint_utils.h"
 #include "entrypoints/quick/quick_alloc_entrypoints.h"
 #include "gc_map.h"
 #include "gc/accounting/card_table-inl.h"
+#include "gc/allocator/rosalloc.h"
 #include "gc/heap.h"
 #include "gc/space/space.h"
+#include "handle_scope-inl.h"
 #include "handle_scope.h"
 #include "indirect_reference_table-inl.h"
 #include "jni_internal.h"
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method-inl.h"
-#include "mirror/class-inl.h"
 #include "mirror/class_loader.h"
+#include "mirror/class-inl.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/stack_trace_element.h"
 #include "monitor.h"
-#include "object_utils.h"
+#include "object_lock.h"
 #include "quick_exception_handler.h"
 #include "quick/quick_method_frame_info.h"
 #include "reflection.h"
@@ -60,10 +62,9 @@
 #include "scoped_thread_state_change.h"
 #include "ScopedLocalRef.h"
 #include "ScopedUtfChars.h"
-#include "handle_scope-inl.h"
 #include "stack.h"
-#include "thread-inl.h"
 #include "thread_list.h"
+#include "thread-inl.h"
 #include "utils.h"
 #include "verifier/dex_gc_map.h"
 #include "verify_object-inl.h"
@@ -1055,7 +1056,7 @@
   tls32_.state_and_flags.as_struct.state = kNative;
   memset(&tlsPtr_.held_mutexes[0], 0, sizeof(tlsPtr_.held_mutexes));
   std::fill(tlsPtr_.rosalloc_runs,
-            tlsPtr_.rosalloc_runs + gc::allocator::RosAlloc::kNumThreadLocalSizeBrackets,
+            tlsPtr_.rosalloc_runs + kNumRosAllocThreadLocalSizeBrackets,
             gc::allocator::RosAlloc::GetDedicatedFullRun());
   for (uint32_t i = 0; i < kMaxCheckpoints; ++i) {
     tlsPtr_.checkpoint_functions[i] = nullptr;
diff --git a/runtime/thread.h b/runtime/thread.h
index bf125f9..d08c2fc 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -31,7 +31,6 @@
 #include "entrypoints/jni/jni_entrypoints.h"
 #include "entrypoints/portable/portable_entrypoints.h"
 #include "entrypoints/quick/quick_entrypoints.h"
-#include "gc/allocator/rosalloc.h"
 #include "globals.h"
 #include "handle_scope.h"
 #include "instruction_set.h"
@@ -93,6 +92,8 @@
   kCheckpointRequest = 2  // Request that the thread do some checkpoint work and then continue.
 };
 
+static constexpr size_t kNumRosAllocThreadLocalSizeBrackets = 34;
+
 class Thread {
  public:
   // How much of the reserved bytes is reserved for incoming signals.
@@ -1076,7 +1077,7 @@
     size_t thread_local_objects;
 
     // There are RosAlloc::kNumThreadLocalSizeBrackets thread-local size brackets per thread.
-    void* rosalloc_runs[gc::allocator::RosAlloc::kNumThreadLocalSizeBrackets];
+    void* rosalloc_runs[kNumRosAllocThreadLocalSizeBrackets];
 
     // Thread-local allocation stack data/routines.
     mirror::Object** thread_local_alloc_stack_top;
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index 54732fa..b649b62 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -39,6 +39,8 @@
 
 namespace art {
 
+static constexpr uint64_t kLongThreadSuspendThreshold = MsToNs(5);
+
 ThreadList::ThreadList()
     : suspend_all_count_(0), debug_suspend_all_count_(0),
       thread_exit_cond_("thread exit condition variable", *Locks::thread_list_lock_) {
@@ -304,8 +306,8 @@
   DCHECK(self != nullptr);
 
   VLOG(threads) << *self << " SuspendAll starting...";
-
   ATRACE_BEGIN("Suspending mutator threads");
+  uint64_t start_time = NanoTime();
 
   Locks::mutator_lock_->AssertNotHeld(self);
   Locks::thread_list_lock_->AssertNotHeld(self);
@@ -338,6 +340,11 @@
   Locks::mutator_lock_->ExclusiveLock(self);
 #endif
 
+  uint64_t end_time = NanoTime();
+  if (end_time - start_time > kLongThreadSuspendThreshold) {
+    LOG(WARNING) << "Suspending all threads took: " << PrettyDuration(end_time - start_time);
+  }
+
   if (kDebugLocking) {
     // Debug check that all threads are suspended.
     AssertThreadsAreSuspended(self, self);
diff --git a/runtime/thread_pool_test.cc b/runtime/thread_pool_test.cc
index 292c94f..4bd44dc 100644
--- a/runtime/thread_pool_test.cc
+++ b/runtime/thread_pool_test.cc
@@ -20,6 +20,7 @@
 
 #include "atomic.h"
 #include "common_runtime_test.h"
+#include "thread-inl.h"
 
 namespace art {
 
diff --git a/runtime/throw_location.cc b/runtime/throw_location.cc
index a1347a4..04abe64 100644
--- a/runtime/throw_location.cc
+++ b/runtime/throw_location.cc
@@ -19,7 +19,6 @@
 #include "mirror/art_method-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "utils.h"
 
 namespace art {
diff --git a/runtime/trace.cc b/runtime/trace.cc
index 1a450c4..f51b8c4 100644
--- a/runtime/trace.cc
+++ b/runtime/trace.cc
@@ -30,7 +30,6 @@
 #include "mirror/dex_cache.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "os.h"
 #include "scoped_thread_state_change.h"
 #include "ScopedLocalRef.h"
@@ -115,7 +114,7 @@
 static const uint16_t kTraceRecordSizeSingleClock = 10;  // using v2
 static const uint16_t kTraceRecordSizeDualClock   = 14;  // using v3 with two timestamps
 
-ProfilerClockSource Trace::default_clock_source_ = kDefaultProfilerClockSource;
+TraceClockSource Trace::default_clock_source_ = kDefaultTraceClockSource;
 
 Trace* volatile Trace::the_trace_ = NULL;
 pthread_t Trace::sampling_pthread_ = 0U;
@@ -149,34 +148,34 @@
   temp_stack_trace_.reset(stack_trace);
 }
 
-void Trace::SetDefaultClockSource(ProfilerClockSource clock_source) {
+void Trace::SetDefaultClockSource(TraceClockSource clock_source) {
 #if defined(HAVE_POSIX_CLOCKS)
   default_clock_source_ = clock_source;
 #else
-  if (clock_source != kProfilerClockSourceWall) {
+  if (clock_source != kTraceClockSourceWall) {
     LOG(WARNING) << "Ignoring tracing request to use CPU time.";
   }
 #endif
 }
 
-static uint16_t GetTraceVersion(ProfilerClockSource clock_source) {
-  return (clock_source == kProfilerClockSourceDual) ? kTraceVersionDualClock
+static uint16_t GetTraceVersion(TraceClockSource clock_source) {
+  return (clock_source == kTraceClockSourceDual) ? kTraceVersionDualClock
                                                     : kTraceVersionSingleClock;
 }
 
-static uint16_t GetRecordSize(ProfilerClockSource clock_source) {
-  return (clock_source == kProfilerClockSourceDual) ? kTraceRecordSizeDualClock
+static uint16_t GetRecordSize(TraceClockSource clock_source) {
+  return (clock_source == kTraceClockSourceDual) ? kTraceRecordSizeDualClock
                                                     : kTraceRecordSizeSingleClock;
 }
 
 bool Trace::UseThreadCpuClock() {
-  return (clock_source_ == kProfilerClockSourceThreadCpu) ||
-      (clock_source_ == kProfilerClockSourceDual);
+  return (clock_source_ == kTraceClockSourceThreadCpu) ||
+      (clock_source_ == kTraceClockSourceDual);
 }
 
 bool Trace::UseWallClock() {
-  return (clock_source_ == kProfilerClockSourceWall) ||
-      (clock_source_ == kProfilerClockSourceDual);
+  return (clock_source_ == kTraceClockSourceWall) ||
+      (clock_source_ == kTraceClockSourceDual);
 }
 
 static void MeasureClockOverhead(Trace* trace) {
@@ -462,7 +461,7 @@
   cur_offset_.StoreRelaxed(kTraceHeaderLength);
 }
 
-static void DumpBuf(uint8_t* buf, size_t buf_size, ProfilerClockSource clock_source)
+static void DumpBuf(uint8_t* buf, size_t buf_size, TraceClockSource clock_source)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   uint8_t* ptr = buf + kTraceHeaderLength;
   uint8_t* end = buf + buf_size;
diff --git a/runtime/trace.h b/runtime/trace.h
index 9c8d35b..d7836b8 100644
--- a/runtime/trace.h
+++ b/runtime/trace.h
@@ -36,20 +36,9 @@
   class ArtField;
   class ArtMethod;
 }  // namespace mirror
+
 class Thread;
 
-enum ProfilerClockSource {
-  kProfilerClockSourceThreadCpu,
-  kProfilerClockSourceWall,
-  kProfilerClockSourceDual,  // Both wall and thread CPU clocks.
-};
-
-#if defined(HAVE_POSIX_CLOCKS)
-const ProfilerClockSource kDefaultProfilerClockSource = kProfilerClockSourceDual;
-#else
-const ProfilerClockSource kDefaultProfilerClockSource = kProfilerClockSourceWall;
-#endif
-
 enum TracingMode {
   kTracingInactive,
   kMethodTracingActive,
@@ -62,7 +51,7 @@
     kTraceCountAllocs = 1,
   };
 
-  static void SetDefaultClockSource(ProfilerClockSource clock_source);
+  static void SetDefaultClockSource(TraceClockSource clock_source);
 
   static void Start(const char* trace_filename, int trace_fd, int buffer_size, int flags,
                     bool direct_to_ddms, bool sampling_enabled, int interval_us)
@@ -138,7 +127,7 @@
   static Trace* volatile the_trace_ GUARDED_BY(Locks::trace_lock_);
 
   // The default profiler clock source.
-  static ProfilerClockSource default_clock_source_;
+  static TraceClockSource default_clock_source_;
 
   // Sampling thread, non-zero when sampling.
   static pthread_t sampling_pthread_;
@@ -158,7 +147,7 @@
   // True if traceview should sample instead of instrumenting method entry/exit.
   const bool sampling_enabled_;
 
-  const ProfilerClockSource clock_source_;
+  const TraceClockSource clock_source_;
 
   // Size of buf_.
   const int buffer_size_;
diff --git a/runtime/transaction_test.cc b/runtime/transaction_test.cc
index a03b389..691aec4 100644
--- a/runtime/transaction_test.cc
+++ b/runtime/transaction_test.cc
@@ -20,6 +20,7 @@
 #include "mirror/array-inl.h"
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method-inl.h"
+#include "scoped_thread_state_change.h"
 
 namespace art {
 
diff --git a/runtime/utils.cc b/runtime/utils.cc
index d038571..8b1ad39 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -28,6 +28,7 @@
 #include "base/stl_util.h"
 #include "base/unix_file/fd_file.h"
 #include "dex_file-inl.h"
+#include "field_helper.h"
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class-inl.h"
@@ -35,7 +36,6 @@
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/string.h"
-#include "object_utils.h"
 #include "os.h"
 #include "scoped_thread_state_change.h"
 #include "utf-inl.h"
@@ -281,11 +281,6 @@
   return result;
 }
 
-std::string PrettyDescriptor(Primitive::Type type) {
-  std::string descriptor_string(Primitive::Descriptor(type));
-  return PrettyDescriptor(descriptor_string);
-}
-
 std::string PrettyField(mirror::ArtField* f, bool with_type) {
   if (f == NULL) {
     return "null";
diff --git a/runtime/utils.h b/runtime/utils.h
index 2ea4953..c920050 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -26,7 +26,7 @@
 #include "base/logging.h"
 #include "globals.h"
 #include "instruction_set.h"
-#include "primitive.h"
+#include "base/mutex.h"
 
 #ifdef HAVE_ANDROID_OS
 #include "cutils/properties.h"
@@ -277,7 +277,6 @@
 std::string PrettyDescriptor(mirror::String* descriptor)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 std::string PrettyDescriptor(const std::string& descriptor);
-std::string PrettyDescriptor(Primitive::Type type);
 std::string PrettyDescriptor(mirror::Class* klass)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index eabb993..f1b5afd 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -25,10 +25,12 @@
 #include "dex_file-inl.h"
 #include "dex_instruction-inl.h"
 #include "dex_instruction_visitor.h"
+#include "field_helper.h"
 #include "gc/accounting/card_table-inl.h"
 #include "indenter.h"
 #include "intern_table.h"
 #include "leb128.h"
+#include "method_helper-inl.h"
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class.h"
@@ -36,7 +38,6 @@
 #include "mirror/dex_cache-inl.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
-#include "object_utils.h"
 #include "register_line-inl.h"
 #include "runtime.h"
 #include "scoped_thread_state_change.h"
diff --git a/runtime/verifier/method_verifier_test.cc b/runtime/verifier/method_verifier_test.cc
index f70faf5..a5895e6 100644
--- a/runtime/verifier/method_verifier_test.cc
+++ b/runtime/verifier/method_verifier_test.cc
@@ -22,6 +22,7 @@
 #include "class_linker-inl.h"
 #include "common_runtime_test.h"
 #include "dex_file.h"
+#include "scoped_thread_state_change.h"
 
 namespace art {
 namespace verifier {
diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc
index e24c920..f0729e4 100644
--- a/runtime/verifier/reg_type.cc
+++ b/runtime/verifier/reg_type.cc
@@ -24,7 +24,6 @@
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
-#include "object_utils.h"
 #include "reg_type_cache-inl.h"
 #include "scoped_thread_state_change.h"
 
diff --git a/runtime/verifier/reg_type_cache.cc b/runtime/verifier/reg_type_cache.cc
index ff9edbb..91fba4d 100644
--- a/runtime/verifier/reg_type_cache.cc
+++ b/runtime/verifier/reg_type_cache.cc
@@ -21,7 +21,6 @@
 #include "dex_file-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 
 namespace art {
 namespace verifier {
diff --git a/runtime/verifier/reg_type_test.cc b/runtime/verifier/reg_type_test.cc
index 1935a5b..9dc0df1 100644
--- a/runtime/verifier/reg_type_test.cc
+++ b/runtime/verifier/reg_type_test.cc
@@ -21,6 +21,8 @@
 #include "base/casts.h"
 #include "common_runtime_test.h"
 #include "reg_type_cache-inl.h"
+#include "scoped_thread_state_change.h"
+#include "thread-inl.h"
 
 namespace art {
 namespace verifier {
diff --git a/runtime/verify_object.h b/runtime/verify_object.h
index 6640e0d..8e1653d 100644
--- a/runtime/verify_object.h
+++ b/runtime/verify_object.h
@@ -52,10 +52,10 @@
 static constexpr VerifyObjectMode kVerifyObjectSupport =
     kDefaultVerifyFlags != 0 ? kVerifyObjectModeFast : kVerifyObjectModeDisabled;
 
-void VerifyObject(mirror::Object* obj) ALWAYS_INLINE NO_THREAD_SAFETY_ANALYSIS;
+ALWAYS_INLINE void VerifyObject(mirror::Object* obj) NO_THREAD_SAFETY_ANALYSIS;
 
 // Check that c.getClass() == c.getClass().getClass().
-bool VerifyClassClass(mirror::Class* c) ALWAYS_INLINE NO_THREAD_SAFETY_ANALYSIS;
+ALWAYS_INLINE bool VerifyClassClass(mirror::Class* c) NO_THREAD_SAFETY_ANALYSIS;
 
 }  // namespace art
 
diff --git a/runtime/zip_archive_test.cc b/runtime/zip_archive_test.cc
index d303d1e..96abee2 100644
--- a/runtime/zip_archive_test.cc
+++ b/runtime/zip_archive_test.cc
@@ -22,6 +22,7 @@
 #include <zlib.h>
 #include <memory>
 
+#include "base/unix_file/fd_file.h"
 #include "common_runtime_test.h"
 #include "os.h"
 
diff --git a/sigchainlib/sigchain.h b/sigchainlib/sigchain.h
index f6f2253..a4ce81c 100644
--- a/sigchainlib/sigchain.h
+++ b/sigchainlib/sigchain.h
@@ -18,10 +18,13 @@
 #define ART_SIGCHAINLIB_SIGCHAIN_H_
 
 #include <signal.h>
+
 namespace art {
 
 void ClaimSignalChain(int signal, struct sigaction* oldaction);
+
 void UnclaimSignalChain(int signal);
+
 void InvokeUserSignalHandler(int sig, siginfo_t* info, void* context);
 
 }   // namespace art
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 25bcf0a..1683074 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -21,26 +21,62 @@
 TEST_ART_RUN_TESTS := $(wildcard $(LOCAL_PATH)/[0-9]*)
 TEST_ART_RUN_TESTS := $(subst $(LOCAL_PATH)/,, $(TEST_ART_RUN_TESTS))
 
+# List all the test names for host and target excluding the -trace suffix
+# $(1): test name, e.g. 003-omnibus-opcodes
+# $(2): undefined or -trace
+define all-run-test-names
+  test-art-host-run-test$(2)-default-$(1)32 \
+  test-art-host-run-test$(2)-optimizing-$(1)32 \
+  test-art-host-run-test$(2)-interpreter-$(1)32 \
+  test-art-host-run-test$(2)-default-$(1)64 \
+  test-art-host-run-test$(2)-optimizing-$(1)64 \
+  test-art-host-run-test$(2)-interpreter-$(1)64 \
+  test-art-target-run-test$(2)-default-$(1)32 \
+  test-art-target-run-test$(2)-optimizing-$(1)32 \
+  test-art-target-run-test$(2)-interpreter-$(1)32 \
+  test-art-target-run-test$(2)-default-$(1)64 \
+  test-art-target-run-test$(2)-optimizing-$(1)64 \
+  test-art-target-run-test$(2)-interpreter-$(1)64
+endef  # all-run-test-names
+
 # Tests that are timing sensitive and flaky on heavily loaded systems.
 TEST_ART_TIMING_SENSITIVE_RUN_TESTS := \
-  test-art-host-run-test-default-053-wait-some32 \
-  test-art-host-run-test-default-053-wait-some64 \
-  test-art-host-run-test-interpreter-053-wait-some32 \
-  test-art-host-run-test-interpreter-053-wait-some64 \
-  test-art-host-run-test-optimizing-053-wait-some32 \
-  test-art-host-run-test-optimizing-053-wait-some64 \
-  test-art-host-run-test-default-055-enum-performance32 \
-  test-art-host-run-test-default-055-enum-performance64 \
-  test-art-host-run-test-interpreter-055-enum-performance32 \
-  test-art-host-run-test-interpreter-055-enum-performance64 \
-  test-art-host-run-test-optimizing-055-enum-performance32 \
-  test-art-host-run-test-optimizing-055-enum-performance64
+  053-wait-some \
+  055-enum-performance
 
  # disable timing sensitive tests on "dist" builds.
 ifdef dist_goal
-  ART_TEST_KNOWN_BROKEN += $(TEST_ART_TIMING_SENSITIVE_RUN_TESTS)
+  ART_TEST_KNOWN_BROKEN += $(foreach test, $(TEST_ART_TIMING_SENSITIVE_RUN_TESTS), $(call all-run-test-names,$(test),))
+  ART_TEST_KNOWN_BROKEN += $(foreach test, $(TEST_ART_TIMING_SENSITIVE_RUN_TESTS), $(call all-run-test-names,$(test),-trace))
 endif
 
+# Tests that are broken in --trace mode.
+TEST_ART_BROKEN_TRACE_RUN_TESTS := \
+  003-omnibus-opcodes \
+  004-annotations \
+  018-stack-overflow \
+  023-many-interfaces \
+  031-class-attributes \
+  037-inherit \
+  044-proxy \
+  046-reflect \
+  051-thread \
+  055-enum-performance \
+  064-field-access \
+  078-polymorphic-virtual \
+  080-oom-throw \
+  082-inline-execute \
+  083-compiler-regressions \
+  097-duplicate-method \
+  100-reflect2 \
+  102-concurrent-gc \
+  103-string-append \
+  107-int-math2 \
+  112-double-math \
+  701-easy-div-rem
+
+ART_TEST_KNOWN_BROKEN += $(foreach test, $(TEST_ART_BROKEN_TRACE_RUN_TESTS), $(call all-run-test-names,$(test),-trace))
+
 # The path where build only targets will be output, e.g.
 # out/target/product/generic_x86_64/obj/PACKAGING/art-run-tests_intermediates/DATA
 art_run_tests_dir := $(call intermediates-dir-for,PACKAGING,art-run-tests)/DATA
@@ -96,9 +132,11 @@
 ART_TEST_HOST_RUN_TEST_DEFAULT_RULES :=
 ART_TEST_HOST_RUN_TEST_INTERPRETER_RULES :=
 ART_TEST_HOST_RUN_TEST_OPTIMIZING_RULES :=
+ART_TEST_HOST_RUN_TEST_ALL$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
 ART_TEST_HOST_RUN_TEST_DEFAULT$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
 ART_TEST_HOST_RUN_TEST_INTERPRETER$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
 ART_TEST_HOST_RUN_TEST_OPTIMIZING$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_RUN_TEST_ALL$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
 ART_TEST_HOST_RUN_TEST_DEFAULT$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
 ART_TEST_HOST_RUN_TEST_INTERPRETER$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
 ART_TEST_HOST_RUN_TEST_OPTIMIZING$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
@@ -124,8 +162,10 @@
 # $(2): host or target
 # $(3): default, optimizing or interpreter
 # $(4): 32 or 64
+# $(5): run tests with tracing enabled or not: trace or undefined
 define define-test-art-run-test
   run_test_options := $(addprefix --runtime-option ,$(DALVIKVM_FLAGS))
+  run_test_rule_name := test-art-$(2)-run-test-$(3)-$(1)$(4)
   uc_host_or_target :=
   prereq_rule :=
   ifeq ($(2),host)
@@ -163,7 +203,14 @@
       $$(error found $(4) expected 32 or 64)
     endif
   endif
-  run_test_rule_name := test-art-$(2)-run-test-$(3)-$(1)$(4)
+  ifeq ($(5),trace)
+    run_test_options += --trace
+    run_test_rule_name := test-art-$(2)-run-test-trace-$(3)-$(1)$(4)
+  else
+    ifneq (,$(5))
+      $$(error found $(5) expected undefined or -trace)
+    endif
+  endif
   run_test_options := --output-path $(ART_HOST_TEST_DIR)/run-test-output/$$(run_test_rule_name) \
     $$(run_test_options)
 $$(run_test_rule_name): PRIVATE_RUN_TEST_OPTIONS := $$(run_test_options)
@@ -222,9 +269,13 @@
   ART_TEST_$$(group_uc_host_or_target)_RUN_TEST_INTERPRETER_$(1)_RULES :=
   ART_TEST_$$(group_uc_host_or_target)_RUN_TEST_OPTIMIZING_$(1)_RULES :=
   ART_TEST_$$(group_uc_host_or_target)_RUN_TEST_$(1)_RULES :=
-  $$(eval $$(call define-test-art-run-test,$(1),$(2),default,$$(ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX)))
-  $$(eval $$(call define-test-art-run-test,$(1),$(2),interpreter,$$(ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX)))
-  $$(eval $$(call define-test-art-run-test,$(1),$(2),optimizing,$$(ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX)))
+  $$(eval $$(call define-test-art-run-test,$(1),$(2),default,$$(ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX),))
+  $$(eval $$(call define-test-art-run-test,$(1),$(2),interpreter,$$(ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX),))
+  $$(eval $$(call define-test-art-run-test,$(1),$(2),optimizing,$$(ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX),))
+  ifeq ($(2),host)
+    # For now just test tracing on the host with default.
+    $$(eval $$(call define-test-art-run-test,$(1),$(2),default,$$(ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX),trace))
+  endif
   do_second := false
   ifeq ($(2),host)
     ifneq ($$(HOST_PREFER_32_BIT),true)
@@ -236,9 +287,13 @@
     endif
   endif
   ifeq (true,$$(do_second))
-    $$(eval $$(call define-test-art-run-test,$(1),$(2),default,$$(2ND_ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX)))
-    $$(eval $$(call define-test-art-run-test,$(1),$(2),interpreter,$$(2ND_ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX)))
-    $$(eval $$(call define-test-art-run-test,$(1),$(2),optimizing,$$(2ND_ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX)))
+    $$(eval $$(call define-test-art-run-test,$(1),$(2),default,$$(2ND_ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX),))
+    $$(eval $$(call define-test-art-run-test,$(1),$(2),interpreter,$$(2ND_ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX),))
+    $$(eval $$(call define-test-art-run-test,$(1),$(2),optimizing,$$(2ND_ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX),))
+    ifeq ($(2),host)
+      # For now just test tracing on the host with default.
+      $$(eval $$(call define-test-art-run-test,$(1),$(2),default,$$(2ND_ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX),trace))
+    endif
   endif
 
   $$(eval $$(call define-test-art-run-test-group-rule,test-art-$(2)-run-test-default-$(1), \
@@ -319,6 +374,7 @@
 define-test-art-run-test :=
 define-test-art-run-test-group-rule :=
 define-test-art-run-test-group :=
+all-run-test-names :=
 ART_TEST_TARGET_RUN_TEST_ALL_RULES :=
 ART_TEST_TARGET_RUN_TEST_DEFAULT_RULES :=
 ART_TEST_TARGET_RUN_TEST_INTERPRETER_RULES :=
@@ -335,9 +391,11 @@
 ART_TEST_HOST_RUN_TEST_DEFAULT_RULES :=
 ART_TEST_HOST_RUN_TEST_INTERPRETER_RULES :=
 ART_TEST_HOST_RUN_TEST_OPTIMIZING_RULES :=
+ART_TEST_HOST_RUN_TEST_ALL$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
 ART_TEST_HOST_RUN_TEST_DEFAULT$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
 ART_TEST_HOST_RUN_TEST_INTERPRETER$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
 ART_TEST_HOST_RUN_TEST_OPTIMIZING$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_RUN_TEST_ALL$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
 ART_TEST_HOST_RUN_TEST_DEFAULT$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
 ART_TEST_HOST_RUN_TEST_INTERPRETER$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
 ART_TEST_HOST_RUN_TEST_OPTIMIZING$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
diff --git a/test/ReferenceMap/stack_walk_refmap_jni.cc b/test/ReferenceMap/stack_walk_refmap_jni.cc
index 87187ed..e5a17861 100644
--- a/test/ReferenceMap/stack_walk_refmap_jni.cc
+++ b/test/ReferenceMap/stack_walk_refmap_jni.cc
@@ -20,12 +20,10 @@
 #include "class_linker.h"
 #include "dex_file-inl.h"
 #include "gc_map.h"
-#include "mirror/art_method.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "scoped_thread_state_change.h"
 #include "thread.h"
 #include "jni.h"
diff --git a/test/StackWalk/stack_walk_jni.cc b/test/StackWalk/stack_walk_jni.cc
index c849c54..e404f6a 100644
--- a/test/StackWalk/stack_walk_jni.cc
+++ b/test/StackWalk/stack_walk_jni.cc
@@ -19,12 +19,10 @@
 
 #include "class_linker.h"
 #include "gc_map.h"
-#include "mirror/art_method.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/object-inl.h"
-#include "object_utils.h"
 #include "jni.h"
 #include "scoped_thread_state_change.h"