Fix for argument passing bug
The code was using r1 as a temp when it was live.
Change-Id: I79f42203eced2aff49980241c890629ecc3ff09a
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index 78a9767..96f5423 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -716,7 +716,6 @@
if (dInsn->vA == 0)
return callState;
- oatLockCallTemps(cUnit);
callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
/*
@@ -729,8 +728,9 @@
if (rlArg.location == kLocPhysReg) {
reg = rlArg.lowReg;
} else {
- reg = r1;
- loadValueDirectFixed(cUnit, rlArg, r1);
+ // r3 is the last arg register loaded, so can safely be used here
+ reg = r3;
+ loadValueDirectFixed(cUnit, rlArg, reg);
callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
}
storeBaseDisp(cUnit, rSP, (i + 1) * 4, reg, kWord);
@@ -859,9 +859,6 @@
callState = loadArgRegs(cUnit, mir, dInsn, callState, registerArgs,
nextCallInsn, rollback);
- // Finally, deal with the register arguments
- // We'll be using fixed registers here
- oatLockCallTemps(cUnit);
callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
return callState;
}
@@ -873,9 +870,11 @@
int callState = 0;
ArmLIR* nullCk;
ArmLIR** pNullCk = direct ? &nullCk : NULL;
-
NextCallInsn nextCallInsn = nextSDCallInsn;
+ // Explicit register usage
+ oatLockCallTemps(cUnit);
+
if (range) {
callState = genDalvikArgsRange(cUnit, mir, dInsn, callState, pNullCk,
nextCallInsn, NULL, false);
@@ -899,6 +898,9 @@
DecodedInstruction* dInsn = &mir->dalvikInsn;
int callState = 0;
ArmLIR* nullCk;
+
+ // Explicit register usage
+ oatLockCallTemps(cUnit);
/* Note: must call nextInterfaceCallInsn() prior to 1st argument load */
callState = nextInterfaceCallInsn(cUnit, mir, dInsn, callState, NULL);
if (mir->dalvikInsn.opcode == OP_INVOKE_INTERFACE)
@@ -925,6 +927,9 @@
Get(dInsn->vB);
NextCallInsn nextCallInsn;
bool fastPath = true;
+
+ // Explicit register usage
+ oatLockCallTemps(cUnit);
if (FORCE_SLOW || baseMethod == NULL) {
fastPath = false;
} else {
@@ -971,6 +976,8 @@
Get(dInsn->vB);
NextCallInsn nextCallInsn;
+ // Explicit register usage
+ oatLockCallTemps(cUnit);
if (FORCE_SLOW || method == NULL) {
// Slow path
nextCallInsn = nextVCallInsnSP;
diff --git a/src/compiler_test.cc b/src/compiler_test.cc
index acfd5e5..a1aadc8 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -270,6 +270,26 @@
111);
}
+TEST_F(CompilerTest, InvokeTest) {
+ CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
+ const ClassLoader* class_loader = LoadDex("Invoke");
+ CompileDirectMethod(class_loader, "Invoke", "<init>", "()V");
+ CompileVirtualMethod(class_loader, "Invoke", "virI_I", "(I)I");
+ CompileVirtualMethod(class_loader, "Invoke", "virI_II", "(II)I");
+ CompileVirtualMethod(class_loader, "Invoke", "virI_III", "(III)I");
+ CompileVirtualMethod(class_loader, "Invoke", "virI_IIII", "(IIII)I");
+ CompileVirtualMethod(class_loader, "Invoke", "virI_IIIII", "(IIIII)I");
+ CompileVirtualMethod(class_loader, "Invoke", "virI_IIIIII", "(IIIIII)I");
+ CompileDirectMethod(class_loader, "Invoke", "statI_I", "(I)I");
+ CompileDirectMethod(class_loader, "Invoke", "statI_II", "(II)I");
+ CompileDirectMethod(class_loader, "Invoke", "statI_III", "(III)I");
+ CompileDirectMethod(class_loader, "Invoke", "statI_IIII", "(IIII)I");
+ CompileDirectMethod(class_loader, "Invoke", "statI_IIIII", "(IIIII)I");
+ CompileDirectMethod(class_loader, "Invoke", "statI_IIIIII", "(IIIIII)I");
+ AssertStaticIntMethod(class_loader, "Invoke", "test0", "(I)I", 20664,
+ 912);
+}
+
TEST_F(CompilerTest, SystemMethodsTest) {
CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");