Skip to content

Commit

Permalink
8318837: javac generates wrong ldc instruction for dynamic constant l…
Browse files Browse the repository at this point in the history
…oads

Reviewed-by: vromero, jlahoda
  • Loading branch information
mcimadamore committed Oct 27, 2023
1 parent ddd0716 commit 2915d74
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 29 deletions.
14 changes: 8 additions & 6 deletions src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
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;
Expand Down Expand Up @@ -401,10 +403,12 @@ void postop() {
*/
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);
}
}
Expand Down Expand Up @@ -1062,16 +1066,14 @@ public void emitop2(int op, int od, PoolConstant data) {
Type t = types.erasure((Type)data);
state.push(t);
break; }
case ldc2:
case ldc2w:
state.push(types.constantType((LoadableConstant)data));
break;
case instanceof_:
state.pop(1);
state.push(syms.intType);
break;
case ldc2:
state.push(types.constantType((LoadableConstant)data));
break;
case jsr:
break;
default:
Expand Down
19 changes: 5 additions & 14 deletions src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java
Original file line number Diff line number Diff line change
Expand Up @@ -590,15 +590,6 @@ class ImmediateItem extends Item {
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;
}
Expand All @@ -614,32 +605,32 @@ else if (Byte.MIN_VALUE <= ival && ival <= Byte.MAX_VALUE)
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:
double dval = numericValue().doubleValue();
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();
Expand Down
24 changes: 15 additions & 9 deletions test/langtools/tools/javac/T8222949/TestConstantDynamic.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,23 @@
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
Expand Down Expand Up @@ -205,6 +207,10 @@ void verifyBytecode(Result<Iterable<? extends JavaFileObject>> res) {
fail("type mismatch for ConstantDynamicEntry");
return;
}
if (lci.opcode() != type.opcode) {
fail("unexpected opcode for constant value: " + lci.opcode());
return;
}
}
}

Expand Down

0 comments on commit 2915d74

Please sign in to comment.