Skip to content

Commit 4a92d72

Browse files
committed
Further facelift
1 parent bc0fdda commit 4a92d72

37 files changed

+1010
-113
lines changed

src/java.base/share/classes/java/lang/classfile/CodeBuilder.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
* #with(ClassFileElement)} or concretely by calling the various {@code withXxx}
5252
* methods.
5353
*
54-
* <h2>Instruction Factories</h2>
54+
* <h2 id="instruction-factories">Instruction Factories</h2>
5555
* {@code CodeBuilder} provides convenience methods to create instructions (See
5656
* JVMS {@jvms 6.5} Instructions) by their mnemonic, taking necessary operands.
5757
* <ul>

src/java.base/share/classes/java/lang/classfile/Instruction.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,13 @@
3131
import jdk.internal.classfile.impl.AbstractInstruction;
3232

3333
/**
34-
* Models an executable instruction in the {@code code} array of the {@link CodeAttribute Code}
35-
* attribute of a method.
34+
* Models an executable instruction in the {@code code} array of the {@link
35+
* CodeAttribute Code} attribute of a method.
36+
* <p>
37+
* Physically, instructions are discriminated unions identified by thier {@link
38+
* #opcode() opcode()}. The exact type of the instruction can be identified
39+
* from {@link Opcode#kind() Opcode::kind}. {@link #sizeInBytes() sizeInBytes()}
40+
* indicates the exact size of such a discriminated union.
3641
*
3742
* @sealedGraph
3843
* @since 24

src/java.base/share/classes/java/lang/classfile/Label.java

+52-10
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,63 @@
2424
*/
2525
package java.lang.classfile;
2626

27+
import java.lang.classfile.attribute.CodeAttribute;
28+
import java.lang.classfile.instruction.LabelTarget;
29+
import java.util.ListIterator;
30+
2731
import jdk.internal.classfile.impl.LabelImpl;
2832

2933
/**
3034
* A marker for a position within the instructions of a method body. The
31-
* association between a label's identity and the position it represents is
32-
* managed by the entity managing the method body (a {@link CodeModel} or {@link
33-
* CodeBuilder}), not the label itself; this allows the same label to have a
34-
* meaning both in an existing method (as managed by a {@linkplain CodeModel})
35-
* and in the transformation of that method (as managed by a {@linkplain
36-
* CodeBuilder}), while corresponding to different positions in each. When
37-
* traversing the elements of a {@linkplain CodeModel}, {@linkplain Label}
38-
* markers will be delivered at the position to which they correspond. A label
39-
* can be bound to the current position within a {@linkplain CodeBuilder} via
40-
* {@link CodeBuilder#labelBinding(Label)} or {@link CodeBuilder#with(ClassFileElement)}.
35+
* position is a cursor position in the list of instructions, similar to that
36+
* of a {@link ListIterator}.
37+
*
38+
* <h2 id="reading">Reading Labels</h2>
39+
* Labels read from {@code class} files represent positions in the {@code code}
40+
* array of a {@link CodeAttribute Code} attribute. It is associated with a
41+
* <dfn>{@index bci}</dfn>, also known as <dfn>{@index pc}</dfn>, the index into
42+
* the {@code code} array; the actual cursor position is immediately before the
43+
* given index, so a label at the beginning of the instructions has bci {@code 0},
44+
* and a label at the end of the instructions has bci {@link CodeAttribute#codeLength
45+
* codeLength() + 1}. The bci can be inspected through {@link CodeAttribute#labelToBci
46+
* CodeAttribute::labelToBci}.
47+
* <p>
48+
* In generic {@link CodeModel}s, a label may not have a bci value; the position
49+
* of a label can be found by searching for the corresponding {@link LabelTarget}
50+
* within that model.
51+
*
52+
* <h2 id="writing">Writing Labels</h2>
53+
* Many models in {@code java.lang.classfile} refer to labels. To write a
54+
* label, a label must be obtained, it must be bound to a {@link CodeBuilder}.
55+
* <p>
56+
* To obtain a label:
57+
* <ul>
58+
* <li>Use a label read from other models.
59+
* <li>Use pre-defined labels from a {@link CodeBuilder}, such as {@link
60+
* CodeBuilder#startLabel() CodeBuilder::startLabel}, {@link CodeBuilder#endLabel
61+
* CodeBuilder::endLabel}, or {@link CodeBuilder.BlockCodeBuilder#breakLabel
62+
* BlockCodeBuilder::breakLabel}. They are already bound.
63+
* <li>Create labels with {@link CodeBuilder#newLabel CodeBuilder::newLabel} or
64+
* {@link CodeBuilder#newBoundLabel CodeBuilder::newBoundLabel}.
65+
* </ul>
66+
* <p>
67+
* A label must be bound exactly once in the {@code CodeBuilder} where it is
68+
* used; otherwise, writing fails. To bind an unbound label:
69+
* <ul>
70+
* <li>Send a {@link LabelTarget} to a {@code CodeBuilder}.
71+
* <li>Use {@link CodeBuilder#labelBinding CodeBuilder::labelBinding}.
72+
* </ul>
73+
* Note that a label read from another model is not automatically bound in a
74+
* {@code CodeBuilder}; they are separate entities and the label is bound to
75+
* different positions in them.
4176
*
77+
* @see CodeAttribute#labelToBci CodeAttribute::labelToBci
78+
* @see LabelTarget
79+
* @see CodeBuilder#newLabel CodeBuilder::newLabel
80+
* @see CodeBuilder#newBoundLabel CodeBuilder::newBoundLabel
81+
* @see CodeBuilder#startLabel CodeBuilder::startLabel
82+
* @see CodeBuilder#endLabel CodeBuilder::endLabel
83+
* @see CodeBuilder.BlockCodeBuilder#breakLabel BlockCodeBuilder::breakLabel
4284
* @since 24
4385
*/
4486
public sealed interface Label

