Use atomic load/store for volatile IGET/IPUT/SGET/SPUT.
Bug: 14112919
Change-Id: I79316f438dd3adea9b2653ffc968af83671ad282
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index d10296f..0ffd189 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -128,6 +128,9 @@
bool wide = (data.op_variant == InlineMethodAnalyser::IGetVariant(Instruction::IGET_WIDE));
bool ref = (data.op_variant == InlineMethodAnalyser::IGetVariant(Instruction::IGET_OBJECT));
OpSize size = LoadStoreOpSize(wide, ref);
+ if (data.is_volatile && !SupportsVolatileLoadStore(size)) {
+ return false;
+ }
// The inliner doesn't distinguish kDouble or kFloat, use shorty.
bool double_or_float = cu_->shorty[0] == 'F' || cu_->shorty[0] == 'D';
@@ -137,12 +140,14 @@
LockArg(data.object_arg);
RegLocation rl_dest = wide ? GetReturnWide(double_or_float) : GetReturn(double_or_float);
RegStorage reg_obj = LoadArg(data.object_arg);
- LoadBaseDisp(reg_obj, data.field_offset, rl_dest.reg, size);
if (data.is_volatile) {
+ LoadBaseDispVolatile(reg_obj, data.field_offset, rl_dest.reg, size);
// Without context sensitive analysis, we must issue the most conservative barriers.
// In this case, either a load or store may follow so we issue both barriers.
GenMemBarrier(kLoadLoad);
GenMemBarrier(kLoadStore);
+ } else {
+ LoadBaseDisp(reg_obj, data.field_offset, rl_dest.reg, size);
}
return true;
}
@@ -162,6 +167,9 @@
bool wide = (data.op_variant == InlineMethodAnalyser::IPutVariant(Instruction::IPUT_WIDE));
bool ref = (data.op_variant == InlineMethodAnalyser::IGetVariant(Instruction::IGET_OBJECT));
OpSize size = LoadStoreOpSize(wide, ref);
+ if (data.is_volatile && !SupportsVolatileLoadStore(size)) {
+ return false;
+ }
// Point of no return - no aborts after this
GenPrintLabel(mir);
@@ -172,11 +180,11 @@
if (data.is_volatile) {
// There might have been a store before this volatile one so insert StoreStore barrier.
GenMemBarrier(kStoreStore);
- }
- StoreBaseDisp(reg_obj, data.field_offset, reg_src, size);
- if (data.is_volatile) {
+ StoreBaseDispVolatile(reg_obj, data.field_offset, reg_src, size);
// A load might follow the volatile store so insert a StoreLoad barrier.
GenMemBarrier(kStoreLoad);
+ } else {
+ StoreBaseDisp(reg_obj, data.field_offset, reg_src, size);
}
if (ref) {
MarkGCCard(reg_src, reg_obj);