Implement heap poisoning in ART's Optimizing compiler.

- Instrument ARM, ARM64, x86 and x86-64 code generators.
- Note: To turn heap poisoning on in Optimizing, set the
  environment variable `ART_HEAP_POISONING' to "true"
  before compiling ART.

Bug: 12687968
Change-Id: Ib3120b38cf805a8a50207a314b9ccc90c8d93740
diff --git a/compiler/utils/arm64/assembler_arm64.cc b/compiler/utils/arm64/assembler_arm64.cc
index 077579c..0e17512 100644
--- a/compiler/utils/arm64/assembler_arm64.cc
+++ b/compiler/utils/arm64/assembler_arm64.cc
@@ -298,15 +298,15 @@
 }
 
 void Arm64Assembler::LoadRef(ManagedRegister m_dst, ManagedRegister m_base, MemberOffset offs,
-                             bool poison_reference) {
+                             bool unpoison_reference) {
   Arm64ManagedRegister dst = m_dst.AsArm64();
   Arm64ManagedRegister base = m_base.AsArm64();
   CHECK(dst.IsXRegister() && base.IsXRegister());
   LoadWFromOffset(kLoadWord, dst.AsOverlappingWRegister(), base.AsXRegister(),
                   offs.Int32Value());
-  if (kPoisonHeapReferences && poison_reference) {
+  if (unpoison_reference) {
     WRegister ref_reg = dst.AsOverlappingWRegister();
-    ___ Neg(reg_w(ref_reg), vixl::Operand(reg_w(ref_reg)));
+    MaybeUnpoisonHeapReference(reg_w(ref_reg));
   }
 }
 
@@ -784,5 +784,25 @@
   cfi_.DefCFAOffset(frame_size);
 }
 
+void Arm64Assembler::PoisonHeapReference(vixl::Register reg) {
+  DCHECK(reg.IsW());
+  // reg = -reg.
+  ___ Neg(reg, vixl::Operand(reg));
+}
+
+void Arm64Assembler::UnpoisonHeapReference(vixl::Register reg) {
+  DCHECK(reg.IsW());
+  // reg = -reg.
+  ___ Neg(reg, vixl::Operand(reg));
+}
+
+void Arm64Assembler::MaybeUnpoisonHeapReference(vixl::Register reg) {
+  if (kPoisonHeapReferences) {
+    UnpoisonHeapReference(reg);
+  }
+}
+
+#undef ___
+
 }  // namespace arm64
 }  // namespace art