arm nterp: Add support for heap poisoning.

Test: testrunner.py --target --jit --32
Change-Id: I6a5f1bc3d3d30feff7bb8d1528adebafdd24e20b
diff --git a/runtime/interpreter/mterp/armng/array.S b/runtime/interpreter/mterp/armng/array.S
index e685cbf..008081c 100644
--- a/runtime/interpreter/mterp/armng/array.S
+++ b/runtime/interpreter/mterp/armng/array.S
@@ -26,6 +26,7 @@
     GOTO_OPCODE ip                      @ jump to next instruction
     .elseif $is_object
     $load   r2, [r0, #$data_offset]     @ w2<- vBB[vCC]
+    UNPOISON_HEAP_REF r2
     TEST_IF_MARKING 2f
 1:
     GET_INST_OPCODE ip                  @ extract opcode from rINST
diff --git a/runtime/interpreter/mterp/armng/invoke.S b/runtime/interpreter/mterp/armng/invoke.S
index f12b18f..a4f76d8 100644
--- a/runtime/interpreter/mterp/armng/invoke.S
+++ b/runtime/interpreter/mterp/armng/invoke.S
@@ -87,6 +87,7 @@
    GET_VREG r1, r1
    // Note: if r1 is null, this will be handled by our SIGSEGV handler.
    ldr r2, [r1, #MIRROR_OBJECT_CLASS_OFFSET]
+   UNPOISON_HEAP_REF r2
    // Test the first two bits of the fetched ArtMethod:
    // - If the first bit is set, this is a method on j.l.Object
    // - If the second bit is set, this is a default method.
@@ -162,6 +163,7 @@
    GET_VREG r1, r1
    // Note: if r1 is null, this will be handled by our SIGSEGV handler.
    ldr r0, [r1, #MIRROR_OBJECT_CLASS_OFFSET]
+   UNPOISON_HEAP_REF r0
    add r0, r0, #MIRROR_CLASS_VTABLE_OFFSET_32
    ldr r0, [r0, r2, lsl #2]
    b $helper
diff --git a/runtime/interpreter/mterp/armng/main.S b/runtime/interpreter/mterp/armng/main.S
index 1e528d4..a6af738 100644
--- a/runtime/interpreter/mterp/armng/main.S
+++ b/runtime/interpreter/mterp/armng/main.S
@@ -1451,6 +1451,12 @@
    GOTO_OPCODE ip
 .endm
 
+.macro POISON_HEAP_REF_IF_OBJECT is_object, rRef
+   .if \is_object
+   POISON_HEAP_REF \rRef
+   .endif
+.endm
+
 .macro WRITE_BARRIER_IF_OBJECT is_object, value, holder, label, tmp
    .if \is_object
    // In T32, we would use `SMART_CBZ \value, \label`
diff --git a/runtime/interpreter/mterp/armng/object.S b/runtime/interpreter/mterp/armng/object.S
index cde8cf9..9188592 100644
--- a/runtime/interpreter/mterp/armng/object.S
+++ b/runtime/interpreter/mterp/armng/object.S
@@ -8,6 +8,7 @@
    cmp     r0, #0
    beq     .L${opcode}_resume
    ldr     r2, [r0, #MIRROR_OBJECT_CLASS_OFFSET]
+   UNPOISON_HEAP_REF r2
    // Fast path: do a comparison without read barrier.
    cmp     r1, r2
    bne     ${slow_path}
@@ -29,10 +30,12 @@
    tst     r3, #MIRROR_CLASS_IS_INTERFACE_FLAG
    bne     2f
    ldr     r3, [r1, #MIRROR_CLASS_COMPONENT_TYPE_OFFSET]
+   UNPOISON_HEAP_REF r3
    cmp     r3, #0
    bne     5f
 1:
    ldr     r2, [r2, #MIRROR_CLASS_SUPER_CLASS_OFFSET]
+   UNPOISON_HEAP_REF r2
    cmp     r1, r2
    beq     .L${opcode}_resume
    cmp     r2, #0
@@ -49,10 +52,12 @@
 5:
    // Class in r1 is an array, r3 is the component type.
    ldr     r2, [r2, #MIRROR_CLASS_COMPONENT_TYPE_OFFSET]
+   UNPOISON_HEAP_REF r2
    // Check if object is an array.
    cmp     r2, #0
    beq     2b
    ldr     r4, [r3, #MIRROR_CLASS_SUPER_CLASS_OFFSET]
+   UNPOISON_HEAP_REF r4
    cmp     r4, #0
    // If the super class of the component type is not null, go slow path.
    bne     2b
@@ -75,6 +80,7 @@
    cmp     r0, #0
    beq     .L${opcode}_resume
    ldr     r2, [r0, #MIRROR_OBJECT_CLASS_OFFSET]
+   UNPOISON_HEAP_REF r2
    // Fast path: do a comparison without read barrier.
    cmp     r1, r2
    bne     ${slow_path}
@@ -103,10 +109,12 @@
    tst     r3, #MIRROR_CLASS_IS_INTERFACE_FLAG
    bne     5f
    ldr     r3, [r1, #MIRROR_CLASS_COMPONENT_TYPE_OFFSET]
+   UNPOISON_HEAP_REF r3
    cmp     r3, #0
    bne     3f
 1:
    ldr     r2, [r2, #MIRROR_CLASS_SUPER_CLASS_OFFSET]
+   UNPOISON_HEAP_REF r2
    cmp     r1, r2
    beq     .L${opcode}_set_one
    cmp     r2, #0
@@ -117,10 +125,12 @@
 3:
    // Class in r1 is an array, r3 is the component type.
    ldr     r2, [r2, #MIRROR_CLASS_COMPONENT_TYPE_OFFSET]
+   UNPOISON_HEAP_REF r2
    // Check if object is an array.
    cmp     r2, #0
    beq     2b
    ldr     r4, [r3, #MIRROR_CLASS_SUPER_CLASS_OFFSET]
+   UNPOISON_HEAP_REF r4
    cmp     r4, #0
    bne     5f
    ldrh    r3, [r3, #MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET]
@@ -167,6 +177,7 @@
    SET_VREG_WIDE_BY_ADDR r0, r1, r2    // fp[A] <- value
    .elseif $is_object
    $load   r0, [r3, r0]
+   UNPOISON_HEAP_REF r0
    TEST_IF_MARKING .L${opcode}_read_barrier
 .L${opcode}_resume_after_read_barrier:
    SET_VREG_OBJECT r0, r2              // fp[A] <- value
@@ -209,6 +220,7 @@
    $load   r0, [r3, r0]
    dmb     ish
    .if $is_object
+   UNPOISON_HEAP_REF r0
    TEST_IF_MARKING .L${opcode}_read_barrier
    SET_VREG_OBJECT r0, r2              // fp[A] <- value
    .else
@@ -257,6 +269,7 @@
    add     r1, r1, r0
    strd    r2, r3, [r1]
    .else
+   POISON_HEAP_REF_IF_OBJECT $is_object, r4
    $store  r4, [r1, r0]
    WRITE_BARRIER_IF_OBJECT $is_object, r4, r1, .L${opcode}_skip_write_barrier, r0
    .endif
@@ -301,6 +314,7 @@
    cmp     r1, #0
    beq     common_errNullObject
    dmb     ish
+   POISON_HEAP_REF_IF_OBJECT $is_object, r4
    $store  r4, [r1, r0]
    dmb     ish
    WRITE_BARRIER_IF_OBJECT $is_object, r4, r1, .L${opcode}_slow_path_skip_write_barrier, r0
@@ -345,6 +359,7 @@
    SET_VREG_WIDE_BY_ADDR r0, r1, r2    // fp[A] <- value
    .elseif $is_object
    $load   r0, [r0, r1]
+   UNPOISON_HEAP_REF r0
    // No need to check the marking register, we know it's not set here.
 .L${opcode}_after_reference_load:
    SET_VREG_OBJECT r0, r2              // fp[A] <- value
@@ -359,6 +374,7 @@
    bl      art_quick_read_barrier_mark_reg00
    .if $is_object
    ldr     r0, [r0, r1]
+   UNPOISON_HEAP_REF r0
 .L${opcode}_mark_after_load:
    // Here, we know the marking register is set.
    bl      art_quick_read_barrier_mark_reg00
@@ -393,6 +409,7 @@
    $load   r0, [r0, r1]
    dmb     ish
    .if $is_object
+   UNPOISON_HEAP_REF r0
    TEST_IF_MARKING .L${opcode}_mark_after_load
    SET_VREG_OBJECT r0, r2              // fp[A] <- value
    .else
@@ -444,6 +461,7 @@
    add     r0, r0, r1
    strd    r2, r3, [r0]
    .else
+   POISON_HEAP_REF_IF_OBJECT $is_object, r4
    $store  r4, [r0, r1]
    WRITE_BARRIER_IF_OBJECT $is_object, r4, r0, .L${opcode}_skip_write_barrier, r1
    .endif
@@ -487,6 +505,7 @@
    dmb     ish
    .else
    dmb     ish
+   POISON_HEAP_REF_IF_OBJECT $is_object r4
    $store  r4, [r0, r1]
    dmb     ish
    WRITE_BARRIER_IF_OBJECT $is_object, r4, r0, .L${opcode}_slow_path_skip_write_barrier, r1
diff --git a/runtime/interpreter/mterp/nterp.cc b/runtime/interpreter/mterp/nterp.cc
index 6ccc5e9..cf7ff00 100644
--- a/runtime/interpreter/mterp/nterp.cc
+++ b/runtime/interpreter/mterp/nterp.cc
@@ -39,7 +39,6 @@
   switch (kRuntimeISA) {
     case InstructionSet::kArm:
     case InstructionSet::kThumb2:
-      return !kPoisonHeapReferences && kReserveMarkingRegister;
     case InstructionSet::kArm64:
       return kReserveMarkingRegister;
     case InstructionSet::kRiscv64: