8318837: javac generates wrong ldc instruction for dynamic constant loads
Reviewed-by: vromero, jlahoda
This commit is contained in:
parent
ddd071617e
commit
2915d74a10
@ -35,7 +35,9 @@ import java.util.function.ToIntBiFunction;
|
||||
import java.util.function.ToIntFunction;
|
||||
|
||||
import static com.sun.tools.javac.code.TypeTag.BOT;
|
||||
import static com.sun.tools.javac.code.TypeTag.DOUBLE;
|
||||
import static com.sun.tools.javac.code.TypeTag.INT;
|
||||
import static com.sun.tools.javac.code.TypeTag.LONG;
|
||||
import static com.sun.tools.javac.jvm.ByteCodes.*;
|
||||
import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Class;
|
||||
import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Double;
|
||||
@ -401,10 +403,12 @@ public class Code {
|
||||
*/
|
||||
public void emitLdc(LoadableConstant constant) {
|
||||
int od = poolWriter.putConstant(constant);
|
||||
if (od <= 255) {
|
||||
Type constantType = types.constantType(constant);
|
||||
if (constantType.hasTag(LONG) || constantType.hasTag(DOUBLE)) {
|
||||
emitop2(ldc2w, od, constant);
|
||||
} else if (od <= 255) {
|
||||
emitop1(ldc1, od, constant);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
emitop2(ldc2, od, constant);
|
||||
}
|
||||
}
|
||||
@ -1062,6 +1066,7 @@ public class Code {
|
||||
Type t = types.erasure((Type)data);
|
||||
state.push(t);
|
||||
break; }
|
||||
case ldc2:
|
||||
case ldc2w:
|
||||
state.push(types.constantType((LoadableConstant)data));
|
||||
break;
|
||||
@ -1069,9 +1074,6 @@ public class Code {
|
||||
state.pop(1);
|
||||
state.push(syms.intType);
|
||||
break;
|
||||
case ldc2:
|
||||
state.push(types.constantType((LoadableConstant)data));
|
||||
break;
|
||||
case jsr:
|
||||
break;
|
||||
default:
|
||||
|
@ -590,15 +590,6 @@ public class Items {
|
||||
throw new UnsupportedOperationException("unsupported tag: " + typecode);
|
||||
}
|
||||
}
|
||||
|
||||
private void ldc() {
|
||||
if (typecode == LONGcode || typecode == DOUBLEcode) {
|
||||
code.emitop2(ldc2w, value, PoolWriter::putConstant);
|
||||
} else {
|
||||
code.emitLdc(value);
|
||||
}
|
||||
}
|
||||
|
||||
private Number numericValue() {
|
||||
return (Number)((BasicConstant)value).data;
|
||||
}
|
||||
@ -614,21 +605,21 @@ public class Items {
|
||||
else if (Short.MIN_VALUE <= ival && ival <= Short.MAX_VALUE)
|
||||
code.emitop2(sipush, ival);
|
||||
else
|
||||
ldc();
|
||||
code.emitLdc(value);
|
||||
break;
|
||||
case LONGcode:
|
||||
long lval = numericValue().longValue();
|
||||
if (lval == 0 || lval == 1)
|
||||
code.emitop0(lconst_0 + (int)lval);
|
||||
else
|
||||
ldc();
|
||||
code.emitLdc(value);
|
||||
break;
|
||||
case FLOATcode:
|
||||
float fval = numericValue().floatValue();
|
||||
if (isPosZero(fval) || fval == 1.0 || fval == 2.0)
|
||||
code.emitop0(fconst_0 + (int)fval);
|
||||
else {
|
||||
ldc();
|
||||
code.emitLdc(value);
|
||||
}
|
||||
break;
|
||||
case DOUBLEcode:
|
||||
@ -636,10 +627,10 @@ public class Items {
|
||||
if (isPosZero(dval) || dval == 1.0)
|
||||
code.emitop0(dconst_0 + (int)dval);
|
||||
else
|
||||
ldc();
|
||||
code.emitLdc(value);
|
||||
break;
|
||||
case OBJECTcode:
|
||||
ldc();
|
||||
code.emitLdc(value);
|
||||
break;
|
||||
default:
|
||||
Assert.error();
|
||||
|
@ -81,21 +81,23 @@ import static java.lang.invoke.MethodHandleInfo.REF_invokeStatic;
|
||||
public class TestConstantDynamic extends ComboInstance<TestConstantDynamic> {
|
||||
|
||||
enum ConstantType implements ComboParameter {
|
||||
STRING("String", "Ljava/lang/String;"),
|
||||
CLASS("Class<?>", "Ljava/lang/Class;"),
|
||||
INTEGER("int", "I"),
|
||||
LONG("long", "J"),
|
||||
FLOAT("float", "F"),
|
||||
DOUBLE("double", "D"),
|
||||
METHOD_HANDLE("MethodHandle", "Ljava/lang/invoke/MethodHandle;"),
|
||||
METHOD_TYPE("MethodType", "Ljava/lang/invoke/MethodType;");
|
||||
STRING("String", "Ljava/lang/String;", Opcode.LDC),
|
||||
CLASS("Class<?>", "Ljava/lang/Class;", Opcode.LDC),
|
||||
INTEGER("int", "I", Opcode.LDC),
|
||||
LONG("long", "J", Opcode.LDC2_W),
|
||||
FLOAT("float", "F", Opcode.LDC),
|
||||
DOUBLE("double", "D", Opcode.LDC2_W),
|
||||
METHOD_HANDLE("MethodHandle", "Ljava/lang/invoke/MethodHandle;", Opcode.LDC),
|
||||
METHOD_TYPE("MethodType", "Ljava/lang/invoke/MethodType;", Opcode.LDC);
|
||||
|
||||
String sourceTypeStr;
|
||||
String bytecodeTypeStr;
|
||||
Opcode opcode;
|
||||
|
||||
ConstantType(String sourceTypeStr, String bytecodeTypeStr) {
|
||||
ConstantType(String sourceTypeStr, String bytecodeTypeStr, Opcode opcode) {
|
||||
this.sourceTypeStr = sourceTypeStr;
|
||||
this.bytecodeTypeStr = bytecodeTypeStr;
|
||||
this.opcode = opcode;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -205,6 +207,10 @@ public class TestConstantDynamic extends ComboInstance<TestConstantDynamic> {
|
||||
fail("type mismatch for ConstantDynamicEntry");
|
||||
return;
|
||||
}
|
||||
if (lci.opcode() != type.opcode) {
|
||||
fail("unexpected opcode for constant value: " + lci.opcode());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user