8339214: Remove misleading CodeBuilder.loadConstant(Opcode, ConstantDesc)

Reviewed-by: asotona
This commit is contained in:
Chen Liang 2024-09-03 13:44:48 +00:00
parent 4ca2c208ea
commit ad40a122d6
10 changed files with 48 additions and 199 deletions

View file

@ -604,23 +604,6 @@ public sealed interface CodeBuilder
return this;
}
/**
* Generate an instruction pushing a constant onto the operand stack
* @see Opcode.Kind#CONSTANT
* @param opcode the constant instruction opcode
* @param value the constant value
* @return this builder
* @since 23
*/
default CodeBuilder loadConstant(Opcode opcode, ConstantDesc value) {
BytecodeHelpers.validateValue(opcode, value);
return with(switch (opcode) {
case SIPUSH, BIPUSH -> ConstantInstruction.ofArgument(opcode, ((Number)value).intValue());
case LDC, LDC_W, LDC2_W -> ConstantInstruction.ofLoad(opcode, BytecodeHelpers.constantEntry(constantPool(), value));
default -> ConstantInstruction.ofIntrinsic(opcode);
});
}
/**
* Generate an instruction pushing a constant onto the operand stack
* @param value the constant value
@ -931,12 +914,12 @@ public sealed interface CodeBuilder
}
/**
* Generate an instruction pushing a byte onto the operand stack
* @param b the byte
* Generate an instruction pushing an int in the range of byte onto the operand stack.
* @param b the int in the range of byte
* @return this builder
*/
default CodeBuilder bipush(int b) {
return loadConstant(Opcode.BIPUSH, b);
return with(ConstantInstruction.ofArgument(Opcode.BIPUSH, b));
}
/**
@ -2396,12 +2379,12 @@ public sealed interface CodeBuilder
}
/**
* Generate an instruction pushing a short onto the operand stack
* @param s the short
* Generate an instruction pushing an int in the range of short onto the operand stack.
* @param s the int in the range of short
* @return this builder
*/
default CodeBuilder sipush(int s) {
return loadConstant(Opcode.SIPUSH, s);
return with(ConstantInstruction.ofArgument(Opcode.SIPUSH, s));
}
/**

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,7 @@ import java.lang.classfile.Opcode;
import java.lang.classfile.TypeKind;
import java.lang.classfile.constantpool.LoadableConstantEntry;
import jdk.internal.classfile.impl.AbstractInstruction;
import jdk.internal.classfile.impl.BytecodeHelpers;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
@ -144,16 +145,21 @@ public sealed interface ConstantInstruction extends Instruction {
/**
* {@return an argument constant instruction}
*
* @param op the opcode for the specific type of intrinsic constant instruction,
* which must be of kind {@link Opcode.Kind#CONSTANT}
* @param op the opcode for the specific type of argument constant instruction,
* which must be {@link Opcode#BIPUSH} or {@link Opcode#SIPUSH}
* @param value the constant value
* @throws IllegalArgumentException if the opcode is not {@link Opcode#BIPUSH}
* or {@link Opcode#SIPUSH}
* or {@link Opcode#SIPUSH}, or if the constant value is out of range
* for the opcode
*/
static ArgumentConstantInstruction ofArgument(Opcode op, int value) {
Util.checkKind(op, Opcode.Kind.CONSTANT);
if (op != Opcode.BIPUSH && op != Opcode.SIPUSH)
if (op == Opcode.BIPUSH) {
BytecodeHelpers.validateBipush(value);
} else if (op == Opcode.SIPUSH) {
BytecodeHelpers.validateSipush(value);
} else {
throw new IllegalArgumentException(String.format("Wrong opcode specified; found %s, expected BIPUSH or SIPUSH", op));
}
return new AbstractInstruction.UnboundArgumentConstantInstruction(op, value);
}

View file

