8335110: Fix instruction name and API spec inconsistencies in CodeBuilder

Reviewed-by: asotona
This commit is contained in:
Chen Liang 2024-07-03 02:49:43 +00:00
parent 8a664a4c35
commit f7af4504a8
6 changed files with 120 additions and 16 deletions

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
@ -97,6 +97,27 @@ import jdk.internal.javac.PreviewFeature;
* #with(ClassFileElement)} or concretely by calling the various {@code withXxx}
* methods.
*
* <h2>Instruction Factories</h2>
* {@code CodeBuilder} provides convenience methods to create instructions (See
* JVMS {@jvms 6.5} Instructions) by their mnemonic, taking necessary operands.
* <ul>
* <li>Instructions that encode their operands in their opcode, such as {@code
* aload_<n>}, share their factories with their generic version like {@link
* #aload aload}. Note that some constant instructions, such as {@link #iconst_1
* iconst_1}, do not have generic versions, and thus have their own factories.
* <li>Instructions that accept wide operands, such as {@code ldc2_w} or {@code
* wide}, share their factories with their regular version like {@link #ldc}. Note
* that {@link #goto_w goto_w} has its own factory to avoid {@linkplain
* ClassFile.ShortJumpsOption short jumps}.
* <li>The {@code goto}, {@code instanceof}, {@code new}, and {@code return}
* instructions' factories are named {@link #goto_ goto_}, {@link #instanceOf
* instanceOf}, {@link #new_ new_}, and {@link #return_() return_} respectively,
* due to clashes with keywords in the Java programming language.
* <li>Factories are not provided for instructions {@code jsr}, {@code jsr_w},
* {@code ret}, and {@code wide ret}, which cannot appear in class files with
* major version {@value ClassFile#JAVA_7_VERSION} or higher. (JVMS {@jvms 4.9.1})
* </ul>
*
* @see CodeTransform
*
* @since 22
@ -130,7 +151,7 @@ public sealed interface CodeBuilder
/**
* {@return the local variable slot associated with the receiver}.
*
* @throws IllegalStateException if this is not a static method
* @throws IllegalStateException if this is a static method
*/
int receiverSlot();
@ -699,7 +720,7 @@ public sealed interface CodeBuilder
* @return this builder
*/
default CodeBuilder exceptionCatch(Label start, Label end, Label handler, ClassEntry catchType) {
return with(ExceptionCatch.of(handler, start, end, Optional.of(catchType)));
return with(ExceptionCatch.of(handler, start, end, Optional.ofNullable(catchType)));
}
/**
@ -837,6 +858,10 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to load a reference from a local variable
*
* <p>This may also generate {@code aload_<N>} and
* {@code wide aload} instructions.
*
* @param slot the local variable slot
* @return this builder
*/
@ -881,6 +906,10 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to store a reference into a local variable
*
* <p>This may also generate {@code astore_<N>} and
* {@code wide astore} instructions.
*
* @param slot the local variable slot
* @return this builder
*/
@ -1046,6 +1075,10 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to load a double from a local variable
*
* <p>This may also generate {@code dload_<N>} and
* {@code wide dload} instructions.
*
* @param slot the local variable slot
* @return this builder
*/
@ -1087,6 +1120,10 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to store a double into a local variable
*
* <p>This may also generate {@code dstore_<N>} and
* {@code wide dstore} instructions.
*
* @param slot the local variable slot
* @return this builder
*/
@ -1250,6 +1287,10 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to load a float from a local variable
*
* <p>This may also generate {@code fload_<N>} and
* {@code wide fload} instructions.
*
* @param slot the local variable slot
* @return this builder
*/
@ -1291,6 +1332,10 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to store a float into a local variable
*
* <p>This may also generate {@code fstore_<N>} and
* {@code wide fstore} instructions.
*
* @param slot the local variable slot
* @return this builder
*/
@ -1350,6 +1395,15 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to branch always
*
* <p>This may also generate {@code goto_w} instructions if the {@link
* ClassFile.ShortJumpsOption#FIX_SHORT_JUMPS FIX_SHORT_JUMPS} option
* is set.
*
* @apiNote The instruction's name is {@code goto}, which coincides with a
* reserved keyword of the Java programming language, thus this method is
* named with an extra {@code _} suffix instead.
*
* @param target the branch target
* @return this builder
*/
@ -1587,7 +1641,7 @@ public sealed interface CodeBuilder
* @param target the branch target
* @return this builder
*/
default CodeBuilder if_nonnull(Label target) {
default CodeBuilder ifnonnull(Label target) {
return branch(Opcode.IFNONNULL, target);
}
@ -1596,7 +1650,7 @@ public sealed interface CodeBuilder
* @param target the branch target
* @return this builder
*/
default CodeBuilder if_null(Label target) {
default CodeBuilder ifnull(Label target) {
return branch(Opcode.IFNULL, target);
}
@ -1666,6 +1720,10 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to load an int from a local variable
*
* <p>This may also generate {@code iload_<N>} and
* {@code wide iload} instructions.
*
* @param slot the local variable slot
* @return this builder
*/
@ -1691,6 +1749,11 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to determine if an object is of the given type
*
* @apiNote The instruction's name is {@code instanceof}, which coincides with a
* reserved keyword of the Java programming language, thus this method is
* named with camel case instead.
*
* @param target the target type
* @return this builder
* @since 23
@ -1701,6 +1764,11 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to determine if an object is of the given type
*
* @apiNote The instruction's name is {@code instanceof}, which coincides with a
* reserved keyword of the Java programming language, thus this method is
* named with camel case instead.
*
* @param target the target type
* @return this builder
* @throws IllegalArgumentException if {@code target} represents a primitive type
@ -1910,6 +1978,10 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to store an int into a local variable
*
* <p>This may also generate {@code istore_<N>} and
* {@code wide istore} instructions.
*
* @param slot the local variable slot
* @return this builder
*/
@ -2033,6 +2105,12 @@ public sealed interface CodeBuilder
/**
* Generate an instruction pushing an item from the run-time constant pool onto the operand stack
*
* <p>This may also generate {@code ldc_w} and {@code ldc2_w} instructions.
*
* @apiNote {@link #loadConstant(ConstantDesc) loadConstant} generates more optimal instructions
* and should be used for general constants if an {@code ldc} instruction is not strictly required.
*
* @param value the constant value
* @return this builder
*/
@ -2042,6 +2120,9 @@ public sealed interface CodeBuilder
/**
* Generate an instruction pushing an item from the run-time constant pool onto the operand stack
*
* <p>This may also generate {@code ldc_w} and {@code ldc2_w} instructions.
*
* @param entry the constant value
* @return this builder
*/
@ -2062,6 +2143,10 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to load a long from a local variable
*
* <p>This may also generate {@code lload_<N>} and
* {@code wide lload} instructions.
*
* @param slot the local variable slot
* @return this builder
*/
@ -2127,6 +2212,10 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to store a long into a local variable
*
* <p>This may also generate {@code lstore_<N>} and
* {@code wide lstore} instructions.
*
* @param slot the local variable slot
* @return this builder
*/
@ -2197,6 +2286,11 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to create a new object
*
* @apiNote The instruction's name is {@code new}, which coincides with a
* reserved keyword of the Java programming language, thus this method is
* named with an extra {@code _} suffix instead.
*
* @param clazz the new class type
* @return this builder
*/
@ -2206,6 +2300,11 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to create a new object
*
* @apiNote The instruction's name is {@code new}, which coincides with a
* reserved keyword of the Java programming language, thus this method is
* named with an extra {@code _} suffix instead.
*
* @param clazz the new class type
* @return this builder
* @throws IllegalArgumentException if {@code clazz} represents a primitive type
@ -2283,6 +2382,11 @@ public sealed interface CodeBuilder
/**
* Generate an instruction to return void from the method
*
* @apiNote The instruction's name is {@code return}, which coincides with a
* reserved keyword of the Java programming language, thus this method is
* named with an extra {@code _} suffix instead.
*
* @return this builder
*/
default CodeBuilder return_() {

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
@ -58,9 +58,9 @@ public sealed interface CodeAttribute extends Attribute<CodeAttribute>, CodeMode
byte[] codeArray();
/**
* {@return the position of the {@code Label} in the {@code codeArray}
* or -1 if the {@code Label} does not point to the {@code codeArray}}
* {@return the position of the {@code label} in the {@link #codeArray codeArray}}
* @param label a marker for a position within this {@code CodeAttribute}
* @throws IllegalArgumentException if the {@code label} is not from this attribute
*/
int labelToBci(Label label);
}

View File

@ -422,7 +422,7 @@ public class SwitchBootstraps {
cb.pop();
cb.aload(SELECTOR_OBJ);
Label nonNullLabel = cb.newLabel();
cb.if_nonnull(nonNullLabel);
cb.ifnonnull(nonNullLabel);
cb.iconst_m1();
cb.ireturn();
cb.labelBinding(nonNullLabel);

View File

@ -51,7 +51,7 @@ public final class LabelImpl
private final LabelContext labelContext;
private int bci;
public LabelImpl(LabelContext labelContext, int bci) {
public LabelImpl(LabelContext labelContext, int bci) {
this.labelContext = Objects.requireNonNull(labelContext);
this.bci = bci;
}

View File

@ -461,7 +461,7 @@ final class EventInstrumentation {
catchAllHandler.dup();
// stack: [ex] [EW] [EW]
Label rethrow = catchAllHandler.newLabel();
catchAllHandler.if_null(rethrow);
catchAllHandler.ifnull(rethrow);
// stack: [ex] [EW]
catchAllHandler.dup();
// stack: [ex] [EW] [EW]
@ -486,7 +486,7 @@ final class EventInstrumentation {
Label fail = codeBuilder.newLabel();
if (guardEventConfiguration) {
getEventConfiguration(codeBuilder);
codeBuilder.if_null(fail);
codeBuilder.ifnull(fail);
}
// if (!eventConfiguration.shouldCommit(duration) goto fail;
getEventConfiguration(codeBuilder);
@ -525,7 +525,7 @@ final class EventInstrumentation {
if (guardEventConfiguration) {
// if (eventConfiguration == null) goto fail;
getEventConfiguration(codeBuilder);
codeBuilder.if_null(fail);
codeBuilder.ifnull(fail);
}
// return eventConfiguration.shouldCommit(duration);
getEventConfiguration(codeBuilder);
@ -738,7 +738,7 @@ final class EventInstrumentation {
Label nullLabel = codeBuilder.newLabel();
if (guardEventConfiguration) {
getEventConfiguration(codeBuilder);
codeBuilder.if_null(nullLabel);
codeBuilder.ifnull(nullLabel);
}
getEventConfiguration(codeBuilder);
invokevirtual(codeBuilder, TYPE_EVENT_CONFIGURATION, METHOD_IS_ENABLED);

View File

@ -257,8 +257,8 @@ class RebuildingTransformation {
case IF_ICMPLE -> cob.if_icmple(target);
case IF_ICMPLT -> cob.if_icmplt(target);
case IF_ICMPNE -> cob.if_icmpne(target);
case IFNONNULL -> cob.if_nonnull(target);
case IFNULL -> cob.if_null(target);
case IFNONNULL -> cob.ifnonnull(target);
case IFNULL -> cob.ifnull(target);
case IFEQ -> cob.ifeq(target);
case IFGE -> cob.ifge(target);
case IFGT -> cob.ifgt(target);