diff --git a/runtime/stack.cc b/runtime/stack.cc
index b39aebf..d570880 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -134,8 +134,7 @@
     } else {
       return cur_shadow_frame_->GetVRegReference(0);
     }
-  } else if (m->IsOptimized(GetInstructionSetPointerSize(
-      Runtime::Current()->GetInstructionSet()))) {
+  } else if (m->IsOptimized(sizeof(void*))) {
     // TODO: Implement, currently only used for exceptions when jdwp is enabled.
     UNIMPLEMENTED(WARNING)
         << "StackVisitor::GetThisObject is unimplemented with the optimizing compiler";
@@ -163,42 +162,10 @@
   if (cur_quick_frame_ != nullptr) {
     DCHECK(context_ != nullptr);  // You can't reliably read registers without a context.
     DCHECK(m == GetMethod());
-    const void* code_pointer = m->GetQuickOatCodePointer(sizeof(void*));
-    DCHECK(code_pointer != nullptr);
-    const VmapTable vmap_table(m->GetVmapTable(code_pointer, sizeof(void*)));
-    QuickMethodFrameInfo frame_info = m->GetQuickFrameInfo(code_pointer);
-    uint32_t vmap_offset;
-    // TODO: IsInContext stops before spotting floating point registers.
-    if (vmap_table.IsInContext(vreg, kind, &vmap_offset)) {
-      bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg);
-      uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask();
-      uint32_t reg = vmap_table.ComputeRegister(spill_mask, vmap_offset, kind);
-      if (!IsAccessibleRegister(reg, is_float)) {
-        return false;
-      }
-      uintptr_t ptr_val = GetRegister(reg, is_float);
-      bool target64 = Is64BitInstructionSet(kRuntimeISA);
-      if (target64) {
-        bool wide_lo = (kind == kLongLoVReg) || (kind == kDoubleLoVReg);
-        bool wide_hi = (kind == kLongHiVReg) || (kind == kDoubleHiVReg);
-        int64_t value_long = static_cast<int64_t>(ptr_val);
-        if (wide_lo) {
-          ptr_val = static_cast<uintptr_t>(value_long & 0xFFFFFFFF);
-        } else if (wide_hi) {
-          ptr_val = static_cast<uintptr_t>(value_long >> 32);
-        }
-      }
-      *val = ptr_val;
-      return true;
+    if (m->IsOptimized(sizeof(void*))) {
+      return GetVRegFromOptimizedCode(m, vreg, kind, val);
     } else {
-      const DexFile::CodeItem* code_item = m->GetCodeItem();
-      DCHECK(code_item != nullptr) << PrettyMethod(m);  // Can't be NULL or how would we compile
-                                                        // its instructions?
-      uint32_t* addr = GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(),
-                                   frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg);
-      DCHECK(addr != nullptr);
-      *val = *addr;
-      return true;
+      return GetVRegFromQuickCode(m, vreg, kind, val);
     }
   } else {
     DCHECK(cur_shadow_frame_ != nullptr);
@@ -207,6 +174,86 @@
   }
 }
 
