API change in StackVisitor::GetVReg*.

- Remove GetVReg() and SetVReg() that were expecting to always succeed.
- Change Quick-only methods to take a FromQuickCode suffix.
- Change deopt to use dead values when GetVReg does not succeed:
  the optimizing compiler will not have a location for uninitialized
  Dex registers and potentially dead registers.

Change-Id: Ida05773a97aff8aa69e0caf42ea961f80f854b77
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index 0eb8eca..2432603 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -205,52 +205,97 @@
     ShadowFrame* new_frame = ShadowFrame::Create(num_regs, nullptr, h_method.Get(), dex_pc);
     self_->SetShadowFrameUnderConstruction(new_frame);
     const std::vector<int32_t> kinds(verifier.DescribeVRegs(dex_pc));
+
+    // Markers for dead values, used when the verifier knows a Dex register is undefined,
+    // or when the compiler knows the register has not been initialized, or is not used
+    // anymore in the method.
+    static constexpr uint32_t kDeadValue = 0xEBADDE09;
+    static constexpr uint64_t kLongDeadValue = 0xEBADDE09EBADDE09;
     for (uint16_t reg = 0; reg < num_regs; ++reg) {
       VRegKind kind = GetVRegKind(reg, kinds);
       switch (kind) {
         case kUndefined:
-          new_frame->SetVReg(reg, 0xEBADDE09);
+          new_frame->SetVReg(reg, kDeadValue);
           break;
         case kConstant:
           new_frame->SetVReg(reg, kinds.at((reg * 2) + 1));
           break;
-        case kReferenceVReg:
-          new_frame->SetVRegReference(reg,
-                                      reinterpret_cast<mirror::Object*>(GetVReg(h_method.Get(),
-                                                                                reg, kind)));
+        case kReferenceVReg: {
+          uint32_t value = 0;
+          if (GetVReg(h_method.Get(), reg, kind, &value)) {
+            new_frame->SetVRegReference(reg, reinterpret_cast<mirror::Object*>(value));
+          } else {
+            new_frame->SetVReg(reg, kDeadValue);
+          }
           break;
+        }
         case kLongLoVReg:
           if (GetVRegKind(reg + 1, kinds) == kLongHiVReg) {
             // Treat it as a "long" register pair.
-            new_frame->SetVRegLong(reg, GetVRegPair(h_method.Get(), reg, kLongLoVReg, kLongHiVReg));
+            uint64_t value = 0;
+            if (GetVRegPair(h_method.Get(), reg, kLongLoVReg, kLongHiVReg, &value)) {
+              new_frame->SetVRegLong(reg, value);
+            } else {
+              new_frame->SetVRegLong(reg, kLongDeadValue);
+            }
           } else {
-            new_frame->SetVReg(reg, GetVReg(h_method.Get(), reg, kind));
+            uint32_t value = 0;
+            if (GetVReg(h_method.Get(), reg, kind, &value)) {
+              new_frame->SetVReg(reg, value);
+            } else {
+              new_frame->SetVReg(reg, kDeadValue);
+            }
           }
           break;
         case kLongHiVReg:
           if (GetVRegKind(reg - 1, kinds) == kLongLoVReg) {
             // Nothing to do: we treated it as a "long" register pair.
           } else {
-            new_frame->SetVReg(reg, GetVReg(h_method.Get(), reg, kind));
+            uint32_t value = 0;
+            if (GetVReg(h_method.Get(), reg, kind, &value)) {
+              new_frame->SetVReg(reg, value);
+            } else {
+              new_frame->SetVReg(reg, kDeadValue);
+            }
           }
           break;
         case kDoubleLoVReg:
           if (GetVRegKind(reg + 1, kinds) == kDoubleHiVReg) {
-            // Treat it as a "double" register pair.
-            new_frame->SetVRegLong(reg, GetVRegPair(h_method.Get(), reg, kDoubleLoVReg, kDoubleHiVReg));
+            uint64_t value = 0;
+            if (GetVRegPair(h_method.Get(), reg, kDoubleLoVReg, kDoubleHiVReg, &value)) {
+              // Treat it as a "double" register pair.
+              new_frame->SetVRegLong(reg, value);
+            } else {
+              new_frame->SetVRegLong(reg, kLongDeadValue);
+            }
           } else {
-            new_frame->SetVReg(reg, GetVReg(h_method.Get(), reg, kind));
+            uint32_t value = 0;
+            if (GetVReg(h_method.Get(), reg, kind, &value)) {
+              new_frame->SetVReg(reg, value);
+            } else {
+              new_frame->SetVReg(reg, kDeadValue);
+            }
           }
           break;
         case kDoubleHiVReg:
           if (GetVRegKind(reg - 1, kinds) == kDoubleLoVReg) {
             // Nothing to do: we treated it as a "double" register pair.
           } else {
-            new_frame->SetVReg(reg, GetVReg(h_method.Get(), reg, kind));
+            uint32_t value = 0;
+            if (GetVReg(h_method.Get(), reg, kind, &value)) {
+              new_frame->SetVReg(reg, value);
+            } else {
+              new_frame->SetVReg(reg, kDeadValue);
+            }
           }
           break;
         default:
-          new_frame->SetVReg(reg, GetVReg(h_method.Get(), reg, kind));
+          uint32_t value = 0;
+          if (GetVReg(h_method.Get(), reg, kind, &value)) {
+            new_frame->SetVReg(reg, value);
+          } else {
+            new_frame->SetVReg(reg, kDeadValue);
+          }
           break;
       }
     }