@ -277,40 +277,20 @@ public class BytecodeHelpers {
};
}
static void validateSipush(long value) {
if (value < Short.MIN_VALUE || Short.MAX_VALUE < value)
public static void validateSipush(int value) {
if (value != (short) value)
throw new IllegalArgumentException(
"SIPUSH: value must be within: Short.MIN_VALUE <= value <= Short.MAX_VALUE, found: "
.concat(Long.toString(value)));
}
static void validateBipush(long value) {
if (value < Byte.MIN_VALUE || Byte.MAX_VALUE < value)
public static void validateBipush(int value) {
if (value != (byte) value)
throw new IllegalArgumentException(
"BIPUSH: value must be within: Byte.MIN_VALUE <= value <= Byte.MAX_VALUE, found: "
.concat(Long.toString(value)));
}
static void validateSipush(ConstantDesc d) {
if (d instanceof Integer iVal) {
validateSipush(iVal.longValue());
} else if (d instanceof Long lVal) {
validateSipush(lVal.longValue());
} else {
throw new IllegalArgumentException("SIPUSH: not an integral number: ".concat(d.toString()));
}
}
static void validateBipush(ConstantDesc d) {
if (d instanceof Integer iVal) {
validateBipush(iVal.longValue());
} else if (d instanceof Long lVal) {
validateBipush(lVal.longValue());
} else {
throw new IllegalArgumentException("BIPUSH: not an integral number: ".concat(d.toString()));
}
}
public static MethodHandleEntry handleDescToHandleInfo(ConstantPoolBuilder constantPool, DirectMethodHandleDesc bootstrapMethod) {
ClassEntry bsOwner = constantPool.classEntry(bootstrapMethod.owner());
NameAndTypeEntry bsNameAndType = constantPool.nameAndTypeEntry(constantPool.utf8Entry(bootstrapMethod.methodName()),
@ -341,32 +321,6 @@ public class BytecodeHelpers {
desc.constantType()));
}
public static void validateValue(Opcode opcode, ConstantDesc v) {
switch (opcode) {
case ACONST_NULL -> {
if (v != null && v != ConstantDescs.NULL)
throw new IllegalArgumentException("value must be null or ConstantDescs.NULL with opcode ACONST_NULL");
}
case SIPUSH ->
validateSipush(v);
case BIPUSH ->
validateBipush(v);
case LDC, LDC_W, LDC2_W -> {
if (v == null)
throw new IllegalArgumentException("`null` must use ACONST_NULL");
}
default -> {
var exp = opcode.constantValue();
if (exp == null)
throw new IllegalArgumentException("Can not use Opcode: " + opcode + " with constant()");
if (v == null || !(v.equals(exp) || (exp instanceof Long l && v.equals(l.intValue())))) {
var t = (exp instanceof Long) ? "L" : (exp instanceof Float) ? "f" : (exp instanceof Double) ? "d" : "";
throw new IllegalArgumentException("value must be " + exp + t + " with opcode " + opcode.name());
}
}
}
}
public static Opcode ldcOpcode(LoadableConstantEntry entry) {
return entry.typeKind().slotSize() == 2 ? Opcode.LDC2_W
: entry.index() > 0xff ? Opcode.LDC_W

View file

@ -258,8 +258,7 @@ public record ClassRemapperImpl(Function<ClassDesc, ClassDesc> mapFunction) impl
cob.localVariableType(c.slot(), c.name().stringValue(),
mapSignature(c.signatureSymbol()), c.startScope(), c.endScope());
case LoadConstantInstruction ldc ->
cob.loadConstant(ldc.opcode(),
mapConstantValue(ldc.constantValue()));
cob.ldc(mapConstantValue(ldc.constantValue()));
case RuntimeVisibleTypeAnnotationsAttribute aa ->
cob.with(RuntimeVisibleTypeAnnotationsAttribute.of(
mapTypeAnnotations(aa.annotations())));

View file

@ -831,21 +831,6 @@ public final class DirectCodeBuilder
return this;
}
@Override
public CodeBuilder loadConstant(Opcode opcode, ConstantDesc value) {
BytecodeHelpers.validateValue(opcode, value);
// avoid non-local enum switch for bootstrap
if (opcode == BIPUSH || opcode == SIPUSH) {
writeArgumentConstant(opcode, ((Number) value).intValue());
} else if (opcode == LDC || opcode == LDC_W || opcode == LDC2_W) {
writeLoadConstant(opcode, BytecodeHelpers.constantEntry(constantPool(), value));
} else {
// intrinsics
writeBytecode(opcode);
}
return this;
}
@Override
public CodeBuilder nop() {
writeBytecode(NOP);