[8u] RFR: fix java_calling_convention for longs
Anton Kozlov
akozlov at azul.com
Thu Mar 10 17:59:17 UTC 2016
Hi!
Current java calling convention have a bug: when last long argument fitting to be passed on registers, high word could occupy register outside of register set intended for argument passing. With java c/c argument on registers r1,r2,r3,r0: r4 may be used. Test case for this issue is not straightforward, because only few places uses r4 directly, so it's rarely destroyed. However, itable_stub is one of them, so here is a test.
=== Test ===
class Test {
public static final long goldValue = (0xdeadL << 32) | 0xdead;
public static void checkLong(long j3) {
System.out.printf("%s: got %x, should be %x\n", j3 == goldValue ? "OK" : "Fail", j3, goldValue);
}
interface TestInterface {
public abstract void callee(int i1, long j3);
}
class TestImpl1 implements TestInterface {
@Override
public void callee(int i1, long j3) {
checkLong(j3);
}
}
class TestImpl2 implements TestInterface {
@Override
public void callee(int i1, long j3) {
checkLong(j3);
}
}
class TestImpl3 implements TestInterface {
@Override
public void callee(int i1, long j3) {
checkLong(j3);
}
}
public void vmain() {
TestInterface ifaces[] = { new TestImpl1(), new TestImpl2(), new TestImpl3() };
TestInterface iface = null;
for (int i = 0; i < ifaces.length; ++i) {
iface = ifaces[i];
iface.callee(0, goldValue);
}
}
public static void main(String[] args) {
Test test = new Test();
test.vmain();
}
}
=== End of Test ===
However, problem could be verified by hands easier. Calling java_calling_convention for checkLong2 signature will allocate r1 for i1, r2 for i2 and r4:r3 for j3; however, r0:r3 expected.
=== TestLongPass ===
class TestLongPass {
public static final long goldValue = (0x31414L << 32) | 0x31415;
public static void checkLong2(int i1, int i2, long j3) {
System.out.printf("%s: got %x, should be %x\n", j3 == goldValue ? "OK" : "Fail", j3, goldValue);
}
public static void main(String[] args) {
checkLong2(0, 0, goldValue);
}
}
=== End of TestLongPass
Fix for this is in attach. It's rather simple, so I hope it could be verified by looking at the code. For now, VMRegPair::set2 used for longs, so if r3 next free register, for long java_calling_convention will call VMRegPair::set2(r3) -> VMRegPair::set_pair(next(r3), r3) -> VMRegPair::set_pair(r4, r3). Calling VMRegPair::set_pair(r0, r3) directly resolves the issue.
Thanks,
Anton
-------------- next part --------------
A non-text attachment was scrubbed...
Name: java_cc_last_long.patch
Type: text/x-patch
Size: 621 bytes
Desc: java_cc_last_long.patch
URL: <http://mail.openjdk.java.net/pipermail/aarch32-port-dev/attachments/20160310/c2a95965/java_cc_last_long.patch>
More information about the aarch32-port-dev
mailing list