From f7af4504a804711d93208b763b3e41eafcf61735 Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Wed, 3 Jul 2024 02:49:43 +0000 Subject: [PATCH] 8335110: Fix instruction name and API spec inconsistencies in CodeBuilder Reviewed-by: asotona --- .../java/lang/classfile/CodeBuilder.java | 114 +++++++++++++++++- .../classfile/attribute/CodeAttribute.java | 6 +- .../java/lang/runtime/SwitchBootstraps.java | 2 +- .../internal/classfile/impl/LabelImpl.java | 2 +- .../jfr/internal/EventInstrumentation.java | 8 +- .../helpers/RebuildingTransformation.java | 4 +- 6 files changed, 120 insertions(+), 16 deletions(-) diff --git a/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java b/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java index e954be079fa..cffa560bef3 100644 --- a/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java +++ b/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java @@ -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. * + *

Instruction Factories

+ * {@code CodeBuilder} provides convenience methods to create instructions (See + * JVMS {@jvms 6.5} Instructions) by their mnemonic, taking necessary operands. + * + * * @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 + * + *

This may also generate {@code aload_} 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 + * + *

This may also generate {@code astore_} 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 + * + *

This may also generate {@code dload_} 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 + * + *

This may also generate {@code dstore_} 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 + * + *

This may also generate {@code fload_} 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 + * + *

This may also generate {@code fstore_} 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 + * + *

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 + * + *

This may also generate {@code iload_} 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 + * + *

This may also generate {@code istore_} 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 + * + *

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 + * + *

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 + * + *

This may also generate {@code lload_} 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 + * + *

This may also generate {@code lstore_} 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_() { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/CodeAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/CodeAttribute.java index 1a57cf4f37f..02cbcee810f 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/CodeAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/CodeAttribute.java @@ -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, 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); } diff --git a/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java b/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java index 24ee48c1f47..ccb33a0e4db 100644 --- a/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java +++ b/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java @@ -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); diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/LabelImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/LabelImpl.java index b316c5a6dd1..2aaf5f033c0 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/LabelImpl.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/LabelImpl.java @@ -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; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java index cf7e162a42e..d8f5e689ca1 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java @@ -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); diff --git a/test/jdk/jdk/classfile/helpers/RebuildingTransformation.java b/test/jdk/jdk/classfile/helpers/RebuildingTransformation.java index 0c9b771c3ef..7905a79fd40 100644 --- a/test/jdk/jdk/classfile/helpers/RebuildingTransformation.java +++ b/test/jdk/jdk/classfile/helpers/RebuildingTransformation.java @@ -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);