+bool StackVisitor::GetVRegFromQuickCode(mirror::ArtMethod* m, uint16_t vreg, VRegKind kind,
+                                        uint32_t* val) const {
+  const void* code_pointer = m->GetQuickOatCodePointer(sizeof(void*));
+  DCHECK(code_pointer != nullptr);
+  const VmapTable vmap_table(m->GetVmapTable(code_pointer, sizeof(void*)));
+  QuickMethodFrameInfo frame_info = m->GetQuickFrameInfo(code_pointer);
+  uint32_t vmap_offset;
+  // TODO: IsInContext stops before spotting floating point registers.
+  if (vmap_table.IsInContext(vreg, kind, &vmap_offset)) {
+    bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg);
+    uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask();
+    uint32_t reg = vmap_table.ComputeRegister(spill_mask, vmap_offset, kind);
+    return GetRegisterIfAccessible(reg, kind, val);
+  } else {
+    const DexFile::CodeItem* code_item = m->GetCodeItem();
+    DCHECK(code_item != nullptr) << PrettyMethod(m);  // Can't be NULL or how would we compile
+                                                      // its instructions?
+    *val = *GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(),
+                        frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg);
+    return true;
+  }
+}
+
+bool StackVisitor::GetVRegFromOptimizedCode(mirror::ArtMethod* m, uint16_t vreg, VRegKind kind,
+                                            uint32_t* val) const {
+  const void* code_pointer = m->GetQuickOatCodePointer(sizeof(void*));
+  DCHECK(code_pointer != nullptr);
+  uint32_t native_pc_offset = m->NativeQuickPcOffset(cur_quick_frame_pc_);
+  CodeInfo code_info = m->GetOptimizedCodeInfo();
+  StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
+  const DexFile::CodeItem* code_item = m->GetCodeItem();
+  DCHECK(code_item != nullptr) << PrettyMethod(m);  // Can't be NULL or how would we compile
+                                                    // its instructions?
+  DCHECK_LT(vreg, code_item->registers_size_);
+  DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map,
+                                                                  code_item->registers_size_);
+  DexRegisterMap::LocationKind location_kind = dex_register_map.GetLocationKind(vreg);
+  switch (location_kind) {
+    case DexRegisterMap::kInStack: {
+      const int32_t offset = dex_register_map.GetStackOffsetInBytes(vreg);
+      const uint8_t* addr = reinterpret_cast<const uint8_t*>(cur_quick_frame_) + offset;
+      *val = *reinterpret_cast<const uint32_t*>(addr);
+      return true;
+    }
+    case DexRegisterMap::kInRegister:
+    case DexRegisterMap::kInFpuRegister: {
+      uint32_t reg = dex_register_map.GetMachineRegister(vreg);
+      return GetRegisterIfAccessible(reg, kind, val);
+    }
+    case DexRegisterMap::kConstant:
+      *val = dex_register_map.GetConstant(vreg);
+      return true;
+    case DexRegisterMap::kNone:
+      return false;
+  }
+  UNREACHABLE();
+  return false;
+}
+
+bool StackVisitor::GetRegisterIfAccessible(uint32_t reg, VRegKind kind, uint32_t* val) const {
+  const bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg);
+  if (!IsAccessibleRegister(reg, is_float)) {
+    return false;
+  }
+  uintptr_t ptr_val = GetRegister(reg, is_float);
+  const bool target64 = Is64BitInstructionSet(kRuntimeISA);
+  if (target64) {
+    const bool wide_lo = (kind == kLongLoVReg) || (kind == kDoubleLoVReg);
+    const bool wide_hi = (kind == kLongHiVReg) || (kind == kDoubleHiVReg);
+    int64_t value_long = static_cast<int64_t>(ptr_val);
+    if (wide_lo) {
+      ptr_val = static_cast<uintptr_t>(Low32Bits(value_long));
+    } else if (wide_hi) {
+      ptr_val = static_cast<uintptr_t>(High32Bits(value_long));
+    }
+  }
+  *val = ptr_val;
+  return true;
+}
+
 bool StackVisitor::GetVRegPair(mirror::ArtMethod* m, uint16_t vreg, VRegKind kind_lo,
                                VRegKind kind_hi, uint64_t* val) const {
   if (kind_lo == kLongLoVReg) {
@@ -215,45 +262,15 @@
     DCHECK_EQ(kind_hi, kDoubleHiVReg);
   } else {
     LOG(FATAL) << "Expected long or double: kind_lo=" << kind_lo << ", kind_hi=" << kind_hi;
+    UNREACHABLE();
   }
   if (cur_quick_frame_ != nullptr) {
     DCHECK(context_ != nullptr);  // You can't reliably read registers without a context.
     DCHECK(m == GetMethod());
-    const void* code_pointer = m->GetQuickOatCodePointer(sizeof(void*));
-    DCHECK(code_pointer != nullptr);
-    const VmapTable vmap_table(m->GetVmapTable(code_pointer, sizeof(void*)));
-    QuickMethodFrameInfo frame_info = m->GetQuickFrameInfo(code_pointer);
-    uint32_t vmap_offset_lo, vmap_offset_hi;
-    // TODO: IsInContext stops before spotting floating point registers.
-    if (vmap_table.IsInContext(vreg, kind_lo, &vmap_offset_lo) &&
-        vmap_table.IsInContext(vreg + 1, kind_hi, &vmap_offset_hi)) {
-      bool is_float = (kind_lo == kDoubleLoVReg);
-      uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask();
-      uint32_t reg_lo = vmap_table.ComputeRegister(spill_mask, vmap_offset_lo, kind_lo);
-      uint32_t reg_hi = vmap_table.ComputeRegister(spill_mask, vmap_offset_hi, kind_hi);
-      if (!IsAccessibleRegister(reg_lo, is_float) || !IsAccessibleRegister(reg_hi, is_float)) {
-        return false;
-      }
-      uintptr_t ptr_val_lo = GetRegister(reg_lo, is_float);
-      uintptr_t ptr_val_hi = GetRegister(reg_hi, is_float);
-      bool target64 = Is64BitInstructionSet(kRuntimeISA);
-      if (target64) {
-        int64_t value_long_lo = static_cast<int64_t>(ptr_val_lo);
-        int64_t value_long_hi = static_cast<int64_t>(ptr_val_hi);
-        ptr_val_lo = static_cast<uintptr_t>(value_long_lo & 0xFFFFFFFF);
-        ptr_val_hi = static_cast<uintptr_t>(value_long_hi >> 32);
-      }
-      *val = (static_cast<uint64_t>(ptr_val_hi) << 32) | static_cast<uint32_t>(ptr_val_lo);
-      return true;
+    if (m->IsOptimized(sizeof(void*))) {
+      return GetVRegPairFromOptimizedCode(m, vreg, kind_lo, kind_hi, val);
     } else {
-      const DexFile::CodeItem* code_item = m->GetCodeItem();
-      DCHECK(code_item != nullptr) << PrettyMethod(m);  // Can't be NULL or how would we compile
-                                                        // its instructions?
-      uint32_t* addr = GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(),
-                                   frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg);
-      DCHECK(addr != nullptr);
-      *val = *reinterpret_cast<uint64_t*>(addr);
-      return true;
+      return GetVRegPairFromQuickCode(m, vreg, kind_lo, kind_hi, val);
     }
   } else {
     DCHECK(cur_shadow_frame_ != nullptr);
@@ -262,61 +279,185 @@
   }
 }
 