src/java.base/share/classes/java/lang/classfile/Opcode.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -1290,7 +1290,7 @@ public enum Opcode {
12901290
GOTO(RawBytecodeHelper.GOTO, 3, Kind.BRANCH),
12911291

12921292
/**
1293-
* Jump subroutine (discontinued); last used in major version {@value
1293+
* (Discontinued) Jump subroutine; last used in major version {@value
12941294
* ClassFile#JAVA_6_VERSION}.
12951295
*
12961296
* @see DiscontinuedInstruction.JsrInstruction
@@ -1300,7 +1300,7 @@ public enum Opcode {
13001300
JSR(RawBytecodeHelper.JSR, 3, Kind.DISCONTINUED_JSR),
13011301

13021302
/**
1303-
* Return from subroutine (discontinued); last used in major version
1303+
* (Discontinued) Return from subroutine; last used in major version
13041304
* {@value ClassFile#JAVA_6_VERSION}.
13051305
*
13061306
* @see DiscontinuedInstruction.RetInstruction
@@ -1522,7 +1522,7 @@ public enum Opcode {
15221522
GOTO_W(RawBytecodeHelper.GOTO_W, 5, Kind.BRANCH),
15231523

15241524
/**
1525-
* Jump subroutine (wide index) (discontinued); last used in major
1525+
* (Discontinued) Jump subroutine (wide index); last used in major
15261526
* version {@value ClassFile#JAVA_6_VERSION}.
15271527
*
15281528
* @see DiscontinuedInstruction.JsrInstruction
@@ -1623,8 +1623,9 @@ public enum Opcode {
16231623
ASTORE_W((RawBytecodeHelper.WIDE << 8) | RawBytecodeHelper.ASTORE, 4, Kind.STORE),
16241624

16251625
/**
1626-
* Return from subroutine (wide index) (discontinued); last used in major
1626+
* (Discontinued) Return from subroutine (wide index) last used in major
16271627
* version {@value ClassFile#JAVA_6_VERSION}.
1628+
* This is a {@linkplain #isWide() wide}-modified pseudo-opcode.
16281629
*
16291630
* @see DiscontinuedInstruction.RetInstruction
16301631
* @jvms 4.9.1 Static Constraints
@@ -1635,6 +1636,7 @@ public enum Opcode {
16351636

16361637
/**
16371638
* Increment local variable by constant (wide index).
1639+
* This is a {@linkplain #isWide() wide}-modified pseudo-opcode.
16381640
*
16391641
* @jvms 6.5.wide <em>wide</em>
16401642
* @jvms 6.5.iinc <em>iinc</em>

src/java.base/share/classes/java/lang/classfile/instruction/ArrayLoadInstruction.java

+22-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*/
2525
package java.lang.classfile.instruction;
2626

27+
import java.lang.classfile.CodeBuilder;
2728
import java.lang.classfile.CodeElement;
2829
import java.lang.classfile.CodeModel;
2930
import java.lang.classfile.Instruction;
@@ -38,15 +39,34 @@
3839
* attribute. Corresponding opcodes have a {@linkplain Opcode#kind() kind}
3940
* of {@link Opcode.Kind#ARRAY_LOAD}. Delivered as a {@link CodeElement} when
4041
* traversing the elements of a {@link CodeModel}.
42+
* <p>
43+
* Conceptually, an array load instruction is a record:
44+
* {@snippet lang=text :
45+
* // @link substring="ArrayLoadInstruction" target="CodeBuilder#arrayLoad(TypeKind)" :
46+
* ArrayLoadInstruction(TypeKind) // @link substring="TypeKind" target="#typeKind()"
47+
* }
48+
* where the {@code TypeKind} is not {@link TypeKind#BOOLEAN boolean} or
49+
* {@link TypeKind#VOID void}. Boolean arrays use the {@link TypeKind#BYTE
50+
* byte} kind instruction.
51+
* <p>
52+
* Physically, an array load instruction is a record:
53+
* {@snippet lang=text :
54+
* // @link substring="ArrayLoadInstruction" target="#of(Opcode)" :
55+
* ArrayLoadInstruction(Opcode) // @link substring="Opcode" target="#opcode()"
56+
* }
57+
* where the {@code Opcode} is of the array load kind. The component type of
58+
* the array is intrinsic to the opcode.
4159
*
60+
* @see CodeBuilder#arrayLoad CodeBuilder::arrayLoad
4261
* @since 24
4362
*/
4463
public sealed interface ArrayLoadInstruction extends Instruction
4564
permits AbstractInstruction.UnboundArrayLoadInstruction {
4665
/**
47-
* {@return the component type of the array} The {@link TypeKind#BYTE byte}
66+
* {@return the component type of the array} The {@link TypeKind#BYTE byte}
4867
* type load instruction {@link Opcode#BALOAD baload} also operates on
49-
* {@link TypeKind#BOOLEAN boolean} arrays.
68+
* {@link TypeKind#BOOLEAN boolean} arrays, so this never returns
69+
* {@code boolean}.
5070
*/
5171
TypeKind typeKind();
5272

src/java.base/share/classes/java/lang/classfile/instruction/ArrayStoreInstruction.java

+22-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*/
2525
package java.lang.classfile.instruction;
2626

27+
import java.lang.classfile.CodeBuilder;
2728
import java.lang.classfile.CodeElement;
2829
import java.lang.classfile.CodeModel;
2930
import java.lang.classfile.Instruction;
@@ -38,15 +39,34 @@
3839
* attribute. Corresponding opcodes have a {@linkplain Opcode#kind() kind}
3940
* of {@link Opcode.Kind#ARRAY_STORE}. Delivered as a {@link CodeElement} when
4041
* traversing the elements of a {@link CodeModel}.
42+
* <p>
43+
* Conceptually, an array store instruction is a record:
44+
* {@snippet lang=text :
45+
* // @link substring="ArrayStoreInstruction" target="CodeBuilder#arrayStore(TypeKind)" :
46+
* ArrayStoreInstruction(TypeKind) // @link substring="TypeKind" target="#typeKind()"
47+
* }
48+
* where the {@code TypeKind} is not {@link TypeKind#BOOLEAN boolean} or
49+
* {@link TypeKind#VOID void}. Boolean arrays use the {@link TypeKind#BYTE
50+
* byte} kind instruction.
51+
* <p>
52+
* Physically, an array store instruction is a record:
53+
* {@snippet lang=text :
54+
* // @link substring="ArrayStoreInstruction" target="#of(Opcode)" :
55+
* ArrayStoreInstruction(Opcode) // @link substring="Opcode" target="#opcode()"
56+
* }
57+
* where the {@code Opcode} is of the array store kind. The component type of
58+
* the array is intrinsic to the opcode.
4159
*
60+
* @see CodeBuilder#arrayStore CodeBuilder::arrayStore
4261
* @since 24
4362
*/
4463
public sealed interface ArrayStoreInstruction extends Instruction
4564
permits AbstractInstruction.UnboundArrayStoreInstruction {
4665
/**
47-
* {@return the component type of the array} The {@link TypeKind#BYTE byte}
66+
* {@return the component type of the array} The {@link TypeKind#BYTE byte}
4867
* type store instruction {@link Opcode#BASTORE bastore} also operates on
49-
* {@link TypeKind#BOOLEAN boolean} arrays.
68+
* {@link TypeKind#BOOLEAN boolean} arrays, so this never returns
69+
* {@code boolean}.
5070
*/
5171
TypeKind typeKind();
5272

src/java.base/share/classes/java/lang/classfile/instruction/BranchInstruction.java

+23-10
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,7 @@
2424
*/
2525
package java.lang.classfile.instruction;
2626

27-
import java.lang.classfile.ClassFile;
28-
import java.lang.classfile.CodeBuilder;
29-
import java.lang.classfile.CodeElement;
30-
import java.lang.classfile.CodeModel;
31-
import java.lang.classfile.Instruction;
32-
import java.lang.classfile.Label;
33-
import java.lang.classfile.Opcode;
27+
import java.lang.classfile.*;
3428

3529
import jdk.internal.classfile.impl.AbstractInstruction;
3630
import jdk.internal.classfile.impl.Util;
@@ -41,10 +35,29 @@
4135
* {@linkplain Opcode#kind() kind} of {@link Opcode.Kind#BRANCH}. Delivered as
4236
* a {@link CodeElement} when traversing the elements of a {@link CodeModel}.
4337
* <p>
44-
* A branch instruction may be rewritten in a {@link CodeBuilder} if the {@link
45-
* #target() target} cannot be encoded and the {@link ClassFile.ShortJumpsOption#FIX_SHORT_JUMPS
46-
* FIX_SHORT_JUMPS} option is set.
38+
* Conceptually, a branch instruction is a record:
39+
* {@snippet lang=text :
40+
* // @link region substring="BranchInstruction" target="#of"
41+
* // @link substring="Opcode" target="#opcode()" :
42+
* BranchInstruction(Opcode, Label) // @link substring="Label" target="#target()"
43+
* // @end
44+
* }
45+
* where the {@code Opcode} is of the branch kind.
46+
* <p>
47+
* Physically, a branch instruction has the same structure; however, some types
48+
* of instructions use a {@code s2} to encode the target, which is insufficient
49+
* to encode targets with bci offsets less than {@code -32768} or greater than
50+
* {@code 32767}. Such instructions have a {@linkplain Opcode#sizeIfFixed()
51+
* size} of {@code 3} bytes.
52+
* <p>
53+
* In such cases, if the {@link ClassFile.ShortJumpsOption#FIX_SHORT_JUMPS
54+
* FIX_SHORT_JUMPS} option is set, a {@link CodeBuilder} will convert this
55+
* instruction to other instructions to achieve the same effect. Otherwise,
56+
* {@link ClassFile.ShortJumpsOption#FAIL_ON_SHORT_JUMPS FAIL_ON_SHORT_JUMPS}
57+
* option can ensure the physical accuracy of the generated {@code class} file
58+
* and fail if an exact representation is not possible.
4759
*
60+
* @see CodeBuilder#branch CodeBuilder::branch
4861
* @since 24
4962
*/
5063
public sealed interface BranchInstruction extends Instruction

src/java.base/share/classes/java/lang/classfile/instruction/CharacterRange.java

+24-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
package java.lang.classfile.instruction;
2626

2727
import java.lang.classfile.ClassFile;
28+
import java.lang.classfile.CodeBuilder;
2829
import java.lang.classfile.CodeElement;
2930
import java.lang.classfile.CodeModel;
3031
import java.lang.classfile.Label;
@@ -40,7 +41,29 @@
4041
* {@link CharacterRangeTableAttribute}. Delivered as a {@link CodeElement}
4142
* during traversal of the elements of a {@link CodeModel}, according to
4243
* the setting of the {@link ClassFile.DebugElementsOption} option.
44+
* <p>
45+
* Conceptually, a character range entry is a record:
46+
* {@snippet lang=text :
47+
* // @link region=0 substring="CharacterRange" target="#of"
48+
* // @link region=1 substring="Label startScope" target="#startScope"
49+
* // @link region=2 substring="Label endScope" target="#endScope"
50+
* // @link region=3 substring="int characterRangeStart" target="#characterRangeStart"
51+
* // @link region=4 substring="int characterRangeEnd" target="#characterRangeEnd"
52+
* // @link substring="int flags" target="#flags()" :
53+
* CharacterRange(Label startScope, Label endScope, int characterRangeStart, int characterRangeEnd, int flags)
54+
* // @end region=0
55+
* // @end region=1
56+
* // @end region=2
57+
* // @end region=3
58+
* // @end region=4
59+
* }
60+
* <p>
61+
* Physically, a character range has the same structure; it is modeled by a
62+
* {@link CharacterRangeInfo}.
4363
*
64+
* @see CharacterRangeTableAttribute
65+
* @see CharacterRangeInfo
66+
* @see CodeBuilder#characterRange CodeBuilder::characterRange
4467
* @since 24
4568
*/
4669
public sealed interface CharacterRange extends PseudoInstruction
@@ -114,7 +137,7 @@ public sealed interface CharacterRange extends PseudoInstruction
114137
* <li>{@link #FLAG_BRANCH_FALSE}
115138
* </ul>
116139
*
117-
* @see java.lang.classfile.attribute.CharacterRangeInfo#flags()
140+
* @see CharacterRangeInfo#flags()
118141
*
119142
* @return the flags
120143
*/

0 commit comments

Comments
 (0)