diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h
new file mode 100644
index 0000000..f935095
--- /dev/null
+++ b/compiler/common_compiler_test.h
@@ -0,0 +1,417 @@
+/*
+ * 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_COMMON_COMPILER_TEST_H_
+#define ART_COMPILER_COMMON_COMPILER_TEST_H_
+
+#include "compiler_backend.h"
+#include "compiler_callbacks.h"
+#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"
+
+namespace art {
+
+#if defined(__arm__)
+
+#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 void baddivideinst(int signo, siginfo *si, void *data) {
+  (void)signo;
+  (void)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;
+}
+
+class CommonCompilerTest : public CommonRuntimeTest {
+ public:
+  static void MakeExecutable(const std::vector<uint8_t>& code) {
+    CHECK_NE(code.size(), 0U);
+    MakeExecutable(&code[0], code.size());
+  }
+
+  // Create an OatMethod based on pointers (for unit tests).
+  OatFile::OatMethod CreateOatMethod(const void* code,
+                                     const size_t frame_size_in_bytes,
+                                     const uint32_t core_spill_mask,
+                                     const uint32_t fp_spill_mask,
+                                     const uint8_t* mapping_table,
+                                     const uint8_t* vmap_table,
+                                     const uint8_t* gc_map) {
+    const byte* base;
+    uint32_t code_offset, mapping_table_offset, vmap_table_offset, gc_map_offset;
+    if (mapping_table == nullptr && vmap_table == nullptr && 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;
+      mapping_table_offset = 0;
+      vmap_table_offset = 0;
+      gc_map_offset = 0;
+    } else {
+      // TODO: 64bit support.
+      base = nullptr;  // Base of data in oat file, ie 0.
+      code_offset = PointerToLowMemUInt32(code);
+      mapping_table_offset = PointerToLowMemUInt32(mapping_table);
+      vmap_table_offset = PointerToLowMemUInt32(vmap_table);
+      gc_map_offset = PointerToLowMemUInt32(gc_map);
+    }
+    return OatFile::OatMethod(base,
+                              code_offset,
+                              frame_size_in_bytes,
+                              core_spill_mask,
+                              fp_spill_mask,
+                              mapping_table_offset,
+                              vmap_table_offset,
+                              gc_map_offset);
+  }
+
+  void MakeExecutable(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    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();
+      if (code == nullptr) {
+        code = compiled_method->GetPortableCode();
+      }
+      MakeExecutable(*code);
+      const void* method_code = CompiledMethod::CodePointer(&(*code)[0],
+                                                            compiled_method->GetInstructionSet());
+      LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
+      OatFile::OatMethod oat_method = CreateOatMethod(method_code,
+                                                      compiled_method->GetFrameSizeInBytes(),
+                                                      compiled_method->GetCoreSpillMask(),
+                                                      compiled_method->GetFpSpillMask(),
+                                                      &compiled_method->GetMappingTable()[0],
+                                                      &compiled_method->GetVmapTable()[0],
+                                                      nullptr);
+      oat_method.LinkMethod(method);
+      method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge);
+    } else {
+      // No code? You must mean to go into the interpreter.
+      const void* method_code = kUsePortableCompiler ? GetPortableToInterpreterBridge()
+                                                     : GetQuickToInterpreterBridge();
+      OatFile::OatMethod oat_method = CreateOatMethod(method_code,
+                                                      kStackAlignment,
+                                                      0,
+                                                      0,
+                                                      nullptr,
+                                                      nullptr,
+                                                      nullptr);
+      oat_method.LinkMethod(method);
+      method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterBridge);
+    }
+    // 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(FATAL) << "UNIMPLEMENTED: cache flush";
+#endif
+  }
+
+  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();
+    SirtRef<mirror::ClassLoader> loader(self, 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));
+    }
+  }
+
+ protected:
+  virtual void SetUp() {
+    CommonRuntimeTest::SetUp();
+    {
+      ScopedObjectAccess soa(Thread::Current());
+
+      InstructionSet instruction_set = kNone;
+
+      // Take the default set of instruction features from the build.
+      InstructionSetFeatures instruction_set_features =
+          ParseFeatureList(STRINGIFY(ART_DEFAULT_INSTRUCTION_SET_FEATURES));
+
+#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_EQ(instruction_set_features, runtime_features);
+#elif defined(__mips__)
+      instruction_set = kMips;
+#elif defined(__i386__)
+      instruction_set = kX86;
+#elif defined(__x86_64__)
+      instruction_set = kX86_64;
+      // TODO: x86_64 compilation support.
+      compiler_options_->SetCompilerFilter(Runtime::kInterpretOnly);
+#endif
+
+      for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
+        Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
+        if (!runtime_->HasCalleeSaveMethod(type)) {
+          runtime_->SetCalleeSaveMethod(
+              runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
+        }
+      }
+
+      // TODO: make selectable
+      CompilerBackend::Kind compiler_backend
+          = (kUsePortableCompiler) ? CompilerBackend::kPortable : CompilerBackend::kQuick;
+      timer_.reset(new CumulativeLogger("Compilation times"));
+      compiler_driver_.reset(new CompilerDriver(compiler_options_.get(),
+                                                verification_results_.get(),
+                                                method_inliner_map_.get(),
+                                                compiler_backend, 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();
+  }
+
+  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();
+    SirtRef<mirror::ClassLoader> loader(self, 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 CompileMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    CHECK(method != nullptr);
+    TimingLogger timings("CommonTest::CompileMethod", false, false);
+    timings.StartSplit("CompileOne");
+    compiler_driver_->CompileOne(method, timings);
+    MakeExecutable(method);
+    timings.EndSplit();
+  }
+
+  void CompileDirectMethod(SirtRef<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);
+  }
+
+  void CompileVirtualMethod(SirtRef<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 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 UnreserveImageSpace() {
+    image_reservation_.reset();
+  }
+
+  UniquePtr<CompilerOptions> compiler_options_;
+  UniquePtr<VerificationResults> verification_results_;
+  UniquePtr<DexFileToMethodInlinerMap> method_inliner_map_;
+  UniquePtr<CompilerCallbacksImpl> callbacks_;
+  UniquePtr<CompilerDriver> compiler_driver_;
+  UniquePtr<CumulativeLogger> timer_;
+
+ private:
+  UniquePtr<MemMap> image_reservation_;
+};
+
+}  // namespace art
+
+#endif  // ART_COMPILER_COMMON_COMPILER_TEST_H_