+bool StackVisitor::GetVRegPairFromQuickCode(mirror::ArtMethod* m, uint16_t vreg, VRegKind kind_lo,
+                                            VRegKind kind_hi, uint64_t* val) const {
+  const void* code_pointer = m->GetQuickOatCodePointer(sizeof(void*));
+  DCHECK(code_pointer != nullptr);
+  const VmapTable vmap_table(m->GetVmapTable(code_pointer, sizeof(void*)));
+  QuickMethodFrameInfo frame_info = m->GetQuickFrameInfo(code_pointer);
+  uint32_t vmap_offset_lo, vmap_offset_hi;
+  // TODO: IsInContext stops before spotting floating point registers.
+  if (vmap_table.IsInContext(vreg, kind_lo, &vmap_offset_lo) &&
+      vmap_table.IsInContext(vreg + 1, kind_hi, &vmap_offset_hi)) {
+    bool is_float = (kind_lo == kDoubleLoVReg);
+    uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask();
+    uint32_t reg_lo = vmap_table.ComputeRegister(spill_mask, vmap_offset_lo, kind_lo);
+    uint32_t reg_hi = vmap_table.ComputeRegister(spill_mask, vmap_offset_hi, kind_hi);
+    return GetRegisterPairIfAccessible(reg_lo, reg_hi, kind_lo, val);
+  } else {
+    const DexFile::CodeItem* code_item = m->GetCodeItem();
+    DCHECK(code_item != nullptr) << PrettyMethod(m);  // Can't be NULL or how would we compile
+                                                      // its instructions?
+    uint32_t* addr = GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(),
+                                 frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg);
+    *val = *reinterpret_cast<uint64_t*>(addr);
+    return true;
+  }
+}
+
+bool StackVisitor::GetVRegPairFromOptimizedCode(mirror::ArtMethod* m, uint16_t vreg,
+                                                VRegKind kind_lo, VRegKind kind_hi,
+                                                uint64_t* val) const {
+  uint32_t low_32bits;
+  uint32_t high_32bits;
+  bool success = GetVRegFromOptimizedCode(m, vreg, kind_lo, &low_32bits);
+  success &= GetVRegFromOptimizedCode(m, vreg + 1, kind_hi, &high_32bits);
+  if (success) {
+    *val = (static_cast<uint64_t>(high_32bits) << 32) | static_cast<uint64_t>(low_32bits);
+  }
+  return success;
+}
+
+bool StackVisitor::GetRegisterPairIfAccessible(uint32_t reg_lo, uint32_t reg_hi,
+                                               VRegKind kind_lo, uint64_t* val) const {
+  const bool is_float = (kind_lo == kDoubleLoVReg);
+  if (!IsAccessibleRegister(reg_lo, is_float) || !IsAccessibleRegister(reg_hi, is_float)) {
+    return false;
+  }
+  uintptr_t ptr_val_lo = GetRegister(reg_lo, is_float);
+  uintptr_t ptr_val_hi = GetRegister(reg_hi, is_float);
+  bool target64 = Is64BitInstructionSet(kRuntimeISA);
+  if (target64) {
+    int64_t value_long_lo = static_cast<int64_t>(ptr_val_lo);
+    int64_t value_long_hi = static_cast<int64_t>(ptr_val_hi);
+    ptr_val_lo = static_cast<uintptr_t>(Low32Bits(value_long_lo));
+    ptr_val_hi = static_cast<uintptr_t>(High32Bits(value_long_hi));
+  }
+  *val = (static_cast<uint64_t>(ptr_val_hi) << 32) | static_cast<uint32_t>(ptr_val_lo);
+  return true;
+}
+
 bool StackVisitor::SetVReg(mirror::ArtMethod* m, uint16_t vreg, uint32_t new_value,
                            VRegKind kind) {
   if (cur_quick_frame_ != nullptr) {
-    DCHECK(context_ != nullptr);  // You can't reliably write registers without a context.
-    DCHECK(m == GetMethod());
-    const void* code_pointer = m->GetQuickOatCodePointer(sizeof(void*));
-    DCHECK(code_pointer != nullptr);
-    const VmapTable vmap_table(m->GetVmapTable(code_pointer, sizeof(void*)));
-    QuickMethodFrameInfo frame_info = m->GetQuickFrameInfo(code_pointer);
-    uint32_t vmap_offset;
-    // TODO: IsInContext stops before spotting floating point registers.
-    if (vmap_table.IsInContext(vreg, kind, &vmap_offset)) {
-      bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg);
-      uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask();
-      const uint32_t reg = vmap_table.ComputeRegister(spill_mask, vmap_offset, kind);
-      if (!IsAccessibleRegister(reg, is_float)) {
-        return false;
+      DCHECK(context_ != nullptr);  // You can't reliably write registers without a context.
+      DCHECK(m == GetMethod());
+      if (m->IsOptimized(sizeof(void*))) {
+        return SetVRegFromOptimizedCode(m, vreg, new_value, kind);
+      } else {
+        return SetVRegFromQuickCode(m, vreg, new_value, kind);
       }
-      bool target64 = Is64BitInstructionSet(kRuntimeISA);
-      // Deal with 32 or 64-bit wide registers in a way that builds on all targets.
-      if (target64) {
-        bool wide_lo = (kind == kLongLoVReg) || (kind == kDoubleLoVReg);
-        bool wide_hi = (kind == kLongHiVReg) || (kind == kDoubleHiVReg);
-        if (wide_lo || wide_hi) {
-          uintptr_t old_reg_val = GetRegister(reg, is_float);
-          uint64_t new_vreg_portion = static_cast<uint64_t>(new_value);
-          uint64_t old_reg_val_as_wide = static_cast<uint64_t>(old_reg_val);
-          uint64_t mask = 0xffffffff;
-          if (wide_lo) {
-            mask = mask << 32;
-          } else {
-            new_vreg_portion = new_vreg_portion << 32;
-          }
-          new_value = static_cast<uintptr_t>((old_reg_val_as_wide & mask) | new_vreg_portion);
-        }
-      }
-      SetRegister(reg, new_value, is_float);
-      return true;
     } else {
-      const DexFile::CodeItem* code_item = m->GetCodeItem();
-      DCHECK(code_item != nullptr) << PrettyMethod(m);  // Can't be NULL or how would we compile
-                                                        // its instructions?
-      uint32_t* addr = GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(),
-                                   frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg);
-      DCHECK(addr != nullptr);
-      *addr = new_value;
+      cur_shadow_frame_->SetVReg(vreg, new_value);
       return true;
     }
+}
+
+bool StackVisitor::SetVRegFromQuickCode(mirror::ArtMethod* m, uint16_t vreg, uint32_t new_value,
+                                        VRegKind kind) {
+  DCHECK(context_ != nullptr);  // You can't reliably write registers without a context.
+  DCHECK(m == GetMethod());
+  const void* code_pointer = m->GetQuickOatCodePointer(sizeof(void*));
+  DCHECK(code_pointer != nullptr);
+  const VmapTable vmap_table(m->GetVmapTable(code_pointer, sizeof(void*)));
+  QuickMethodFrameInfo frame_info = m->GetQuickFrameInfo(code_pointer);
+  uint32_t vmap_offset;
+  // TODO: IsInContext stops before spotting floating point registers.
+  if (vmap_table.IsInContext(vreg, kind, &vmap_offset)) {
+    bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg);
+    uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask();
+    uint32_t reg = vmap_table.ComputeRegister(spill_mask, vmap_offset, kind);
+    return SetRegisterIfAccessible(reg, new_value, kind);
   } else {
-    DCHECK(cur_shadow_frame_ != nullptr);
-    cur_shadow_frame_->SetVReg(vreg, new_value);
+    const DexFile::CodeItem* code_item = m->GetCodeItem();
+    DCHECK(code_item != nullptr) << PrettyMethod(m);  // Can't be NULL or how would we compile
+                                                      // its instructions?
+    uint32_t* addr = GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(),
+                                 frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg);
+    *addr = new_value;
     return true;
   }
 }
 
