Revert "Revert "ART: Split out more cases of Load/StoreRef, volatile as parameter""
This reverts commit de68676b24f61a55adc0b22fe828f036a5925c41.
Fixes an API comment, and differentiates between inserting and appending.
Change-Id: I0e9a21bb1d25766e3cbd802d8b48633ae251a6bf
diff --git a/compiler/dex/quick/mips/utility_mips.cc b/compiler/dex/quick/mips/utility_mips.cc
index 01b25f92..b49f436 100644
--- a/compiler/dex/quick/mips/utility_mips.cc
+++ b/compiler/dex/quick/mips/utility_mips.cc
@@ -546,23 +546,31 @@
return load;
}
-LIR* MipsMir2Lir::LoadBaseDispVolatile(RegStorage r_base, int displacement, RegStorage r_dest,
- OpSize size) {
- DCHECK(size != k64 && size != kDouble);
- return LoadBaseDisp(r_base, displacement, r_dest, size);
-}
-
LIR* MipsMir2Lir::LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest,
- OpSize size) {
+ OpSize size, VolatileKind is_volatile) {
+ if (is_volatile == kVolatile) {
+ DCHECK(size != k64 && size != kDouble);
+ }
+
// TODO: base this on target.
if (size == kWord) {
size = k32;
}
+ LIR* load;
if (size == k64 || size == kDouble) {
- return LoadBaseDispBody(r_base, displacement, r_dest.GetLow(), r_dest.GetHigh(), size);
+ load = LoadBaseDispBody(r_base, displacement, r_dest.GetLow(), r_dest.GetHigh(), size);
} else {
- return LoadBaseDispBody(r_base, displacement, r_dest, RegStorage::InvalidReg(), size);
+ load = LoadBaseDispBody(r_base, displacement, r_dest, RegStorage::InvalidReg(), size);
}
+
+ if (UNLIKELY(is_volatile == kVolatile)) {
+ // 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);
+ }
+
+ return load;
}
// FIXME: don't split r_dest into 2 containers.
@@ -648,23 +656,31 @@
return res;
}
-LIR* MipsMir2Lir::StoreBaseDispVolatile(RegStorage r_base, int displacement, RegStorage r_src,
- OpSize size) {
- DCHECK(size != k64 && size != kDouble);
- return StoreBaseDisp(r_base, displacement, r_src, size);
-}
-
LIR* MipsMir2Lir::StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r_src,
- OpSize size) {
+ OpSize size, VolatileKind is_volatile) {
+ if (is_volatile == kVolatile) {
+ DCHECK(size != k64 && size != kDouble);
+ // There might have been a store before this volatile one so insert StoreStore barrier.
+ GenMemBarrier(kStoreStore);
+ }
+
// TODO: base this on target.
if (size == kWord) {
size = k32;
}
+ LIR* store;
if (size == k64 || size == kDouble) {
- return StoreBaseDispBody(r_base, displacement, r_src.GetLow(), r_src.GetHigh(), size);
+ store = StoreBaseDispBody(r_base, displacement, r_src.GetLow(), r_src.GetHigh(), size);
} else {
- return StoreBaseDispBody(r_base, displacement, r_src, RegStorage::InvalidReg(), size);
+ store = StoreBaseDispBody(r_base, displacement, r_src, RegStorage::InvalidReg(), size);
}
+
+ if (UNLIKELY(is_volatile == kVolatile)) {
+ // A load might follow the volatile store so insert a StoreLoad barrier.
+ GenMemBarrier(kStoreLoad);
+ }
+
+ return store;
}
LIR* MipsMir2Lir::OpThreadMem(OpKind op, ThreadOffset<4> thread_offset) {