Add memory barriers (Issue 3338450)
Add missing barriers required for volatile access on Arm. Also,
flipped long volatile field accesses to the slow path. The
previous codegen was not only missing barriers, but was not
using 64-bit atomics.
Change-Id: I4aa2be2bf81971e5ae664c762ceaf2ea58ce231b
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index cfeb16a..9e026be 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -222,6 +222,11 @@
branchOver->generic.target = (LIR*)skipTarget;
rlSrc = oatGetSrc(cUnit, mir, 0);
rlSrc = loadValue(cUnit, rlSrc, kAnyReg);
+#if ANDROID_SMP != 0
+ if (field->IsVolatile()) {
+ oatGenMemBarrier(cUnit, kST);
+ }
+#endif
storeWordDisp(cUnit, rBase, fieldOffset, rlSrc.lowReg);
#if ANDROID_SMP != 0
if (field->IsVolatile()) {
@@ -241,7 +246,12 @@
uint32_t typeIdx;
Field* field = FindFieldWithResolvedStaticStorage(cUnit->method, fieldIdx, typeIdx);
oatFlushAllRegs(cUnit);
- if (SLOW_FIELD_PATH || field == NULL) {
+#if ANDROID_SMP != 0
+ bool isVolatile = (field == NULL) || field->IsVolatile();
+#else
+ bool isVolatile = false;
+#endif
+ if (SLOW_FIELD_PATH || field == NULL || isVolatile) {
LOG(INFO) << "Field " << fieldNameFromIndex(cUnit->method, fieldIdx)
<< " unresolved at compile time";
loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pSet64Static), rLR);
@@ -276,11 +286,6 @@
rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg);
storeBaseDispWide(cUnit, rBase, fieldOffset, rlSrc.lowReg,
rlSrc.highReg);
-#if ANDROID_SMP != 0
- if (field->IsVolatile()) {
- oatGenMemBarrier(cUnit, kSY);
- }
-#endif
oatFreeTemp(cUnit, rBase);
}
}
@@ -292,8 +297,13 @@
int fieldIdx = mir->dalvikInsn.vB;
uint32_t typeIdx;
Field* field = FindFieldWithResolvedStaticStorage(cUnit->method, fieldIdx, typeIdx);
+#if ANDROID_SMP != 0
+ bool isVolatile = (field == NULL) || field->IsVolatile();
+#else
+ bool isVolatile = false;
+#endif
oatFlushAllRegs(cUnit);
- if (SLOW_FIELD_PATH || field == NULL) {
+ if (SLOW_FIELD_PATH || field == NULL || isVolatile) {
LOG(INFO) << "Field " << fieldNameFromIndex(cUnit->method, fieldIdx)
<< " unresolved at compile time";
loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pGet64Static), rLR);
@@ -327,11 +337,6 @@
branchOver->generic.target = (LIR*)skipTarget;
rlDest = oatGetDestWide(cUnit, mir, 0, 1);
RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
-#if ANDROID_SMP != 0
- if (field->IsVolatile()) {
- oatGenMemBarrier(cUnit, kSY);
- }
-#endif
loadBaseDispWide(cUnit, NULL, rBase, fieldOffset, rlResult.lowReg,
rlResult.highReg, INVALID_SREG);
oatFreeTemp(cUnit, rBase);