diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc
new file mode 100644
index 0000000..ee68a5d
--- /dev/null
+++ b/compiler/dex/dex_to_dex_compiler.cc
@@ -0,0 +1,302 @@
+/*
+ * 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 "base/logging.h"
+#include "base/mutex.h"
+#include "dex_file-inl.h"
+#include "dex_instruction-inl.h"
+#include "driver/compiler_driver.h"
+#include "driver/dex_compilation_unit.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/class-inl.h"
+#include "mirror/dex_cache.h"
+#include "mirror/field-inl.h"
+
+namespace art {
+namespace optimizer {
+
+// Controls quickening activation.
+const bool kEnableQuickening = true;
+// Controls logging.
+const bool kEnableLogging = false;
+
+class DexCompiler {
+ public:
+  DexCompiler(art::CompilerDriver& compiler,
+              const DexCompilationUnit& unit)
+    : driver_(compiler),
+      unit_(unit) {};
+
+  ~DexCompiler() {};
+
+  void Compile();
+
+ private:
+  const DexFile& GetDexFile() const {
+    return *unit_.GetDexFile();
+  }
+
+  // TODO: since the whole compilation pipeline uses a "const DexFile", we need
+  // to "unconst" here. The DEX-to-DEX compiler should work on a non-const DexFile.
+  DexFile& GetModifiableDexFile() {
+    return *const_cast<DexFile*>(unit_.GetDexFile());
+  }
+
+  // Compiles a RETURN-VOID into a RETURN-VOID-BARRIER within a constructor where
+  // a barrier is required.
+  void CompileReturnVoid(Instruction* inst, uint32_t dex_pc);
+
+  // Compiles a field access into a quick field access.
+  // The field index is replaced by an offset within an Object where we can read
+  // from / write to this field. Therefore, this does not involve any resolution
+  // at runtime.
+  // Since the field index is encoded with 16 bits, we can replace it only if the
+  // field offset can be encoded with 16 bits too.
+  void CompileInstanceFieldAccess(Instruction* inst, uint32_t dex_pc,
+                                  Instruction::Code new_opcode, bool is_put);
+
+  // Compiles a virtual method invocation into a quick virtual method invocation.
+  // The method index is replaced by the vtable index where the corresponding
+  // AbstractMethod can be found. Therefore, this does not involve any resolution
+  // at runtime.
+  // Since the method index is encoded with 16 bits, we can replace it only if the
+  // vtable index can be encoded with 16 bits too.
+  void CompileInvokeVirtual(Instruction* inst, uint32_t dex_pc,
+                            Instruction::Code new_opcode, bool is_range);
+
+  CompilerDriver& driver_;
+  const DexCompilationUnit& unit_;
+
+  DISALLOW_COPY_AND_ASSIGN(DexCompiler);
+};
+
+// Ensures write access to a part of DEX file.
+//
+// If a DEX file is read-only, it modifies its protection (mprotect) so it allows
+// write access to the part of DEX file defined by an address and a length.
+// In this case, it also takes the DexFile::modification_lock to prevent from
+// concurrent protection modification from a parallel DEX-to-DEX compilation on
+// the same DEX file.
+// When the instance is destroyed, it recovers original protection and releases
+// the lock.
+// TODO: as this scoped class is similar to a MutexLock we should use annotalysis
+// to capture the locking behavior.
+class ScopedDexWriteAccess {
+ public:
+  ScopedDexWriteAccess(DexFile& dex_file, Instruction* inst,
+                       size_t length)
+    : dex_file_(dex_file),
+      address_(reinterpret_cast<uint8_t*>(inst)),
+      length_(length),
+      is_read_only_(dex_file_.IsReadOnly()) {
+    if (is_read_only_) {
+      // We need to enable DEX write access. To avoid concurrent DEX write access
+      // modification, we take the DexFile::modification_lock before.
+      dex_file_.GetModificationLock().ExclusiveLock(Thread::Current());
+      bool success = dex_file_.EnableWrite(address_, length_);
+      DCHECK(success) << "Failed to enable DEX write access";
+    }
+  }
+
+  ~ScopedDexWriteAccess() {
+    DCHECK_EQ(is_read_only_, dex_file_.IsReadOnly());
+    if (is_read_only_) {
+      bool success = dex_file_.DisableWrite(address_, length_);
+      DCHECK(success) << "Failed to disable DEX write access";
+      // Now we recovered original read-only protection, we can release the
+      // DexFile::modification_lock.
+      dex_file_.GetModificationLock().ExclusiveUnlock(Thread::Current());
+    }
+  }
+
+ private:
+  DexFile& dex_file_;
+  // TODO: make address_ const.
+  uint8_t* address_;
+  const size_t length_;
+  const bool is_read_only_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedDexWriteAccess);
+};
+
+void DexCompiler::Compile() {
+  const DexFile::CodeItem* code_item = unit_.GetCodeItem();
+  const uint16_t* insns = code_item->insns_;
+  const uint32_t insns_size = code_item->insns_size_in_code_units_;
+  Instruction* inst = const_cast<Instruction*>(Instruction::At(insns));
+
+  for (uint32_t dex_pc = 0; dex_pc < insns_size;
+       inst = const_cast<Instruction*>(inst->Next()), dex_pc = inst->GetDexPc(insns)) {
+    switch (inst->Opcode()) {
+      case Instruction::RETURN_VOID:
+        CompileReturnVoid(inst, dex_pc);
+        break;
+
+      case Instruction::IGET:
+        CompileInstanceFieldAccess(inst, dex_pc, Instruction::IGET_QUICK, false);
+        break;
+
+      case Instruction::IGET_WIDE:
+        CompileInstanceFieldAccess(inst, dex_pc, Instruction::IGET_WIDE_QUICK, false);
+        break;
+
+      case Instruction::IGET_OBJECT:
+        CompileInstanceFieldAccess(inst, dex_pc, Instruction::IGET_OBJECT_QUICK, false);
+        break;
+
+      case Instruction::IPUT:
+      case Instruction::IPUT_BOOLEAN:
+      case Instruction::IPUT_BYTE:
+      case Instruction::IPUT_CHAR:
+      case Instruction::IPUT_SHORT:
+        // These opcodes have the same implementation in interpreter so group
+        // them under IPUT_QUICK.
+        CompileInstanceFieldAccess(inst, dex_pc, Instruction::IPUT_QUICK, true);
+        break;
+
+      case Instruction::IPUT_WIDE:
+        CompileInstanceFieldAccess(inst, dex_pc, Instruction::IPUT_WIDE_QUICK, true);
+        break;
+
+      case Instruction::IPUT_OBJECT:
+        CompileInstanceFieldAccess(inst, dex_pc, Instruction::IPUT_OBJECT_QUICK, true);
+        break;
+
+      case Instruction::INVOKE_VIRTUAL:
+        CompileInvokeVirtual(inst, dex_pc, Instruction::INVOKE_VIRTUAL_QUICK, false);
+        break;
+
+      case Instruction::INVOKE_VIRTUAL_RANGE:
+        CompileInvokeVirtual(inst, dex_pc, Instruction::INVOKE_VIRTUAL_RANGE_QUICK, true);
+        break;
+
+      default:
+        // Nothing to do.
+        break;
+    }
+  }
+}
+
+void DexCompiler::CompileReturnVoid(Instruction* inst, uint32_t dex_pc) {
+  DCHECK(inst->Opcode() == Instruction::RETURN_VOID);
+  // Are we compiling a constructor ?
+  if ((unit_.GetAccessFlags() & kAccConstructor) == 0) {
+    return;
+  }
+  // Do we need a constructor barrier ?
+  if (!driver_.RequiresConstructorBarrier(Thread::Current(), unit_.GetDexFile(),
+                                         unit_.GetClassDefIndex())) {
+    return;
+  }
+  // Replace RETURN_VOID by RETURN_VOID_BARRIER.
+  if (kEnableLogging) {
+    LOG(INFO) << "Replacing " << Instruction::Name(inst->Opcode())
+    << " by " << Instruction::Name(Instruction::RETURN_VOID_BARRIER)
+    << " at dex pc " << StringPrintf("0x%x", dex_pc) << " in method "
+    << PrettyMethod(unit_.GetDexMethodIndex(), GetDexFile(), true);
+  }
+  ScopedDexWriteAccess sdwa(GetModifiableDexFile(), inst, 2u);
+  inst->SetOpcode(Instruction::RETURN_VOID_BARRIER);
+}
+
+void DexCompiler::CompileInstanceFieldAccess(Instruction* inst,
+                                             uint32_t dex_pc,
+                                             Instruction::Code new_opcode,
+                                             bool is_put) {
+  if (!kEnableQuickening) {
+    return;
+  }
+  uint32_t field_idx = inst->VRegC_22c();
+  int field_offset;
+  bool is_volatile;
+  bool fast_path = driver_.ComputeInstanceFieldInfo(field_idx, &unit_, field_offset,
+                                                    is_volatile, is_put);
+  if (fast_path && !is_volatile && IsUint(16, field_offset)) {
+    // TODO: use VLOG ?
+    if (kEnableLogging) {
+      LOG(INFO) << "Quickening " << Instruction::Name(inst->Opcode())
+                << " to " << Instruction::Name(new_opcode)
+                << " by replacing field index " << field_idx
+                << " by field offset " << field_offset
+                << " at dex pc " << StringPrintf("0x%x", dex_pc) << " in method "
+                << PrettyMethod(unit_.GetDexMethodIndex(), GetDexFile(), true);
+    }
+    // We are modifying 4 consecutive bytes.
+    ScopedDexWriteAccess sdwa(GetModifiableDexFile(), inst, 4u);
+    inst->SetOpcode(new_opcode);
+    // Replace field index by field offset.
+    inst->SetVRegC_22c(static_cast<uint16_t>(field_offset));
+  }
+}
+
+void DexCompiler::CompileInvokeVirtual(Instruction* inst,
+                                uint32_t dex_pc,
+                                Instruction::Code new_opcode,
+                                bool is_range) {
+  if (!kEnableQuickening) {
+    return;
+  }
+  uint32_t method_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c();
+  MethodReference target_method(&GetDexFile(), method_idx);
+  InvokeType invoke_type = kVirtual;
+  InvokeType original_invoke_type = invoke_type;
+  int vtable_idx;
+  uintptr_t direct_code;
+  uintptr_t direct_method;
+  bool fast_path = driver_.ComputeInvokeInfo(&unit_, dex_pc, invoke_type,
+                                             target_method, vtable_idx,
+                                             direct_code, direct_method,
+                                             false);
+  // TODO: support devirtualization.
+  if (fast_path && original_invoke_type == invoke_type) {
+    if (vtable_idx >= 0 && IsUint(16, vtable_idx)) {
+      // TODO: use VLOG ?
+      if (kEnableLogging) {
+        LOG(INFO) << "Quickening " << Instruction::Name(inst->Opcode())
+                  << "(" << PrettyMethod(method_idx, GetDexFile(), true) << ")"
+                  << " to " << Instruction::Name(new_opcode)
+                  << " by replacing method index " << method_idx
+                  << " by vtable index " << vtable_idx
+                  << " at dex pc " << StringPrintf("0x%x", dex_pc) << " in method "
+                  << PrettyMethod(unit_.GetDexMethodIndex(), GetDexFile(), true);
+      }
+      // We are modifying 4 consecutive bytes.
+      ScopedDexWriteAccess sdwa(GetModifiableDexFile(), inst, 4u);
+      inst->SetOpcode(new_opcode);
+      // Replace method index by vtable index.
+      if (is_range) {
+        inst->SetVRegB_3rc(static_cast<uint16_t>(vtable_idx));
+      } else {
+        inst->SetVRegB_35c(static_cast<uint16_t>(vtable_idx));
+      }
+    }
+  }
+}
+
+}  // namespace optimizer
+}  // namespace art
+
+extern "C" art::CompiledMethod*
+    ArtCompileDEX(art::CompilerDriver& compiler, const art::DexFile::CodeItem* code_item,
+                  uint32_t access_flags, art::InvokeType invoke_type,
+                  uint32_t class_def_idx, uint32_t method_idx, jobject class_loader,
+                  const art::DexFile& dex_file) {
+  art::DexCompilationUnit unit(NULL, class_loader, art::Runtime::Current()->GetClassLinker(),
+                               dex_file, code_item, class_def_idx, method_idx, access_flags);
+  art::optimizer::DexCompiler dex_compiler(compiler, unit);
+  dex_compiler.Compile();
+  return NULL;
+}
