The x86/JIT compiler fails for any piece of code containing opc_ldc2_w or
opc_ldc2_w_quick:
1) It fails for the "quick" opcode because there is no case statement for it
in the big switch statement of JITCompile_md() in pass2.c.
2) It fails for the non-quick opcode because the code calls j86ResolveInfallibly
on both ndx and ndx+1. j86ResolveInfallibly eventually calls resolveCarefullyCommon(), which will call JITFail on the index ndx+1. This is
not a legal constant pool index, and its constant pool index type is 0.
These have already been fixed for JavaOS.
For #1, just add a case for opc_ldc2_w_quick above the case for opc_ldc2_w. The
code is identical.
For #2, we use the code:
unsigned ndx = U2(jmi.byteCode + (jmi.pc + 1));
if (resolveCarefully(ji, ndx)) {
p = jmi.cgs + jmi.height;
p->kind = KindC;
p->c = cbConstantPool(ji->thisClass)[ndx].i;
p += 1;
p->kind = KindC;
p->c = cbConstantPool(ji->thisClass)[ndx + 1].i;
jmi.height += 2;
} else {
j86Panic("resolveCarefully() failed when it can't!");
}
break;
This code is, in fact, a little bit too paranoid. resolveCarefully will always
return true in this case. The code can just use the cbConstantPool values
directly. Note that this is what the SPARC code does.
Feel free to look at /net/pan.eng/export/home/fy/luna/src/javaos/cjit.i386
for our code that fixes both of these problems.
opc_ldc2_w_quick:
1) It fails for the "quick" opcode because there is no case statement for it
in the big switch statement of JITCompile_md() in pass2.c.
2) It fails for the non-quick opcode because the code calls j86ResolveInfallibly
on both ndx and ndx+1. j86ResolveInfallibly eventually calls resolveCarefullyCommon(), which will call JITFail on the index ndx+1. This is
not a legal constant pool index, and its constant pool index type is 0.
These have already been fixed for JavaOS.
For #1, just add a case for opc_ldc2_w_quick above the case for opc_ldc2_w. The
code is identical.
For #2, we use the code:
unsigned ndx = U2(jmi.byteCode + (jmi.pc + 1));
if (resolveCarefully(ji, ndx)) {
p = jmi.cgs + jmi.height;
p->kind = KindC;
p->c = cbConstantPool(ji->thisClass)[ndx].i;
p += 1;
p->kind = KindC;
p->c = cbConstantPool(ji->thisClass)[ndx + 1].i;
jmi.height += 2;
} else {
j86Panic("resolveCarefully() failed when it can't!");
}
break;
This code is, in fact, a little bit too paranoid. resolveCarefully will always
return true in this case. The code can just use the cbConstantPool values
directly. Note that this is what the SPARC code does.
Feel free to look at /net/pan.eng/export/home/fy/luna/src/javaos/cjit.i386
for our code that fixes both of these problems.