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/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc
index 888c7b8..ea342e9 100644
--- a/compiler/optimizing/intrinsics_x86_64.cc
+++ b/compiler/optimizing/intrinsics_x86_64.cc
@@ -1251,6 +1251,9 @@
case Primitive::kPrimInt:
case Primitive::kPrimNot:
__ movl(trg, Address(base, offset, ScaleFactor::TIMES_1, 0));
+ if (type == Primitive::kPrimNot) {
+ __ MaybeUnpoisonHeapReference(trg);
+ }
break;
case Primitive::kPrimLong:
@@ -1325,7 +1328,7 @@
locations->SetInAt(3, Location::RequiresRegister());
if (type == Primitive::kPrimNot) {
// Need temp registers for card-marking.
- locations->AddTemp(Location::RequiresRegister());
+ locations->AddTemp(Location::RequiresRegister()); // Possibly used for reference poisoning too.
locations->AddTemp(Location::RequiresRegister());
}
}
@@ -1369,6 +1372,11 @@
if (type == Primitive::kPrimLong) {
__ movq(Address(base, offset, ScaleFactor::TIMES_1, 0), value);
+ } else if (kPoisonHeapReferences && type == Primitive::kPrimNot) {
+ CpuRegister temp = locations->GetTemp(0).AsRegister<CpuRegister>();
+ __ movl(temp, value);
+ __ PoisonHeapReference(temp);
+ __ movl(Address(base, offset, ScaleFactor::TIMES_1, 0), temp);
} else {
__ movl(Address(base, offset, ScaleFactor::TIMES_1, 0), value);
}
@@ -1471,6 +1479,11 @@
base,
value,
value_can_be_null);
+
+ if (kPoisonHeapReferences) {
+ __ PoisonHeapReference(expected);
+ __ PoisonHeapReference(value);
+ }
}
__ LockCmpxchgl(Address(base, offset, TIMES_1, 0), value);
@@ -1482,6 +1495,11 @@
// Convert ZF into the boolean result.
__ setcc(kZero, out);
__ movzxb(out, out);
+
+ if (kPoisonHeapReferences && type == Primitive::kPrimNot) {
+ __ UnpoisonHeapReference(value);
+ __ UnpoisonHeapReference(expected);
+ }
}
void IntrinsicCodeGeneratorX86_64::VisitUnsafeCASInt(HInvoke* invoke) {
@@ -1598,5 +1616,9 @@
UNIMPLEMENTED_INTRINSIC(SystemArrayCopyChar)
UNIMPLEMENTED_INTRINSIC(ReferenceGetReferent)
+#undef UNIMPLEMENTED_INTRINSIC
+
+#undef __
+
} // namespace x86_64
} // namespace art