+bool StackVisitor::SetVRegFromOptimizedCode(mirror::ArtMethod* m, uint16_t vreg, uint32_t new_value,
+                                            VRegKind kind) {
+  const void* code_pointer = m->GetQuickOatCodePointer(sizeof(void*));
+  DCHECK(code_pointer != nullptr);
+  uint32_t native_pc_offset = m->NativeQuickPcOffset(cur_quick_frame_pc_);
+  CodeInfo code_info = m->GetOptimizedCodeInfo();
+  StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
+  const DexFile::CodeItem* code_item = m->GetCodeItem();
+  DCHECK(code_item != nullptr) << PrettyMethod(m);  // Can't be NULL or how would we compile
+                                                    // its instructions?
+  DCHECK_LT(vreg, code_item->registers_size_);
+  DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map,
+                                                                  code_item->registers_size_);
+  DexRegisterMap::LocationKind location_kind = dex_register_map.GetLocationKind(vreg);
+  uint32_t dex_pc = m->ToDexPc(cur_quick_frame_pc_, false);
+  switch (location_kind) {
+    case DexRegisterMap::kInStack: {
+      const int32_t offset = dex_register_map.GetStackOffsetInBytes(vreg);
+      uint8_t* addr = reinterpret_cast<uint8_t*>(cur_quick_frame_) + offset;
+      *reinterpret_cast<uint32_t*>(addr) = new_value;
+      return true;
+    }
+    case DexRegisterMap::kInRegister:
+    case DexRegisterMap::kInFpuRegister: {
+      uint32_t reg = dex_register_map.GetMachineRegister(vreg);
+      return SetRegisterIfAccessible(reg, new_value, kind);
+    }
+    case DexRegisterMap::kConstant:
+      LOG(ERROR) << StringPrintf("Cannot change value of DEX register v%u used as a constant at "
+                                 "DEX pc 0x%x (native pc 0x%x) of method %s",
+                                 vreg, dex_pc, native_pc_offset,
+                                 PrettyMethod(cur_quick_frame_->AsMirrorPtr()).c_str());
+      return false;
+    case DexRegisterMap::kNone:
+      LOG(ERROR) << StringPrintf("No location for DEX register v%u at DEX pc 0x%x "
+                                 "(native pc 0x%x) of method %s",
+                                 vreg, dex_pc, native_pc_offset,
+                                 PrettyMethod(cur_quick_frame_->AsMirrorPtr()).c_str());
+      return false;
+    default:
+      LOG(FATAL) << StringPrintf("Unknown location for DEX register v%u at DEX pc 0x%x "
+                                 "(native pc 0x%x) of method %s",
+                                 vreg, dex_pc, native_pc_offset,
+                                 PrettyMethod(cur_quick_frame_->AsMirrorPtr()).c_str());
+      UNREACHABLE();
+  }
+}
+
+bool StackVisitor::SetRegisterIfAccessible(uint32_t reg, uint32_t new_value, VRegKind kind) {
+  const bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg);
+  if (!IsAccessibleRegister(reg, is_float)) {
+    return false;
+  }
+  const bool target64 = Is64BitInstructionSet(kRuntimeISA);
+
+  // Create a new value that can hold both low 32 and high 32 bits, in
+  // case we are running 64 bits.
+  uintptr_t full_new_value = new_value;
+  // Deal with 32 or 64-bit wide registers in a way that builds on all targets.
+  if (target64) {
+    bool wide_lo = (kind == kLongLoVReg) || (kind == kDoubleLoVReg);
+    bool wide_hi = (kind == kLongHiVReg) || (kind == kDoubleHiVReg);
+    if (wide_lo || wide_hi) {
+      uintptr_t old_reg_val = GetRegister(reg, is_float);
+      uint64_t new_vreg_portion = static_cast<uint64_t>(new_value);
+      uint64_t old_reg_val_as_wide = static_cast<uint64_t>(old_reg_val);
+      uint64_t mask = 0xffffffff;
+      if (wide_lo) {
+        mask = mask << 32;
+      } else {
+        new_vreg_portion = new_vreg_portion << 32;
+      }
+      full_new_value = static_cast<uintptr_t>((old_reg_val_as_wide & mask) | new_vreg_portion);
+    }
+  }
+  SetRegister(reg, full_new_value, is_float);
+  return true;
+}
+
 bool StackVisitor::SetVRegPair(mirror::ArtMethod* m, uint16_t vreg, uint64_t new_value,
                                VRegKind kind_lo, VRegKind kind_hi) {
   if (kind_lo == kLongLoVReg) {
@@ -329,49 +470,10 @@
   if (cur_quick_frame_ != nullptr) {
     DCHECK(context_ != nullptr);  // You can't reliably write registers without a context.
     DCHECK(m == GetMethod());
-    const void* code_pointer = m->GetQuickOatCodePointer(sizeof(void*));
-    DCHECK(code_pointer != nullptr);
-    const VmapTable vmap_table(m->GetVmapTable(code_pointer, sizeof(void*)));
-    QuickMethodFrameInfo frame_info = m->GetQuickFrameInfo(code_pointer);
-    uint32_t vmap_offset_lo, vmap_offset_hi;
-    // TODO: IsInContext stops before spotting floating point registers.
-    if (vmap_table.IsInContext(vreg, kind_lo, &vmap_offset_lo) &&
-        vmap_table.IsInContext(vreg + 1, kind_hi, &vmap_offset_hi)) {
-      bool is_float = (kind_lo == kDoubleLoVReg);
-      uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask();
-      uint32_t reg_lo = vmap_table.ComputeRegister(spill_mask, vmap_offset_lo, kind_lo);
-      uint32_t reg_hi = vmap_table.ComputeRegister(spill_mask, vmap_offset_hi, kind_hi);
-      if (!IsAccessibleRegister(reg_lo, is_float) || !IsAccessibleRegister(reg_hi, is_float)) {
-        return false;
-      }
-      uintptr_t new_value_lo = static_cast<uintptr_t>(new_value & 0xFFFFFFFF);
-      uintptr_t new_value_hi = static_cast<uintptr_t>(new_value >> 32);
-      bool target64 = Is64BitInstructionSet(kRuntimeISA);
-      // Deal with 32 or 64-bit wide registers in a way that builds on all targets.
-      if (target64) {
-        uintptr_t old_reg_val_lo = GetRegister(reg_lo, is_float);
-        uintptr_t old_reg_val_hi = GetRegister(reg_hi, is_float);
-        uint64_t new_vreg_portion_lo = static_cast<uint64_t>(new_value_lo);
-        uint64_t new_vreg_portion_hi = static_cast<uint64_t>(new_value_hi) << 32;
-        uint64_t old_reg_val_lo_as_wide = static_cast<uint64_t>(old_reg_val_lo);
-        uint64_t old_reg_val_hi_as_wide = static_cast<uint64_t>(old_reg_val_hi);
-        uint64_t mask_lo = static_cast<uint64_t>(0xffffffff) << 32;
-        uint64_t mask_hi = 0xffffffff;
-        new_value_lo = static_cast<uintptr_t>((old_reg_val_lo_as_wide & mask_lo) | new_vreg_portion_lo);
-        new_value_hi = static_cast<uintptr_t>((old_reg_val_hi_as_wide & mask_hi) | new_vreg_portion_hi);
-      }
-      SetRegister(reg_lo, new_value_lo, is_float);
-      SetRegister(reg_hi, new_value_hi, is_float);
-      return true;
+    if (m->IsOptimized(sizeof(void*))) {
+      return SetVRegPairFromOptimizedCode(m, vreg, new_value, kind_lo, kind_hi);
     } else {
-      const DexFile::CodeItem* code_item = m->GetCodeItem();
-      DCHECK(code_item != nullptr) << PrettyMethod(m);  // Can't be NULL or how would we compile
-                                                        // its instructions?
-      uint32_t* addr = GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(),
-                                   frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg);
-      DCHECK(addr != nullptr);
-      *reinterpret_cast<uint64_t*>(addr) = new_value;
-      return true;
+      return SetVRegPairFromQuickCode(m, vreg, new_value, kind_lo, kind_hi);
     }
   } else {
     DCHECK(cur_shadow_frame_ != nullptr);
@@ -380,6 +482,60 @@
   }
 }
 
+bool StackVisitor::SetVRegPairFromQuickCode(mirror::ArtMethod* m, uint16_t vreg, uint64_t new_value,
+                                            VRegKind kind_lo, VRegKind kind_hi) {
+  const void* code_pointer = m->GetQuickOatCodePointer(sizeof(void*));
+  DCHECK(code_pointer != nullptr);
+  const VmapTable vmap_table(m->GetVmapTable(code_pointer, sizeof(void*)));
+  QuickMethodFrameInfo frame_info = m->GetQuickFrameInfo(code_pointer);
+  uint32_t vmap_offset_lo, vmap_offset_hi;
+  // TODO: IsInContext stops before spotting floating point registers.
+  if (vmap_table.IsInContext(vreg, kind_lo, &vmap_offset_lo) &&
+      vmap_table.IsInContext(vreg + 1, kind_hi, &vmap_offset_hi)) {
+    bool is_float = (kind_lo == kDoubleLoVReg);
+    uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask();
+    uint32_t reg_lo = vmap_table.ComputeRegister(spill_mask, vmap_offset_lo, kind_lo);
+    uint32_t reg_hi = vmap_table.ComputeRegister(spill_mask, vmap_offset_hi, kind_hi);
+    return SetRegisterPairIfAccessible(reg_lo, reg_hi, new_value, is_float);
+  } else {
+    const DexFile::CodeItem* code_item = m->GetCodeItem();
+    DCHECK(code_item != nullptr) << PrettyMethod(m);  // Can't be NULL or how would we compile
+                                                      // its instructions?
+    uint32_t* addr = GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(),
+                                 frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg);
+    *reinterpret_cast<uint64_t*>(addr) = new_value;
+    return true;
+  }
+}
+
+bool StackVisitor::SetVRegPairFromOptimizedCode(mirror::ArtMethod* m, uint16_t vreg, uint64_t new_value,
+                                                VRegKind kind_lo, VRegKind kind_hi) {
+  uint32_t low_32bits = Low32Bits(new_value);
+  uint32_t high_32bits = High32Bits(new_value);
+  bool success = SetVRegFromOptimizedCode(m, vreg, low_32bits, kind_lo);
+  success &= SetVRegFromOptimizedCode(m, vreg + 1, high_32bits, kind_hi);
+  return success;
+}
+
+bool StackVisitor::SetRegisterPairIfAccessible(uint32_t reg_lo, uint32_t reg_hi,
+                                               uint64_t new_value, bool is_float) {
+  if (!IsAccessibleRegister(reg_lo, is_float) || !IsAccessibleRegister(reg_hi, is_float)) {
+    return false;
+  }
+  uintptr_t new_value_lo = static_cast<uintptr_t>(new_value & 0xFFFFFFFF);
+  uintptr_t new_value_hi = static_cast<uintptr_t>(new_value >> 32);
+  bool target64 = Is64BitInstructionSet(kRuntimeISA);
+  // Deal with 32 or 64-bit wide registers in a way that builds on all targets.
+  if (target64) {
+    DCHECK_EQ(reg_lo, reg_hi);
+    SetRegister(reg_lo, new_value, is_float);
+  } else {
+    SetRegister(reg_lo, new_value_lo, is_float);
+    SetRegister(reg_hi, new_value_hi, is_float);
+  }
+  return true;
+}
+
 bool StackVisitor::IsAccessibleGPR(uint32_t reg) const {
   DCHECK(context_ != nullptr);
   return context_->IsAccessibleGPR(reg);
