Fix access to long/double stack values from debugger

Long and double values live in a pair of DEX registers. When we compile DEX
code with the Quick compiler, a DEX register either lives in the stack or is
promoted to a physical register. In the case of a pair of DEX registers, the
Quick compiler assumes both registers live in the same "area": both live in
the stack or both are promoted to physical registers.

From the debugger, we used to access these values by reading/writing each DEX
register separately. However, this does not work when only one DEX register of
a pair is promoted and the other lives in the stack. In this case, the compiled
code reads from/writes to the stack only.

To fix that, the debugger must follow the same rule than the Quick compiler: if
both DEX registers are promoted, read/write them from/to physical registers,
otherwise read/write them from/to the stack. We add StackVisitor:GetVRegPair and
StackVisitor:SetVRegPair for this purpose.

We also follow the same rule when deoptimizing. However we need to do that only
when we know two consecutive DEX registers are part of a pair (long or double).
We know that thanks to the verifier.

Bug: 15527793
Change-Id: I04812285ff26ef0129f39792a1cf776f3591ca2d
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 4cf4c09..e4ab9f5 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -2450,12 +2450,9 @@
         }
         case JDWP::JT_DOUBLE: {
           CHECK_EQ(width_, 8U);
-          uint32_t lo;
-          uint32_t hi;
-          if (GetVReg(m, reg, kDoubleLoVReg, &lo) && GetVReg(m, reg + 1, kDoubleHiVReg, &hi)) {
-            uint64_t longVal = (static_cast<uint64_t>(hi) << 32) | lo;
-            VLOG(jdwp) << "get double local " << reg << " = "
-                       << hi << ":" << lo << " = " << longVal;
+          uint64_t longVal;
+          if (GetVRegPair(m, reg, kDoubleLoVReg, kDoubleHiVReg, &longVal)) {
+            VLOG(jdwp) << "get double local " << reg << " = " << longVal;
             JDWP::Set8BE(buf_+1, longVal);
           } else {
             VLOG(jdwp) << "failed to get double local " << reg;
@@ -2465,12 +2462,9 @@
         }
         case JDWP::JT_LONG: {
           CHECK_EQ(width_, 8U);
-          uint32_t lo;
-          uint32_t hi;
-          if (GetVReg(m, reg, kLongLoVReg, &lo) && GetVReg(m, reg + 1, kLongHiVReg, &hi)) {
-            uint64_t longVal = (static_cast<uint64_t>(hi) << 32) | lo;
-            VLOG(jdwp) << "get long local " << reg << " = "
-                       << hi << ":" << lo << " = " << longVal;
+          uint64_t longVal;
+          if (GetVRegPair(m, reg, kLongLoVReg, kLongHiVReg, &longVal)) {
+            VLOG(jdwp) << "get long local " << reg << " = " << longVal;
             JDWP::Set8BE(buf_+1, longVal);
           } else {
             VLOG(jdwp) << "failed to get long local " << reg;
@@ -2593,28 +2587,18 @@
         }
         case JDWP::JT_DOUBLE: {
           CHECK_EQ(width_, 8U);
-          const uint32_t lo = static_cast<uint32_t>(value_);
-          const uint32_t hi = static_cast<uint32_t>(value_ >> 32);
-          bool success = SetVReg(m, reg, lo, kDoubleLoVReg);
-          success &= SetVReg(m, reg + 1, hi, kDoubleHiVReg);
+          bool success = SetVRegPair(m, reg, value_, kDoubleLoVReg, kDoubleHiVReg);
           if (!success) {
-            uint64_t longVal = (static_cast<uint64_t>(hi) << 32) | lo;
-            VLOG(jdwp) << "failed to set double local " << reg << " = "
-                       << hi << ":" << lo << " = " << longVal;
+            VLOG(jdwp) << "failed to set double local " << reg << " = " << value_;
             error_ = kFailureErrorCode;
           }
           break;
         }
         case JDWP::JT_LONG: {
           CHECK_EQ(width_, 8U);
-          const uint32_t lo = static_cast<uint32_t>(value_);
-          const uint32_t hi = static_cast<uint32_t>(value_ >> 32);
-          bool success = SetVReg(m, reg, lo, kLongLoVReg);
-          success &= SetVReg(m, reg + 1, hi, kLongHiVReg);
+          bool success = SetVRegPair(m, reg, value_, kLongLoVReg, kLongHiVReg);
           if (!success) {
-            uint64_t longVal = (static_cast<uint64_t>(hi) << 32) | lo;
-            VLOG(jdwp) << "failed to set double local " << reg << " = "
-                       << hi << ":" << lo << " = " << longVal;
+            VLOG(jdwp) << "failed to set double local " << reg << " = " << value_;
             error_ = kFailureErrorCode;
           }
           break;