Merge "Reuse promoted register temporarily"
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 1fe0af9..c929265 100644
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -734,6 +734,10 @@
NewLIR2(kX86Cmp16TI8, offset.Int32Value(), val);
}
+static bool IsInReg(X86Mir2Lir *pMir2Lir, const RegLocation &rl, int reg) {
+ return !rl.reg.IsInvalid() && rl.reg.GetReg() == reg && (pMir2Lir->IsLive(reg) || rl.home);
+}
+
bool X86Mir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
DCHECK_EQ(cu_->instruction_set, kX86);
// Unused - RegLocation rl_src_unsafe = info->args[0];
@@ -746,6 +750,8 @@
// If is_long, high half is in info->args[7]
if (is_long) {
+ // TODO: avoid unnecessary loads of SI and DI when the values are in registers.
+ // TODO: CFI support.
FlushAllRegs();
LockCallTemps();
LoadValueDirectWideFixed(rl_src_expected, rAX, rDX);
@@ -757,8 +763,14 @@
MarkTemp(rSI);
LockTemp(rSI);
const int push_offset = 4 /* push edi */ + 4 /* push esi */;
- LoadWordDisp(TargetReg(kSp), SRegOffset(rl_src_obj.s_reg_low) + push_offset, rDI);
- LoadWordDisp(TargetReg(kSp), SRegOffset(rl_src_offset.s_reg_low) + push_offset, rSI);
+ int srcObjSp = IsInReg(this, rl_src_obj, rSI) ? 0
+ : (IsInReg(this, rl_src_obj, rDI) ? 4
+ : (SRegOffset(rl_src_obj.s_reg_low) + push_offset));
+ LoadWordDisp(TargetReg(kSp), srcObjSp, rDI);
+ int srcOffsetSp = IsInReg(this, rl_src_offset, rSI) ? 0
+ : (IsInReg(this, rl_src_offset, rDI) ? 4
+ : (SRegOffset(rl_src_offset.s_reg_low) + push_offset));
+ LoadWordDisp(TargetReg(kSp), srcOffsetSp, rSI);
NewLIR4(kX86LockCmpxchg8bA, rDI, rSI, 0, 0);
FreeTemp(rSI);
UnmarkTemp(rSI);
diff --git a/test/083-compiler-regressions/expected.txt b/test/083-compiler-regressions/expected.txt
index 90d8634..f6de0e7 100644
--- a/test/083-compiler-regressions/expected.txt
+++ b/test/083-compiler-regressions/expected.txt
@@ -16,3 +16,4 @@
longModTest passes
testIfCcz passes
ManyFloatArgs passes
+atomicLong passes
diff --git a/test/083-compiler-regressions/src/Main.java b/test/083-compiler-regressions/src/Main.java
index 96c71cf..2745c27 100644
--- a/test/083-compiler-regressions/src/Main.java
+++ b/test/083-compiler-regressions/src/Main.java
@@ -15,6 +15,7 @@
*/
import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicLong;
/**
* Test for Jit regressions.
@@ -47,6 +48,18 @@
ZeroTests.longModTest();
MirOpSelectTests.testIfCcz();
ManyFloatArgs();
+ atomicLong();
+ }
+
+ public static void atomicLong() {
+ AtomicLong atomicLong = new AtomicLong();
+ atomicLong.addAndGet(3);
+ atomicLong.addAndGet(2);
+ atomicLong.addAndGet(1);
+ long result = atomicLong.get();
+ System.out.println(result == 6L ? "atomicLong passes" :
+ ("atomicLong failes: returns " + result + ", expected 6")
+ );
}
public static void returnConstantTest() {