This specification is not final and is subject to change. Use is subject to license terms.

Inline Classes (Milestone LW2)

Changes to the Java® Virtual Machine Specification • Version 14-internal+0-adhoc.dlsmith.20190628

This document describes changes to the Java Virtual Machine Specification to support inline classes.

It incorporates additional changes from:

Changes are described with respect to existing sections of the JVM Specification. New text is indicated like this and deleted text is indicated like this. Explanation and discussion, as needed, is set aside in grey boxes.

Unresolved items:

Chapter 2: The Structure of the Java Virtual Machine

2.2 Data Types

The Java Virtual Machine operates on two kinds of types: primitive types and reference types. There are, correspondingly, two kinds of values that can be stored in variables, passed as arguments, returned by methods, and operated upon: primitive values and reference values.

The Java Virtual Machine expects that nearly all type checking is done prior to run time, typically by a compiler, and does not have to be done by the Java Virtual Machine itself. Values of primitive types need not be tagged or otherwise be inspectable to determine their types at run time, or to be distinguished from values of reference types. Instead, the instruction set of the Java Virtual Machine distinguishes its operand types using instructions intended to operate on values of specific types. For instance, iadd, ladd, fadd, and dadd are all Java Virtual Machine instructions that add two numeric values and produce numeric results, but each is specialized for its operand type: int, long, float, and double, respectively. For a summary of type support in the Java Virtual Machine instruction set, see 2.11.1.

The Java Virtual Machine contains explicit support for objects. An object is either a dynamically allocated class instance or an array. A reference to an object is considered to have Java Virtual Machine type reference. References are polymorphic: a single reference may also be a value of multiple class types, interface types, or array types. Values of type reference can be thought of as pointers to objects. More than one reference to an object may exist. Objects are always operated on, passed, and tested via values of type reference.

2.4 Reference Types and Values

There are three five kinds of reference types: identity class types, inline class types, array types, and interface types, and the Object type. Their values are references to dynamically created class instances, arrays, or class instances or arrays that implement interfaces, respectively objects.

Most reference types are nullable, meaning the special null reference (representing the absence of an object) is a value of the type. Some reference types are null-free, meaning that null is not a value of the type.

A reference value may also be the special null reference, a reference to no object, which will be denoted here by null. The null reference initially has no run-time type, but may be cast to any type. The default value of a reference type is null.

The default value of a nullable reference type is null. The default value of a null-free inline class type is a reference to a class instance whose fields all have the default value for their type.

This specification does not mandate a concrete value encoding null.

2.11 Instruction Set Summary

2.11.2 Load and Store Instructions

The load and store instructions transfer values between the local variables (2.6.1) and the operand stack (2.6.2) of a Java Virtual Machine frame (2.6):

Instructions that access fields of objects and elements of arrays (2.11.5) also transfer data to and from the operand stack.

Instruction mnemonics shown above with trailing letters between angle brackets (for instance, iload_<n>) denote families of instructions (with members iload_0, iload_1, iload_2, and iload_3 in the case of iload_<n>). Such families of instructions are specializations of an additional generic instruction (iload) that takes one operand. For the specialized instructions, the operand is implicit and does not need to be stored or fetched. The semantics are otherwise the same (iload_0 means the same thing as iload with the operand 0). The letter between the angle brackets specifies the type of the implicit operand for that family of instructions: for <n>, a nonnegative integer; for <i>, an int; for <l>, a long; for <f>, a float; and for <d>, a double.

This notation for instruction families is used throughout this specification.

2.11.5 Object Creation and Manipulation

Although both class instances and arrays are objects, the Java Virtual Machine creates and manipulates class instances and arrays using distinct sets of instructions:

Chapter 4: The class File Format

4.1 The ClassFile Structure

A class file consists of a single ClassFile structure:

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

The items in the ClassFile structure are as follows:

magic

The magic item supplies the magic number identifying the class file format; it has the value 0xCAFEBABE.

minor_version, major_version

The values of the minor_version and major_version items are the minor and major version numbers of this class file. Together, a major and a minor version number determine the version of the class file format. If a class file has major version number M and minor version number m, we denote the version of its class file format as M.m.

A Java Virtual Machine implementation which conforms to Java SE N must support exactly the major versions of the class file format specified for Java SE N in Table 4.1-A. The notation A .. B means major versions A through B inclusive. The column "Corresponding major version" denotes the major version introduced by each Java SE release, that is, the first release that could have accepted a class file containing that major_version item. For very early releases, the JDK version is shown instead of the Java SE release.

Table 4.1-A. class file format major versions

Java SE Corresponding major version Supported major versions
1.0.2 45 45
1.1 45 45
1.2 46 45 .. 46
1.3 47 45 .. 47
1.4 48 45 .. 48
5.0 49 45 .. 49
6 50 45 .. 50
7 51 45 .. 51
8 52 45 .. 52
9 53 45 .. 53
10 54 45 .. 54
11 55 45 .. 55
12 56 45 .. 56

For a class file whose major_version is 56 or above, the minor_version must be 0 or 65535.

For a class file whose major_version is between 45 and 55 inclusive, the minor_version may be any value.

A historical perspective on versions of the class file format is warranted. JDK 1.0.2 supported versions 45.0 through 45.3 inclusive. JDK 1.1 supported versions 45.0 through 45.65535 inclusive. When JDK 1.2 introduced support for major version 46, the only minor version supported under that major version was 0. Later JDKs continued the practice of introducing support for a new major version (47, 48, etc) but supporting only a minor version of 0 under the new major version. Finally, the introduction of preview features in Java SE 12 (see below) motivated a standard role for the minor version of the class file format, so JDK 12 supported minor versions of 0 and 65535 under major version 56. Subsequent JDKs introduce support for N.0 and N.65535 where N is the corresponding major version of the implemented Java SE Platform.

The Java SE Platform may define preview features. A Java Virtual Machine implementation which conforms to Java SE N (N 12) must support all the preview features of Java SE N, and none of the preview features of any other Java SE release. The implementation must by default disable the supported preview features, and must provide a way to enable all of them, and must not provide a way to enable only some of them.

A class file is said to depend on the preview features of Java SE N (N 12) if it has a major_version that corresponds to Java SE N (according to Table 4.1-A) and a minor_version of 65535.

A Java Virtual Machine implementation which conforms to Java SE N (N 12) must behave as follows:

constant_pool_count

The value of the constant_pool_count item is equal to the number of entries in the constant_pool table plus one. A constant_pool index is considered valid if it is greater than zero and less than constant_pool_count, with the exception for constants of type long and double noted in 4.4.5.

constant_pool[]

The constant_pool is a table of structures (4.4) representing various string constants, class and interface names, field names, and other constants that are referred to within the ClassFile structure and its substructures. The format of each constant_pool table entry is indicated by its first "tag" byte.

The constant_pool table is indexed from 1 to constant_pool_count - 1.

access_flags

The value of the access_flags item is a mask of flags used to denote access permissions to and properties of this class or interface. The interpretation of each flag, when set, is specified in Table 4.1-B.

Table 4.1-B. Class access and property modifiers

Flag Name Value Interpretation
ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_FINAL 0x0010 Declared final; no subclasses allowed.
ACC_SUPER 0x0020 Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INLINE 0x0100 Is an inline class.
ACC_INTERFACE 0x0200 Is an interface, not a class.
ACC_ABSTRACT 0x0400 Declared abstract; must not be instantiated.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.
ACC_ANNOTATION 0x2000 Declared as an annotation type.
ACC_ENUM 0x4000 Declared as an enum type.
ACC_MODULE 0x8000 Is a module, not a class or interface.

The ACC_MODULE flag indicates that this class file defines a module, not a class or interface. If the ACC_MODULE flag is set, then special rules apply to the class file which are given at the end of this section. If the ACC_MODULE flag is not set, then the rules immediately below the current paragraph apply to the class file.

An interface is distinguished by the ACC_INTERFACE flag being set. If the ACC_INTERFACE flag is not set, this class file defines a class, not an interface.

If the ACC_INTERFACE flag is set, the ACC_ABSTRACT flag must also be set, and the ACC_FINAL, ACC_SUPER, ACC_ENUM, ACC_INLINE, and ACC_MODULE flags must not be set.

An inline class is identified with the ACC_INLINE flag being set.

If the ACC_INLINE flag is set, the ACC_FINAL flag must also be set, and the ACC_ABSTRACT, ACC_SUPER, ACC_ENUM, ACC_INTERFACE, and ACC_MODULE flags must not be set.

If neither the ACC_MODULE flag nor the ACC_INTERFACE flag none of the ACC_MODULE, ACC_INTERFACE, or ACC_INLINE flags is set, the ClassFile structure represents a class an identity class or the class Object, and any of the other flags in Table 4.1-B may be set except ACC_ANNOTATION.

If the ACC_FINAL flag is set, the ACC_ABSTRACT flag must not be set.

The ACC_SUPER flag indicates which of two alternative semantics is to be expressed by the invokespecial instruction (6.5.invokespecial) if it appears in this class or interface. Compilers to the instruction set of the Java Virtual Machine should set the ACC_SUPER flag. In Java SE 8 and above, the Java Virtual Machine considers the ACC_SUPER flag to be set in every class file, regardless of the actual value of the flag in the class file and the version of the class file.

The ACC_SUPER flag exists for backward compatibility with code compiled by older compilers for the Java programming language. Prior to JDK 1.0.2, the compiler generated access_flags in which the flag now representing ACC_SUPER had no assigned meaning, and Oracle's Java Virtual Machine implementation ignored the flag if it was set.

The ACC_SYNTHETIC flag indicates that this class or interface was generated by a compiler and does not appear in source code.

An annotation type (JLS §9.6) must have its ACC_ANNOTATION flag set. If the ACC_ANNOTATION flag is set, the ACC_INTERFACE flag must also be set.

The ACC_ENUM flag indicates that this class or its superclass is declared as an enumerated type (JLS §8.9).

All bits of the access_flags item not assigned in Table 4.1-B are reserved for future use. They should be set to zero in generated class files and should be ignored by Java Virtual Machine implementations.

In a class file whose version number is less than 57.0, the ACC_INLINE flag should not be set and is treated as if it were not set.

Design discussion: access_flags provide a convenient way to document that a class is an inline class, but there are other ways we could encode the same information. For example, an attribute could be present, or a particular superclass could be used.

this_class

The value of the this_class item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure (4.4.1) representing the class or interface defined by this class file.

The CONSTANT_Utf8_info of the CONSTANT_Class_info structure must be a class or interface name, not a field descriptor.

super_class

For a class, the value of the super_class item either must be zero or must be a valid index into the constant_pool table. If the value of the super_class item is nonzero, the constant_pool entry at that index must be a CONSTANT_Class_info structure representing the direct superclass of the class defined by this class file. Neither the direct superclass nor any of its superclasses may have the ACC_FINAL flag set in the access_flags item of its ClassFile structure.

If the value of the super_class item is zero, then this class file must represent the class Object, the only class or interface without a direct superclass.

The CONSTANT_Utf8_info of the CONSTANT_Class_info structure, if present, must be a class name, not a field descriptor.

For an interface or an inline class, the value of the super_class item must always be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure representing the class Object.

interfaces_count

The value of the interfaces_count item gives the number of direct superinterfaces of this class or interface.

interfaces[]

Each value in the interfaces array must be a valid index into the constant_pool table. The constant_pool entry at each value of interfaces[*i*], where 0 i < interfaces_count, must be a CONSTANT_Class_info structure representing an interface that is a direct superinterface of this class or interface, in the left-to-right order given in the source for the class or interface.

The CONSTANT_Utf8_info of each CONSTANT_Class_info structure must be an interface name, not a field descriptor.

fields_count

The value of the fields_count item gives the number of field_info structures in the fields table. The field_info structures represent all fields, both class variables and instance variables, declared by this class or interface.

fields[]

Each value in the fields table must be a field_info structure (4.5) giving a complete description of a field in this class or interface. The fields table includes only those fields that are declared by this class or interface. It does not include items representing fields that are inherited from superclasses or superinterfaces.

methods_count

The value of the methods_count item gives the number of method_info structures in the methods table.

methods[]

Each value in the methods table must be a method_info structure (4.6) giving a complete description of a method in this class or interface. If neither of the ACC_NATIVE and ACC_ABSTRACT flags are set in the access_flags item of a method_info structure, the Java Virtual Machine instructions implementing the method are also supplied.

The method_info structures represent all methods declared by this class or interface, including instance methods, class methods, instance initialization methods (2.9.1), and any class or interface initialization method (2.9.2). The methods table does not include items representing methods that are inherited from superclasses or superinterfaces.

attributes_count

The value of the attributes_count item gives the number of attributes in the attributes table of this class.

attributes[]

Each value of the attributes table must be an attribute_info structure (4.7).

The attributes defined by this specification as appearing in the attributes table of a ClassFile structure are listed in Table 4.7-C.

The rules concerning attributes defined to appear in the attributes table of a ClassFile structure are given in 4.7.

The rules concerning non-predefined attributes in the attributes table of a ClassFile structure are given in 4.7.1.

If the ACC_MODULE flag is set in the access_flags item, then no other flag in the access_flags item may be set, and the following rules apply to the rest of the ClassFile structure:

4.3 Descriptors

4.3.2 Field Descriptors

A field descriptor represents the type of a field, parameter, value, or local variable.

FieldDescriptor:
FieldType
FieldType:
BaseType
ClassType
ArrayType
ReferenceType
BaseType:
(one of)
B C D F I J S Z
ReferenceType:
NullableClassType
NullFreeClassType
ArrayType
ClassType: NullableClassType:
L ClassName ;
NullFreeClassType:
Q ClassName ;
ArrayType:
[ ComponentType
ComponentType:
FieldType

ClassName represents a binary class or interface name encoded in internal form (4.2.1).

A field descriptor mentions a class or interface name if the name appears as a ClassName in the descriptor. This includes a ClassName nested in the ComponentType of an ArrayType.

The interpretation of field descriptors as types is shown in Table 4.3-A. See 2.2, 2.3, and 2.4 for the meaning of these types.

A field descriptor representing an array type is valid only if it represents a type with 255 or fewer dimensions.

Table 4.3-A. Interpretation of field descriptors

FieldType term Type
B byte
C char
D double
F float
I int
J long
L ClassName ; Named Nullable named class or interface type
Q ClassName ; Null-free named inline class type
S short
Z boolean
[ Array of given component type

The field descriptor of an instance variable of type int is simply I.

The field descriptor of an instance variable of type Object is Ljava/lang/Object;. Note that the internal form of the binary name for class Object is used.

The field descriptor of an instance variable of the multidimensional array type double[][][] is [[[D.

4.4 The Constant Pool

Design discussion: the withfield and defaultvalue instructions may justify new forms of CONSTANT_MethodHandle, but for now no changes are made to 4.4.8.

4.4.1 The CONSTANT_Class_info Structure

The CONSTANT_Class_info structure is used to represent a class, an interface, or an array a reference type:

CONSTANT_Class_info {
    u1 tag;
    u2 name_index;
}

The items of the CONSTANT_Class_info structure are as follows:

tag

The tag item has the value CONSTANT_Class (7).

name_index

The value of the name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing either a valid binary class or interface name encoded in internal form (4.2.1) or an ArrayType a ReferenceType descriptor (4.3.2).

In a class file whose version number is less than 57.0, the name_index item must not be a field descriptor of the form NullableClassType or NullFreeClassType.

For example, the name_index string representing the class String is java/lang/String. The name_index string representing the identity class type String is Ljava/lang/String;. The name_index string representing the interface Runnable is java/lang/Runnable. The name_index string representing the null-free inline class type Foo is QFoo;. The name_index string representing the array type Thread[] is [Ljava/lang/Thread;. The name_index string representing the array type int[][] is [[I.

Note that it is not supported to represent a primitive type with a CONSTANT_Class_info. For example, the name_index string D represents a class or interface named D, not the primitive type double.

Design discussion: as a minimum, we need a way to encode null-free types for anewarray. A constant pool encoding is also convenient for ldc, checkcast, and bootstrap arguments. For consistency, instanceof should probably support null-free types too (although instanceof Foo and instanceof QFoo; will always have the same result).

The strategy used here is to overload CONSTANT_Class_info with null-free class type descriptors. In doing so, there's no particular reason (though we may decide to be more restrictive) that L types can't be supported, too, as an alternative to bare class names in contexts that work on arbitrary types. The only descriptors that can't be allowed, due to syntactic ambiguity, are those for primitive types—supporting primitive types would require new syntax.

Despite the overloading, many contexts that use CONSTANT_Class_info only permit class or interface names, not arbitrary types. In these contexts, type descriptors continue to be prohibited. The overhead and risks associated with validating all of these contexts may make it worthwhile to instead introduce a new kind of constant for types.

4.4.2 The CONSTANT_Fieldref_info, CONSTANT_Methodref_info, and CONSTANT_InterfaceMethodref_info Structures

Fields, methods, and interface methods are represented by similar structures:

CONSTANT_Fieldref_info {
    u1 tag;
    u2 class_index;
    u2 name_and_type_index;
}

CONSTANT_Methodref_info {
    u1 tag;
    u2 class_index;
    u2 name_and_type_index;
}

CONSTANT_InterfaceMethodref_info {
    u1 tag;
    u2 class_index;
    u2 name_and_type_index;
}

The items of these structures are as follows:

tag

The tag item of a CONSTANT_Fieldref_info structure has the value CONSTANT_Fieldref (9).

The tag item of a CONSTANT_Methodref_info structure has the value CONSTANT_Methodref (10).

The tag item of a CONSTANT_InterfaceMethodref_info structure has the value CONSTANT_InterfaceMethodref (11).

class_index

The value of the class_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure (4.4.1) representing a class or interface that has the field or method as a member.

The CONSTANT_Utf8_info of the CONSTANT_Class_info structure must be a class or interface name, not a field descriptor.

In a CONSTANT_Fieldref_info structure, the class_index item may be either a class or an interface.

In a CONSTANT_Methodref_info structure, the class_index item must be a class, not an interface.

In a CONSTANT_InterfaceMethodref_info structure, the class_index item must be an interface, not a class.

name_and_type_index

The value of the name_and_type_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_NameAndType_info structure (4.4.6). This constant_pool entry indicates the name and descriptor of the field or method.

In a CONSTANT_Fieldref_info structure, the indicated descriptor must be a field descriptor (4.3.2). Otherwise, the indicated descriptor must be a method descriptor (4.3.3).

In a CONSTANT_Methodref_info structure or a CONSTANT_InterfaceMethodref structure, the referenced name must be a valid method name (4.2.2).

4.4.6 The CONSTANT_NameAndType_info Structure

The CONSTANT_NameAndType_info structure is used to represent a field or method, without indicating which class or interface it belongs to:

CONSTANT_NameAndType_info {
    u1 tag;
    u2 name_index;
    u2 descriptor_index;
}

The items of the CONSTANT_NameAndType_info structure are as follows:

tag

The tag item has the value CONSTANT_NameAndType (12).

name_index

The value of the name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing a valid unqualified name (4.2.2).

descriptor_index

The value of the descriptor_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing a valid field descriptor or method descriptor (4.3.2, 4.3.3).

In a class file whose version number is less than 57.0, the field or method descriptor must not make use of any type of the form NullFreeClassType.

4.4.9 The CONSTANT_MethodType_info Structure

The CONSTANT_MethodType_info structure is used to represent a method type:

CONSTANT_MethodType_info {
    u1 tag;
    u2 descriptor_index;
}

The items of the CONSTANT_MethodType_info structure are as follows:

tag

The tag item has the value CONSTANT_MethodType (16).

descriptor_index

The value of the descriptor_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing a method descriptor (4.3.3).

In a class file whose version number is less than 57.0, the method descriptor must not make use of any type of the form NullFreeClassType.

4.5 Fields

Each field is described by a field_info structure.

No two fields in one class file may have the same name and descriptor (4.3.2).

The structure has the following format:

field_info {
    u2             access_flags;
    u2             name_index;
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

The items of the field_info structure are as follows:

access_flags

The value of the access_flags item is a mask of flags used to denote access permission to and properties of this field. The interpretation of each flag, when set, is specified in Table 4.5-A.

Table 4.5-A. Field access and property flags

Flag Name Value Interpretation
ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_PRIVATE 0x0002 Declared private; accessible only within the defining class and other classes belonging to the same nest (5.4.4).
ACC_PROTECTED 0x0004 Declared protected; may be accessed within subclasses.
ACC_STATIC 0x0008 Declared static.
ACC_FINAL 0x0010 Declared final; never directly assigned to after object construction (JLS §17.5).
ACC_VOLATILE 0x0040 Declared volatile; cannot be cached.
ACC_TRANSIENT 0x0080 Declared transient; not written or read by a persistent object manager.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.
ACC_ENUM 0x4000 Declared as an element of an enum.

Fields of classes may set any of the flags in Table 4.5-A. However, each field of a class may have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set (JLS §8.3.1), and must not have both its ACC_FINAL and ACC_VOLATILE flags set (JLS §8.3.1.4). Each field of an inline class must have at least one of its ACC_STATIC or ACC_FINAL flags set.

Fields of interfaces must have their ACC_PUBLIC, ACC_STATIC, and ACC_FINAL flags set; they may have their ACC_SYNTHETIC flag set and must not have any of the other flags in Table 4.5-A set (JLS §9.3).

The ACC_SYNTHETIC flag indicates that this field was generated by a compiler and does not appear in source code.

The ACC_ENUM flag indicates that this field is used to hold an element of an enumerated type.

All bits of the access_flags item not assigned in Table 4.5-A are reserved for future use. They should be set to zero in generated class files and should be ignored by Java Virtual Machine implementations.

name_index

The value of the name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) which represents a valid unqualified name denoting a field (4.2.2).

descriptor_index

The value of the descriptor_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) which represents a valid field descriptor (4.3.2).

In a class file whose version number is less than 57, the field descriptor must not make use of any type of the form NullFreeClassType.

attributes_count

The value of the attributes_count item indicates the number of additional attributes of this field.

attributes[]

Each value of the attributes table must be an attribute_info structure (4.7).

A field can have any number of optional attributes associated with it.

The attributes defined by this specification as appearing in the attributes table of a field_info structure are listed in Table 4.7-C.

The rules concerning attributes defined to appear in the attributes table of a field_info structure are given in 4.7.

The rules concerning non-predefined attributes in the attributes table of a field_info structure are given in 4.7.1.

4.6 Methods

Each method, including each instance initialization method (2.9.1) and the class or interface initialization method (2.9.2), is described by a method_info structure.

No two methods in one class file may have the same name and descriptor (4.3.3).

The structure has the following format:

method_info {
    u2             access_flags;
    u2             name_index;
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

The items of the method_info structure are as follows:

access_flags

The value of the access_flags item is a mask of flags used to denote access permission to and properties of this method. The interpretation of each flag, when set, is specified in Table 4.6-A.

Table 4.6-A. Method access and property flags

Flag Name Value Interpretation
ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_PRIVATE 0x0002 Declared private; accessible only within the defining class and other classes belonging to the same nest (5.4.4).
ACC_PROTECTED 0x0004 Declared protected; may be accessed within subclasses.
ACC_STATIC 0x0008 Declared static.
ACC_FINAL 0x0010 Declared final; must not be overridden (5.4.5).
ACC_SYNCHRONIZED 0x0020 Declared synchronized; invocation is wrapped by a monitor use.
ACC_BRIDGE 0x0040 A bridge method, generated by the compiler.
ACC_VARARGS 0x0080 Declared with variable number of arguments.
ACC_NATIVE 0x0100 Declared native; implemented in a language other than the Java programming language.
ACC_ABSTRACT 0x0400 Declared abstract; no implementation is provided.
ACC_STRICT 0x0800 Declared strictfp; floating-point mode is FP-strict.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.

An instance initialization method (that is, a method with name <init> and return descriptor V) may have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set, and may also have its ACC_VARARGS, ACC_STRICT, and ACC_SYNTHETIC flags set, but must not have any of the other flags in Table 4.6-A set.

In a class file whose version number is 57.0 or above, a class or interface initialization method (that is, a method declared with name <clinit> and descriptor ()V) must have its ACC_STATIC flag set, and may also have its ACC_STRICT and ACC_SYNTHETIC flags set, but must not have any of the other flags in Table 4.6-A set.

In a class file whose version number is less than 57.0, a class or interface initialization method may have any of the flags in Table 4.6-A set, in any combination, but all flags except ACC_STATIC, ACC_STRICT, and ACC_SYNTHETIC are treated by the Java Virtual Machine as if they were not set. If the major version number is 51 to 56, inclusive, the ACC_STATIC flag must be set; if the major version number is 50 or below, the ACC_STATIC flag is treated by the Java Virtual Machine as if it were set.

Methods of classes other than instance initialization methods and the class initialization method may have any of the flags in Table 4.6-A set. However, each non-initialization method of a class may have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set (JLS §8.4.3).

A method of an inline class that has its ACC_SYNCHRONIZED flag set must also have its ACC_STATIC flag set.

Methods of interfaces other than the interface initialization method may have any of the flags in Table 4.6-A set except ACC_PROTECTED, ACC_FINAL, ACC_SYNCHRONIZED, and ACC_NATIVE (JLS §9.4); exactly one of the ACC_PUBLIC or ACC_PRIVATE flags must be set. In a class file whose version number is less than 52.0, each non-initialization method of an interface must have its ACC_PUBLIC and ACC_ABSTRACT flags set.

If a method of a class or interface has its ACC_ABSTRACT flag set, it must not have any of its ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, or ACC_STRICT flags set.

The ACC_BRIDGE flag is used to indicate a bridge method generated by a compiler for the Java programming language.

The ACC_VARARGS flag indicates that this method takes a variable number of arguments at the source code level.

The ACC_SYNTHETIC flag indicates that this method was generated by a compiler and does not appear in source code, and is not one of the methods named in 4.7.8.

All bits of the access_flags item not assigned in Table 4.6-A are reserved for future use. They should be set to zero in generated class files and should be ignored by Java Virtual Machine implementations.

name_index

The value of the name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing a valid unqualified method name (4.2.2).

descriptor_index

The value of the descriptor_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing a valid method descriptor (4.3.3).

If this method is declared in an inline class or an interface, and the name of the method is <init>, then the descriptor must not denote a void method.

Instance initialization methods are not allowed in interfaces only allowed in identity classes and the class Object.

In a class file whose version number is less than 57.0, the method descriptor must not make use of any type of the form NullFreeClassType.

A future edition of this specification may require that the last parameter descriptor of the method descriptor is an array type if the ACC_VARARGS flag is set in the access_flags item.

attributes_count

The value of the attributes_count item indicates the number of additional attributes of this method.

attributes[]

Each value of the attributes table must be an attribute_info structure (4.7).

A method can have any number of optional attributes associated with it.

The attributes defined by this specification as appearing in the attributes table of a method_info structure are listed in Table 4.7-C.

The rules concerning attributes defined to appear in the attributes table of a method_info structure are given in 4.7.

The rules concerning non-predefined attributes in the attributes table of a method_info structure are given in 4.7.1.

4.7 Attributes

4.7.3 The Code Attribute

The Code attribute is a variable-length attribute in the attributes table of a method_info structure (4.6). A Code attribute contains the Java Virtual Machine instructions and auxiliary information for a method, including an instance initialization method and a class or interface initialization method (2.9.1, 2.9.2).

If the method is either native or abstract, and is not a class or interface initialization method, then its method_info structure must not have a Code attribute in its attributes table. Otherwise, its method_info structure must have exactly one Code attribute in its attributes table.

The Code attribute has the following format:

Code_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 max_stack;
    u2 max_locals;
    u4 code_length;
    u1 code[code_length];
    u2 exception_table_length;
    {   u2 start_pc;
        u2 end_pc;
        u2 handler_pc;
        u2 catch_type;
    } exception_table[exception_table_length];
    u2 attributes_count;
    attribute_info attributes[attributes_count];
}

The items of the Code_attribute structure are as follows:

attribute_name_index

The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing the string "Code".

attribute_length

The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes.

max_stack

The value of the max_stack item gives the maximum depth of the operand stack of this method (2.6.2) at any point during execution of the method.

max_locals

The value of the max_locals item gives the number of local variables in the local variable array allocated upon invocation of this method (2.6.1), including the local variables used to pass parameters to the method on its invocation.

The greatest local variable index for a value of type long or double is max_locals - 2. The greatest local variable index for a value of any other type is max_locals - 1.

code_length

The value of the code_length item gives the number of bytes in the code array for this method.

The value of code_length must be greater than zero (as the code array must not be empty) and less than 65536.

code[]

The code array gives the actual bytes of Java Virtual Machine code that implement the method.

When the code array is read into memory on a byte-addressable machine, if the first byte of the array is aligned on a 4-byte boundary, the tableswitch and lookupswitch 32-bit offsets will be 4-byte aligned. (Refer to the descriptions of those instructions for more information on the consequences of code array alignment.)

The detailed constraints on the contents of the code array are extensive and are given in a separate section (4.9).

exception_table_length

The value of the exception_table_length item gives the number of entries in the exception_table table.

exception_table[]

Each entry in the exception_table array describes one exception handler in the code array. The order of the handlers in the exception_table array is significant (2.10).

Each exception_table entry contains the following four items:

start_pc, end_pc

The values of the two items start_pc and end_pc indicate the ranges in the code array at which the exception handler is active. The value of start_pc must be a valid index into the code array of the opcode of an instruction. The value of end_pc either must be a valid index into the code array of the opcode of an instruction or must be equal to code_length, the length of the code array. The value of start_pc must be less than the value of end_pc.

The start_pc is inclusive and end_pc is exclusive; that is, the exception handler must be active while the program counter is within the interval [start_pc, end_pc).

The fact that end_pc is exclusive is a historical mistake in the design of the Java Virtual Machine: if the Java Virtual Machine code for a method is exactly 65535 bytes long and ends with an instruction that is 1 byte long, then that instruction cannot be protected by an exception handler. A compiler writer can work around this bug by limiting the maximum size of the generated Java Virtual Machine code for any method, instance initialization method, or static initializer (the size of any code array) to 65534 bytes.

handler_pc

The value of the handler_pc item indicates the start of the exception handler. The value of the item must be a valid index into the code array and must be the index of the opcode of an instruction.

catch_type

If the value of the catch_type item is nonzero, it must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure (4.4.1) representing a class of exceptions that this exception handler is designated to catch. The exception handler will be called only if the thrown exception is an instance of the given class or one of its subclasses.

The CONSTANT_Utf8_info of the CONSTANT_Class_info structure, if present, must be a class or interface name, not a field descriptor.

The verifier checks that the class is Throwable or a subclass of Throwable (4.9.2).

If the value of the catch_type item is zero, this exception handler is called for all exceptions.

This is used to implement finally (3.13).

attributes_count

The value of the attributes_count item indicates the number of attributes of the Code attribute.

attributes[]

Each value of the attributes table must be an attribute_info structure (4.7).

A Code attribute can have any number of optional attributes associated with it.

The attributes defined by this specification as appearing in the attributes table of a Code attribute are listed in Table 4.7-C.

The rules concerning attributes defined to appear in the attributes table of a Code attribute are given in 4.7.

The rules concerning non-predefined attributes in the attributes table of a Code attribute are given in 4.7.1.

4.7.4 The StackMapTable Attribute

...

A verification type specifies the type of either one or two locations, where a location is either a single local variable or a single operand stack entry. A verification type is represented by a discriminated union, verification_type_info, that consists of a one-byte tag, indicating which item of the union is in use, followed by zero or more bytes, giving more information about the tag.

union verification_type_info {
    Top_variable_info;
    Integer_variable_info;
    Float_variable_info;
    Long_variable_info;
    Double_variable_info;
    Null_variable_info;
    UninitializedThis_variable_info;
    Object_variable_info;
    Uninitialized_variable_info;
}

A verification type that specifies one location in the local variable array or in the operand stack is represented by the following items of the verification_type_info union:

A verification type that specifies two locations in the local variable array or in the operand stack is represented by the following items of the verification_type_info union:

...

4.7.5 The Exceptions Attribute

The Exceptions attribute is a variable-length attribute in the attributes table of a method_info structure (4.6). The Exceptions attribute indicates which checked exceptions a method may throw.

There may be at most one Exceptions attribute in the attributes table of a method_info structure.

The Exceptions attribute has the following format:

Exceptions_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 number_of_exceptions;
    u2 exception_index_table[number_of_exceptions];
}

The items of the Exceptions_attribute structure are as follows:

attribute_name_index

The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be the CONSTANT_Utf8_info structure (4.4.7) representing the string "Exceptions".

attribute_length

The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes.

number_of_exceptions

The value of the number_of_exceptions item indicates the number of entries in the exception_index_table.

exception_index_table[]

Each value in the exception_index_table array must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure (4.4.1) representing a class that this method is declared to throw.

The CONSTANT_Utf8_info of each CONSTANT_Class_info structure must be a class or interface name, not a field descriptor.

A method should throw an exception only if at least one of the following three criteria is met:

These requirements are not enforced in the Java Virtual Machine; they are enforced only at compile time.

4.7.6 The InnerClasses Attribute

The InnerClasses attribute is a variable-length attribute in the attributes table of a ClassFile structure (4.1).

If the constant pool of a class or interface C contains at least one CONSTANT_Class_info entry (4.4.1) which represents names a class or interface that is not a member of a package, then there must be exactly one InnerClasses attribute in the attributes table of the ClassFile structure for C.

The InnerClasses attribute has the following format:

InnerClasses_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 number_of_classes;
    {   u2 inner_class_info_index;
        u2 outer_class_info_index;
        u2 inner_name_index;
        u2 inner_class_access_flags;
    } classes[number_of_classes];
}

The items of the InnerClasses_attribute structure are as follows:

attribute_name_index

The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing the string "InnerClasses".

attribute_length

The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes.

number_of_classes

The value of the number_of_classes item indicates the number of entries in the classes array.

classes[]

Every CONSTANT_Class_info entry in the constant_pool table which represents names a class or interface C that is not a package member must have exactly one corresponding entry in the classes array.

If a class or interface has members that are classes or interfaces, its constant_pool table (and hence its InnerClasses attribute) must refer to each such member (JLS §13.1), even if that member is not otherwise mentioned by the class.

In addition, the constant_pool table of every nested class and nested interface must refer to its enclosing class, so altogether, every nested class and nested interface will have InnerClasses information for each enclosing class and for each of its own nested classes and interfaces.

Each entry in the classes array contains the following four items:

inner_class_info_index

The value of the inner_class_info_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure representing C.

The CONSTANT_Utf8_info of the CONSTANT_Class_info structure must be a class or interface name, not a field descriptor.

outer_class_info_index

If C is not a member of a class or an interface - that is, if C is a top-level class or interface (JLS §7.6) or a local class (JLS §14.3) or an anonymous class (JLS §15.9.5) - then the value of the outer_class_info_index item must be zero.

Otherwise, the value of the outer_class_info_index item must be a valid index into the constant_pool table, and the entry at that index must be a CONSTANT_Class_info structure representing the class or interface of which C is a member. The value of the outer_class_info_index item must not equal the the value of the inner_class_info_index item.

The CONSTANT_Utf8_info of the CONSTANT_Class_info structure, if present, must be a class or interface name, not a field descriptor.

inner_name_index

If C is anonymous (JLS §15.9.5), the value of the inner_name_index item must be zero.

Otherwise, the value of the inner_name_index item must be a valid index into the constant_pool table, and the entry at that index must be a CONSTANT_Utf8_info structure that represents the original simple name of C, as given in the source code from which this class file was compiled.

inner_class_access_flags

The value of the inner_class_access_flags item is a mask of flags used to denote access permissions to and properties of class or interface C as declared in the source code from which this class file was compiled. It is used by a compiler to recover the original information when source code is not available. The flags are specified in Table 4.7.6-A.

Table 4.7.6-A. Nested class access and property flags

Flag Name Value Interpretation
ACC_PUBLIC 0x0001 Marked or implicitly public in source.
ACC_PRIVATE 0x0002 Marked private in source.
ACC_PROTECTED 0x0004 Marked protected in source.
ACC_STATIC 0x0008 Marked or implicitly static in source.
ACC_FINAL 0x0010 Marked or implicitly final in source.
ACC_INTERFACE 0x0200 Was an interface in source.
ACC_ABSTRACT 0x0400 Marked or implicitly abstract in source.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.
ACC_ANNOTATION 0x2000 Declared as an annotation type.
ACC_ENUM 0x4000 Declared as an enum type.

All bits of the inner_class_access_flags item not assigned in Table 4.7.6-A are reserved for future use. They should be set to zero in generated class files and should be ignored by Java Virtual Machine implementations.

If a class file has a version number that is 51.0 or above, and has an InnerClasses attribute in its attributes table, then for all entries in the classes array of the InnerClasses attribute, the value of the outer_class_info_index item must be zero if the value of the inner_name_index item is zero.

Oracle's Java Virtual Machine implementation does not check the consistency of an InnerClasses attribute against a class file representing a class or interface referenced by the attribute.

4.7.7 The EnclosingMethod Attribute

The EnclosingMethod attribute is a fixed-length attribute in the attributes table of a ClassFile structure (4.1). A class must have an EnclosingMethod attribute if and only if it represents a local class or an anonymous class (JLS §14.3, JLS §15.9.5).

There may be at most one EnclosingMethod attribute in the attributes table of a ClassFile structure.

The EnclosingMethod attribute has the following format:

EnclosingMethod_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 class_index;
    u2 method_index;
}

The items of the EnclosingMethod_attribute structure are as follows:

attribute_name_index

The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing the string "EnclosingMethod".

attribute_length

The value of the attribute_length item must be four.

class_index

The value of the class_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure (4.4.1) representing the innermost class or interface that encloses the declaration of the current class.

The CONSTANT_Utf8_info of the CONSTANT_Class_info structure must be a class or interface name, not a field descriptor.

method_index

If the current class is not immediately enclosed by a method or constructor, then the value of the method_index item must be zero.

In particular, method_index must be zero if the current class was immediately enclosed in source code by an instance initializer, static initializer, instance variable initializer, or class variable initializer. (The first two concern both local classes and anonymous classes, while the last two concern anonymous classes declared on the right hand side of a field assignment.)

Otherwise, the value of the method_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_NameAndType_info structure (4.4.6) representing the name and type of a method in the class or interface referenced by the class_index attribute above.

It is the responsibility of a Java compiler to ensure that the method identified via the method_index is indeed the closest lexically enclosing method of the class that contains this EnclosingMethod attribute.

4.7.16 The RuntimeVisibleAnnotations Attribute

4.7.16.1 The element_value structure

The element_value structure is a discriminated union representing the value of an element-value pair. It has the following format:

element_value {
    u1 tag;
    union {
        u2 const_value_index;

        {   u2 type_name_index;
            u2 const_name_index;
        } enum_const_value;

        u2 class_info_index;

        annotation annotation_value;

        {   u2            num_values;
            element_value values[num_values];
        } array_value;
    } value;
}

The tag item uses a single ASCII character to indicate the type of the value of the element-value pair. This determines which item of the value union is in use. [Table 4.7.16.1-A] shows the valid characters for the tag item, the type indicated by each character, and the item used in the value union for each character. The table's fourth column is used in the description below of one item of the value union.

Table 4.7.16.1-A. Interpretation of tag values as types

tag Item Type value Item Constant Type
B byte const_value_index CONSTANT_Integer
C char const_value_index CONSTANT_Integer
D double const_value_index CONSTANT_Double
F float const_value_index CONSTANT_Float
I int const_value_index CONSTANT_Integer
J long const_value_index CONSTANT_Long
S short const_value_index CONSTANT_Integer
Z boolean const_value_index CONSTANT_Integer
s String const_value_index CONSTANT_Utf8
e Enum type enum_const_value Not applicable
c Class class_info_index Not applicable
@ Annotation type annotation_value Not applicable
[ Array type array_value Not applicable

The value item represents the value of an element-value pair. The item is a union, whose own items are as follows:

const_value_index

The const_value_index item denotes either a primitive constant value or a String literal as the value of this element-value pair.

The value of the const_value_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be of a type appropriate to the tag item, as specified in the fourth column of [Table 4.7.16.1-A].

enum_const_value

The enum_const_value item denotes an enum constant as the value of this element-value pair.

The enum_const_value item consists of the following two items:

type_name_index

The value of the type_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing a field descriptor (4.3.2). The constant_pool entry gives the internal form of the binary name of the type of the enum constant represented by this element_value structure (4.2.1).

const_name_index

The value of the const_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7). The constant_pool entry gives the simple name of the enum constant represented by this element_value structure.

class_info_index

The class_info_index item denotes a class literal as the value of this element-value pair.

The class_info_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing a return descriptor (4.3.3). The return descriptor gives the type corresponding to the class literal represented by this element_value structure. Types correspond to class literals as follows:

For example, the class literal Object.class corresponds to the type Object, so the constant_pool entry is Ljava/lang/Object;, whereas the class literal int.class corresponds to the type int, so the constant_pool entry is I.

The class literal void.class corresponds to void, so the constant_pool entry is V, whereas the class literal Void.class corresponds to the type Void, so the constant_pool entry is Ljava/lang/Void;.

annotation_value

The annotation_value item denotes a "nested" annotation as the value of this element-value pair.

The value of the annotation_value item is an annotation structure ([4.7.16]) that gives the annotation represented by this element_value structure.

array_value

The array_value item denotes an array as the value of this element-value pair.

The array_value item consists of the following two items:

num_values

The value of the num_values item gives the number of elements in the array represented by this element_value structure.

values[]

Each value in the values table gives the corresponding element of the array represented by this element_value structure.

4.7.25 The Module Attribute

The Module attribute is a variable-length attribute in the attributes table of a ClassFile structure (4.1). The Module attribute indicates the modules required by a module; the packages exported and opened by a module; and the services used and provided by a module.

There may be at most one Module attribute in the attributes table of a ClassFile structure.

The Module attribute has the following format:

Module_attribute {
    u2 attribute_name_index;
    u4 attribute_length;

    u2 module_name_index;
    u2 module_flags;
    u2 module_version_index;

    u2 requires_count;
    {   u2 requires_index;
        u2 requires_flags;
        u2 requires_version_index;
    } requires[requires_count];

    u2 exports_count;
    {   u2 exports_index;
        u2 exports_flags;
        u2 exports_to_count;
        u2 exports_to_index[exports_to_count];
    } exports[exports_count];

    u2 opens_count;
    {   u2 opens_index;
        u2 opens_flags;
        u2 opens_to_count;
        u2 opens_to_index[opens_to_count];
    } opens[opens_count];

    u2 uses_count;
    u2 uses_index[uses_count];

    u2 provides_count;
    {   u2 provides_index;
        u2 provides_with_count;
        u2 provides_with_index[provides_with_count];
    } provides[provides_count];
}

The items of the Module_attribute structure are as follows:

attribute_name_index

The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing the string "Module".

attribute_length

The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes.

module_name_index

The value of the module_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Module_info structure (4.4.11) denoting the current module.

module_flags

The value of the module_flags item is as follows:

0x0020 (ACC_OPEN)

Indicates that this module is open.

0x1000 (ACC_SYNTHETIC)

Indicates that this module was not explicitly or implicitly declared.

0x8000 (ACC_MANDATED)

Indicates that this module was implicitly declared.

module_version_index

The value of the module_version_index item must be either zero or a valid index into the constant_pool table. If the value of the item is zero, then no version information about the current module is present. If the value of the item is nonzero, then the constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the version of the current module.

requires_count

The value of the requires_count item indicates the number of entries in the requires table.

If the current module is java.base, then requires_count must be zero.

If the current module is not java.base, then requires_count must be at least one.

requires[]

Each entry in the requires table specifies a dependence of the current module. The items in each entry are as follows:

requires_index

The value of the requires_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Module_info structure denoting a module on which the current module depends.

At most one entry in the requires table may specify a module of a given name with its requires_index item.

requires_flags

The value of the requires_flags item is as follows:

0x0020 (ACC_TRANSITIVE)

Indicates that any module which depends on the current module, implicitly declares a dependence on the module indicated by this entry.

0x0040 (ACC_STATIC_PHASE)

Indicates that this dependence is mandatory in the static phase, i.e., at compile time, but is optional in the dynamic phase, i.e., at run time.

0x1000 (ACC_SYNTHETIC)

Indicates that this dependence was not explicitly or implicitly declared in the source of the module declaration.

0x8000 (ACC_MANDATED)

Indicates that this dependence was implicitly declared in the source of the module declaration.

If the current module is not java.base, and the class file version number is 54.0 or above, then neither ACC_TRANSITIVE nor ACC_STATIC_PHASE may be set in requires_flags.

requires_version_index

The value of the requires_version_index item must be either zero or a valid index into the constant_pool table. If the value of the item is zero, then no version information about the dependence is present. If the value of the item is nonzero, then the constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the version of the module specified by requires_index.

Unless the current module is java.base, exactly one entry in the requires table must have both a requires_index item which indicates java.base and a requires_flags item which has the ACC_SYNTHETIC flag not set.

exports_count

The value of the exports_count item indicates the number of entries in the exports table.

exports[]

Each entry in the exports table specifies a package exported by the current module, such that public and protected types in the package, and their public and protected members, may be accessed from outside the current module, possibly from a limited set of "friend" modules.

The items in each entry are as follows:

exports_index

The value of the exports_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Package_info structure (4.4.12) representing a package exported by the current module.

At most one entry in the exports table may specify a package of a given name with its exports_index item.

exports_flags

The value of the exports_flags item is as follows:

0x1000 (ACC_SYNTHETIC)

Indicates that this export was not explicitly or implicitly declared in the source of the module declaration.

0x8000 (ACC_MANDATED)

Indicates that this export was implicitly declared in the source of the module declaration.

exports_to_count

The value of the exports_to_count indicates the number of entries in the exports_to_index table.

If exports_to_count is zero, then this package is exported by the current module in an unqualified fashion; code in any other module may access the types and members in the package.

If exports_to_count is nonzero, then this package is exported by the current module in a qualified fashion; only code in the modules listed in the exports_to_index table may access the types and members in the package.

exports_to_index[]

The value of each entry in the exports_to_index table must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Module_info structure denoting a module whose code can access the types and members in this exported package.

For each entry in the exports table, at most one entry in its exports_to_index table may specify a module of a given name.

opens_count

The value of the opens_count item indicates the number of entries in the opens table.

opens_count must be zero if the current module is open.

opens[]

Each entry in the opens table specifies a package opened by the current module, such that all types in the package, and all their members, may be accessed from outside the current module via the reflection libraries of the Java SE Platform, possibly from a limited set of "friend" modules.

The items in each entry are as follows:

opens_index

The value of the opens_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Package_info structure representing a package opened by the current module.

At most one entry in the opens table may specify a package of a given name with its opens_index item.

opens_flags

The value of the opens_flags item is as follows:

0x1000 (ACC_SYNTHETIC)

Indicates that this opening was not explicitly or implicitly declared in the source of the module declaration.

0x8000 (ACC_MANDATED)

Indicates that this opening was implicitly declared in the source of the module declaration.

opens_to_count

The value of the opens_to_count indicates the number of entries in the opens_to_index table.

If opens_to_count is zero, then this package is opened by the current module in an unqualified fashion; code in any other module may reflectively access the types and members in the package.

If opens_to_count is nonzero, then this package is opened by the current module in a qualified fashion; only code in the modules listed in the exports_to_index table may reflectively access the types and members in the package.

opens_to_index[]

The value of each entry in the opens_to_index table must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Module_info structure denoting a module whose code can access the types and members in this opened package.

For each entry in the opens table, at most one entry in its opens_to_index table may specify a module of a given name.

uses_count

The value of the uses_count item indicates the number of entries in the uses_index table.

uses_index[]

The value of each entry in the uses_index table must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure (4.4.1) representing a service interface which the current module may discover via java.util.ServiceLoader.

The CONSTANT_Utf8_info of each CONSTANT_Class_info structure must be a class or interface name, not a field descriptor.

At most one entry in the uses_index table may specify a service interface of a given name.

provides_count

The value of the provides_count item indicates the number of entries in the provides table.

provides[]

Each entry in the provides table represents a service implementation for a given service interface.

The items in each entry are as follows:

provides_index

The value of the provides_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure representing a service interface for which the current module provides a service implementation.

The CONSTANT_Utf8_info of the CONSTANT_Class_info structure must be a class or interface name, not a field descriptor.

At most one entry in the provides table may specify a service interface of a given name with its provides_index item.

provides_with_count

The value of the provides_with_count indicates the number of entries in the provides_with_index table.

provides_with_count must be nonzero.

provides_with_index[]

The value of each entry in the provides_with_index table must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure representing a service implementation for the service interface specified by provides_index.

The CONSTANT_Utf8_info of each CONSTANT_Class_info structure must be a class or interface name, not a field descriptor.

For each entry in the provides table, at most one entry in its provides_with_index table may specify a service implementation of a given name.

4.7.27 The ModuleMainClass Attribute

The ModuleMainClass attribute is a fixed-length attribute in the attributes table of a ClassFile structure (4.1. The ModuleMainClass attribute indicates the main class of a module.

There may be at most one ModuleMainClass attribute in the attributes table of a ClassFile structure.

The ModuleMainClass attribute has the following format:

ModuleMainClass_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 main_class_index;
}

The items of the ModuleMainClass_attribute structure are as follows:

attribute_name_index

The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing the string "ModuleMainClass".

attribute_length

The value of the attribute_length item must be two.

main_class_index

The value of the main_class_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure (4.4.1) representing the main class of the current module.

The CONSTANT_Utf8_info of the CONSTANT_Class_info structure must be a class or interface name, not a field descriptor.

4.7.28 The NestHost Attribute

The NestHost attribute is a fixed-length attribute in the attributes table of a ClassFile structure. The NestHost attribute records the nest host of the nest to which the current class or interface claims to belong (5.4.4).

There may be at most one NestHost attribute in the attributes table of a ClassFile structure.

The NestHost attribute has the following format:

NestHost_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 host_class_index;
}

The items of the NestHost_attribute structure are as follows:

attribute_name_index

The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing the string "NestHost".

attribute_length

The value of the attribute_length item must be two.

host_class_index

The value of the host_class_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure (4.4.1) representing a class or interface which is the nest host for the current class or interface.

The CONSTANT_Utf8_info of the CONSTANT_Class_info structure must be a class or interface name, not a field descriptor.

If the nest host cannot be loaded, or is not in the same run-time package as the current class or interface, or does not authorize nest membership for the current class or interface, then an error may occur during access control (5.4.4).

4.7.29 The NestMembers Attribute

The NestMembers attribute is a variable-length attribute in the attributes table of a ClassFile structure (4.1). The NestMembers attribute records the classes and interfaces that are authorized to claim membership in the nest hosted by the current class or interface (5.4.4).

There may be at most one NestMembers attribute in the attributes table of a ClassFile structure.

The attributes table of a ClassFile structure must not contain both a NestMembers attribute and a NestHost attribute.

This rule prevents a nest host from claiming membership in a different nest. It is implicitly a member of the nest that it hosts.

The NestMembers attribute has the following format:

NestMembers_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 number_of_classes;
    u2 classes[number_of_classes];
}

The items of the NestMembers_attribute structure are as follows:

attribute_name_index

The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing the string "NestMembers".

attribute_length

The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes.

number_of_classes

The value of the number_of_classes item indicates the number of entries in the classes array.

classes[]

Each value in the classes array must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure (4.4.1) representing a class or interface which is a member of the nest hosted by the current class or interface.

The CONSTANT_Utf8_info of each CONSTANT_Class_info structure must be a class or interface name, not a field descriptor.

The classes array is consulted by access control (5.4.4). It should consist of references to other classes and interfaces that are in the same run-time package and have NestHost attributes which reference the current class or interface. Array items that do not meet these criteria are ignored by access control.

4.9 Constraints on Java Virtual Machine Code

4.9.1 Static Constraints

The static constraints on a class file are those defining the well-formedness of the file. These constraints have been given in the previous sections, except for static constraints on the code in the class file. The static constraints on the code in a class file specify how Java Virtual Machine instructions must be laid out in the code array and what the operands of individual instructions must be.

The static constraints on the instructions in the code array are as follows:

The static constraints on the operands of instructions in the code array are as follows:

4.9.2 Structural Constraints

The structural constraints on the code array specify constraints on relationships between Java Virtual Machine instructions. The structural constraints are as follows:

4.10 Verification of class Files

4.10.1 Verification by Type Checking

4.10.1.2 Verification Type System

The type checker enforces a type system based upon a hierarchy of verification types, illustrated below.

``` Verification type hierarchy:

                         top
             ____________/\____________
            /                          \
           /                            \
        oneWord                       twoWord
       /   |   \                     /       \
      /    |    \                   /         \
    int  float  reference        long        double
                 /     \
                /       \_____________
               /                      \
              /                        \
           uninitialized                    +------------------+
            /         \                     |  reference type  |
           /           \                    |  hierarchy       |
uninitializedThis  uninitialized(Offset)    +------------------+  
           uninitialized                    +-------------------+
            /         \                     |  reference types  |
           /           \                    |  and null         |
uninitializedThis  uninitialized(Offset)    +-------------------+  

The type null is no longer a subtype of all reference types, and identifying exactly which reference types it is related to is beyond the scope of this diagram.

Most verification types have a direct correspondence with the primitive and reference types described in 2.2 and represented by field descriptors in Table 4.3-A:

The remaining verification types are described as follows:

The subtyping rules for verification types are as follows.

Subtyping is reflexive.

isAssignable(X, X).

The type top is a supertype of all other types.

isAssignable(oneWord, top).
isAssignable(twoWord, top).

A type is a subtype of some other type, X, if its direct supertype is a subtype of X.

isAssignable(int, X)    :- isAssignable(oneWord, X).
isAssignable(float, X)  :- isAssignable(oneWord, X).
isAssignable(long, X)   :- isAssignable(twoWord, X).
isAssignable(double, X) :- isAssignable(twoWord, X).

isAssignable(reference, X)   :- isAssignable(oneWord, X).
isAssignable(class(_, _), X) :- isAssignable(reference, X).
isAssignable(nullfree(_,_), X) :- isAssignable(reference, X).
isAssignable(arrayOf(_), X)  :- isAssignable(reference, X).
isAssignable(null, X) :- isAssignable(reference, X).

isAssignable(uninitialized, X)     :- isAssignable(reference, X).
isAssignable(uninitializedThis, X) :- isAssignable(uninitialized, X).
isAssignable(uninitialized(_), X)  :- isAssignable(uninitialized, X).

The type null is a subtype of all nullable reference types.

isAssignable(null, class(_, _)).
isAssignable(null, arrayOf(_)).

These subtype rules are not necessarily the most obvious formulation of subtyping. There is a clear split between subtyping rules among reference types, and rules for the remaining verification types. The split allows us to state general subtyping relations between reference types and other verification types. These relations hold independently of a reference type's position in the type hierarchy, and help to prevent excessive class loading by a Java Virtual Machine implementation. For example, we do not want to start climbing the superclass hierarchy in response to a query of the form class(foo, L) <: twoWord.

We also have a rule that says subtyping is reflexive, so together these rules cover most verification types that are not reference types.

Subtype rules for the reference types are specified recursively with isWideningReference.

isAssignable(From, To) :- isWideningReference(From, To).

The verifier allows any reference type to be widened to an interface type.

isWideningReference(class(_, _), class(To, L)) :-
    loadedClass(To, L, ToClass),
    classIsInterface(ToClass).

isWideningReference(arrayOf(_), class(To, L)) :-
    loadedClass(To, L, ToClass),
    classIsInterface(ToClass).
isWideningReference(nullfree(_,_), class(To, L)) :-
    loadedClass(To, L, ToClass),
    classIsInterface(ToClass).

This approach is less strict than the Java Programming Language, which will not allow an assignment to an interface unless the value is statically known to implement or extend the interface. The Java Virtual Machine instead uses a run-time check to ensure that invocations of interface methods actually operate on objects that implement the interface (6.5.invokeinterface). But there is no requirement that a reference stored by a local variable of an interface type refers to an object that actually implements that interface.

A nullable class type can be widened to another nullable class type if that type refers to the loaded class or one of its superclasses.

isWideningReference(class(ClassName, L1), class(ClassName, L2)) :-
    L1 \= L2,
    loadedClass(ClassName, L1, Class),
    loadedClass(ClassName, L2, Class).

isWideningReference(class(From, L1), class(To, L2)) :-
    From \= To,
    loadedClass(From, L1, FromClass),
    loadedClass(To, L2, ToClass),
    loadedSuperclases(FromClass, Supers),
    member(ToClass, Supers).

A null-free inline class type is a subtype of the nullable type for that class and its supertypes.

isWideningReference(nullfree(N, L), class(N, L)).

isWideningReference(nullfree(From, L1), class(To, L2)) :-
    isWideningReference(class(From, L1), class(To, L2)).

Array types are subtypes of Object.

isWideningReference(arrayOf(_), class('java/lang/Object', L)) :-
    loadedClass('java/lang/Object', L, ObjectClass),
    classDefiningLoader(ObjectClass, BL),
    isBootstrapLoader(BL).

Subtyping between arrays of reference type is covariant.

isWideningReference(arrayOf(X), arrayOf(Y)) :-
    isWideningReference(X, Y).
4.10.1.3 Instruction Representation

Individual bytecode instructions are represented in Prolog as terms whose functor is the name of the instruction and whose arguments are its parsed operands.

For example, an aload instruction is represented as the term aload(N), which includes the index N that is the operand of the instruction.

The instructions as a whole are represented as a list of terms of the form:

instruction(Offset, AnInstruction)

For example, instruction(21, aload(1)).

The order of instructions in this list must be the same as in the class file.

Some instructions have operands that refer to entries in the constant_pool table. If the constant_pool index of an operand is invalid, or if the constant pool entry at that index does not have a supported form, as described below, the code attribute cannot be parsed, and verification will fail.

Each checkcast, instanceof, anewarray, and multianewarray, and defaultvalue instruction must have an operand that refers to a CONSTANT_Class_info constant pool entry (4.4.1). This entry is represented with a functor application, where the functor is the instruction name, and the operand is a class, nullfree, or arrayOf verification type (4.10.1.2) representing the referenced class, interface, or array reference type.

A CONSTANT_Class_info structure that references a class or interface name is interpreted in this context as the nullable type of the referenced class or interface.

For example, a checkcast instruction whose operand refers to a constant pool entry representing the class String would be represented as checkcast(class('java/lang/String', L)), where L is the class loader of the class containing the instruction.

Each new instruction must have an operand that refers to a CONSTANT_Class_info constant pool entry. This entry is represented with a functor application of the form new(ClassName), where ClassName is the name of the referenced class. (The CONSTANT_Class_info must not reference an array type a field descriptor.)

For example, a new instruction whose operand refers to a constant pool entry representing the class Object would be represented as new('java/lang/Object').

Each getfield, putfield, withfield, getstatic, and putstatic instruction must have an operand that refers to a CONSTANT_Fieldref_info constant pool entry (4.4.2). This entry is represented with a functor application of the form field(FieldClassName, FieldName, FieldDescriptor). FieldClassName is the name of the class referenced by the class_index item in the structure. FieldName and FieldDescriptor correspond to the name and field descriptor referenced by the name_and_type_index item of the structure.

For example, a getfield instruction whose operand refers to a constant pool entry representing a field foo of type float in class Bar would be represented as getfield(field('Bar', 'foo', 'F')).

Each invokevirtual, invokeinterface, invokespecial, and invokestatic instruction must have an operand that refers to a constant pool entry that references a method. This entry is represented with a functor application, as follows:

For example, an invokevirtual instruction whose operand refers to a constant pool entry representing the hashCode method in class Object would be represented as invokevirtual(method('java/lang/Object', 'hashCode', '()I')).

Each invokedynamic instruction must have an operand that refers to a CONSTANT_InvokeDynamic_info constant pool entry (4.4.10). This entry is represented with a functor application of the form dmethod(CallSiteName, MethodDescriptor).

CallSiteName and MethodDescriptor correspond to the name and method descriptor referenced by the name_and_type_index item of the structure. (The bootstrap_method_attr_index item is irrelevant to verification.)

Each ldc, ldc_w, and ldc2_w instruction must have an operand that refers to a loadable entry in the constant_pool table. There are nine kinds of loadable entry (see Table 4.4-C), represented by functor applications of the following forms:

To interpret method invocation instructions, the following predicates identify references to methods that are instance, class, or interface initialization methods.

isInitReference(MethodRef) :-
    MethodRef = method(_, '<init>', MethodDescriptor),
    parseMethodDescriptor(MethodDescriptor, _, void).

isInitReference(MethodRef) :-
    MethodRef = imethod(_, '<init>', MethodDescriptor),
    parseMethodDescriptor(MethodDescriptor, _, void).

isClinitReference(MethodRef) :-
    MethodRef = method(_, '<clinit>', MethodDescriptor),
    parseMethodDescriptor(MethodDescriptor, [], void).

isClinitReference(MethodRef) :-
    MethodRef = imethod(_, '<clinit>', MethodDescriptor),
    parseMethodDescriptor(MethodDescriptor, [], void).
4.10.1.6 Type Checking Methods with Code

Non-abstract, non-native methods are type correct if they have code and the code is type correct.

methodIsTypeSafe(Class, Method) :-
    doesNotOverrideFinalMethod(Class, Method),
    methodAccessFlags(Method, AccessFlags),
    methodAttributes(Method, Attributes),
    notMember(native, AccessFlags),
    notMember(abstract, AccessFlags),
    member(attribute('Code', _), Attributes),
    methodWithCodeIsTypeSafe(Class, Method).

A method with code is type safe if it is possible to merge the code and the stack map frames into a single stream such that each stack map frame precedes the instruction it corresponds to, and the merged stream is type correct. The method's exception handlers, if any, must also be legal.

methodWithCodeIsTypeSafe(Class, Method) :-
    parseCodeAttribute(Class, Method, FrameSize, MaxStack,
                       ParsedCode, Handlers, StackMap),
    mergeStackMapAndCode(StackMap, ParsedCode, MergedCode),
    methodInitialStackFrame(Class, Method, FrameSize, StackFrame, ReturnType),
    Environment = environment(Class, Method, ReturnType, MergedCode,
                              MaxStack, Handlers),
    handlersAreLegal(Environment),
    mergedCodeIsTypeSafe(Environment, MergedCode, StackFrame).

Let us consider exception handlers first.

An exception handler is represented by a functor application of the form:

handler(Start, End, Target, ClassName)

whose arguments are, respectively, the start and end of the range of instructions covered by the handler, the first instruction of the handler code, and the name of the exception class that this handler is designed to handle.

An exception handler is legal if its start (Start) is less than its end (End), there exists an instruction whose offset is equal to Start, there exists an instruction whose offset equals End, and the handler's exception class is assignable to the class Throwable. The exception class of a handler is Throwable if the handler's class entry is 0, otherwise it is the class named in the handler.

An additional requirement exists for a handler inside an instance initialization method if one of the instructions covered by the handler is invokespecial of an instance initialization method. In this case, the fact that a handler is running means the object under construction is likely broken, so it is important that the handler does not swallow the exception and allow the enclosing instance initialization method to return normally to the caller. Accordingly, the handler is required to either complete abruptly by throwing an exception to the caller of the enclosing instance initialization method, or to loop forever.

handlersAreLegal(Environment) :-
    exceptionHandlers(Environment, Handlers),
    checklist(handlerIsLegal(Environment), Handlers).

handlerIsLegal(Environment, Handler) :-
    Handler = handler(Start, End, Target, _),
    Start < End,
    allInstructions(Environment, Instructions),
    member(instruction(Start, _), Instructions),
    offsetStackFrame(Environment, Target, _),
    instructionsIncludeEnd(Instructions, End),
    currentClassLoader(Environment, CurrentLoader),
    handlerExceptionClass(Handler, ExceptionClass, CurrentLoader),
    isBootstrapLoader(BL),
    isAssignable(ExceptionClass, class('java/lang/Throwable', BL)),
    initHandlerIsLegal(Environment, Handler).

instructionsIncludeEnd(Instructions, End) :-
    member(instruction(End, _), Instructions).
instructionsIncludeEnd(Instructions, End) :-
    member(endOfCode(End), Instructions).

handlerExceptionClass(handler(_, _, _, 0),
                      class('java/lang/Throwable', BL), _) :-
    isBootstrapLoader(BL).

handlerExceptionClass(handler(_, _, _, Name),
                      class(Name, L), L) :-
    Name \= 0.
initHandlerIsLegal(Environment, Handler) :-
    notInitHandler(Environment, Handler).

notInitHandler(Environment, Handler) :-
    Environment = environment(_Class, Method, _, Instructions, _, _),
    isNotInit(Method).

notInitHandler(Environment, Handler) :-
    Environment = environment(_Class, Method, _, Instructions, _, _),
    isInit(Method),
    member(instruction(_, invokespecial(CP)), Instructions),
    \+ isInitReference(CP).

initHandlerIsLegal(Environment, Handler) :-
    isInitHandler(Environment, Handler),
    sublist(isApplicableInstruction(Target), Instructions,
            HandlerInstructions),
    noAttemptToReturnNormally(HandlerInstructions).

isInitHandler(Environment, Handler) :-
    Environment = environment(_Class, Method, _, Instructions, _, _),
    isInit(Method).
    member(instruction(_, invokespecial(CP)), Instructions),
    isInitReference(CP).

isApplicableInstruction(HandlerStart, instruction(Offset, _)) :-
    Offset >= HandlerStart.

noAttemptToReturnNormally(Instructions) :-
    notMember(instruction(_, return), Instructions).

noAttemptToReturnNormally(Instructions) :-
    member(instruction(_, athrow), Instructions).

Let us now turn to the stream of instructions and stack map frames.

Merging instructions and stack map frames into a single stream involves four cases:

To determine if the merged stream for a method is type correct, we first infer the method's initial type state.

The initial type state of a method consists of an empty operand stack and local variable types derived from the type of this and the arguments, as well as the appropriate flag, depending on whether this is an instance initialization method.

methodInitialStackFrame(Class, Method, FrameSize, frame(Locals, [], Flags),
                        ReturnType):-
    methodDescriptor(Method, Descriptor),
    parseMethodDescriptor(Descriptor, RawArgs, ReturnType),
    expandTypeList(RawArgs, Args),
    methodInitialThisType(Class, Method, ThisList),
    flags(ThisList, Flags),
    append(ThisList, Args, ThisArgs),
    expandToLength(ThisArgs, FrameSize, top, Locals).

Given a list of types, the following clause produces a list where every type of size 2 has been substituted by two entries: one for itself, and one top entry. The result then corresponds to the representation of the list as 32-bit words in the Java Virtual Machine.

expandTypeList([], []).
expandTypeList([Item | List], [Item | Result]) :-
    sizeOf(Item, 1),
    expandTypeList(List, Result).
expandTypeList([Item | List], [Item, top | Result]) :-
    sizeOf(Item, 2),
    expandTypeList(List, Result).
flags([uninitializedThis], [flagThisUninit]).
flags(X, []) :- X \= [uninitializedThis].

expandToLength(List, Size, _Filler, List) :-
    length(List, Size).
expandToLength(List, Size, Filler, Result) :-
    length(List, ListLength),
    ListLength < Size,
    Delta is Size - ListLength,
    length(Extra, Delta),
    checklist(=(Filler), Extra),
    append(List, Extra, Result).

For the initial type state of an instance method, we compute the type of this and put it in a list. The type of this in the instance initialization method of Object is Object; in other instance initialization methods, the type of this is uninitializedThis; **the type of this in an instance method of an inline class is nullfree(N, L), where N is the name of the class containing the method and L is its defining class loader; otherwise, the type of this in an instance method is class(N, L) where N is the name of the class containing the method and L is its defining class loader.

For the initial type state of a static method, this is irrelevant, so the list is empty.

methodInitialThisType(_Class, Method, []) :-
    methodAccessFlags(Method, AccessFlags),
    member(static, AccessFlags).

methodInitialThisType(Class, Method, [This]) :-
    methodAccessFlags(Method, AccessFlags),
    notMember(static, AccessFlags),
    instanceMethodInitialThisType(Class, Method, This).

instanceMethodInitialThisType(Class, Method, class('java/lang/Object', L)) :-
    isInit(Method),
    classDefiningLoader(Class, L),
    isBootstrapLoader(L),
    classClassName(Class, 'java/lang/Object').

instanceMethodInitialThisType(Class, Method, uninitializedThis) :-
    isInit(Method),
    loadedSuperclasses(Class, Supers),
    Supers \= [].
instanceMethodInitialThisType(Class, Method, class(ClassName, L)) :-
    isNotInit(Method),
    classDefiningLoader(Class, L),
    classClassName(Class, ClassName).
instanceMethodInitialThisType(Class, Method, nullfree(ClassName, L)) :-
    classIsInline(Class),
    classDefiningLoader(Class, L),
    classClassName(Class, ClassName).

instanceMethodInitialThisType(Class, Method, class(ClassName, L)) :-
    isNotInit(Method),
    \+ classIsInline(Class),
    classDefiningLoader(Class, L),
    classClassName(Class, ClassName).

We now compute whether the merged stream for a method is type correct, using the method's initial type state:

Branching to a target is type safe if the target has an associated stack frame, Frame, and the current stack frame, StackFrame, is assignable to Frame.

targetIsTypeSafe(Environment, StackFrame, Target) :-
    offsetStackFrame(Environment, Target, Frame),
    frameIsAssignable(StackFrame, Frame).

An instruction satisfies its exception handlers if it satisfies every exception handler that is applicable to the instruction.

instructionSatisfiesHandlers(Environment, Offset, ExceptionStackFrame) :-
    exceptionHandlers(Environment, Handlers),
    sublist(isApplicableHandler(Offset), Handlers, ApplicableHandlers),
    checklist(instructionSatisfiesHandler(Environment, ExceptionStackFrame),
              ApplicableHandlers).

An exception handler is applicable to an instruction if the offset of the instruction is greater or equal to the start of the handler's range and less than the end of the handler's range.

isApplicableHandler(Offset, handler(Start, End, _Target, _ClassName)) :-
    Offset >= Start,
    Offset < End.

An instruction satisfies an exception handler if the instructions's outgoing type state is ExcStackFrame, and the handler's target (the initial instruction of the handler code) is type safe assuming an incoming type state T. The type state T is derived from ExcStackFrame by replacing the operand stack with a stack whose sole element is the handler's exception class.

instructionSatisfiesHandler(Environment, ExcStackFrame, Handler) :-
    Handler = handler(_, _, Target, _),
    currentClassLoader(Environment, CurrentLoader),
    handlerExceptionClass(Handler, ExceptionClass, CurrentLoader),
    /* The stack consists of just the exception. */
    ExcStackFrame = frame(Locals, _, Flags),
    TrueExcStackFrame = frame(Locals, [ ExceptionClass ], Flags),
    operandStackHasLegalLength(Environment, TrueExcStackFrame),
    targetIsTypeSafe(Environment, TrueExcStackFrame, Target).
4.10.1.9 Type Checking Instructions
anewarray

An anewarray instruction with operand CP is type safe iff CP refers to a constant pool entry denoting a class, an interface, or an array a reference type, and one can legally replace a type matching int on the incoming operand stack with an array with component type CP yielding the outgoing type state.

instructionIsTypeSafe(anewarray(CP), Environment, _Offset, StackFrame,
                      NextStackFrame, ExceptionStackFrame) :-
    validTypeTransition(Environment, [int], arrayOf(CP),
                        StackFrame, NextStackFrame),
    exceptionStackFrame(StackFrame, ExceptionStackFrame).
checkcast

A checkcast instruction with operand CP is type safe iff CP refers to a constant pool entry denoting a class, an interface, or an array a reference type, and one can validly replace the type Object on top of the incoming operand stack with the type denoted by CP yielding the outgoing type state.

instructionIsTypeSafe(checkcast(CP), Environment, _Offset, StackFrame,
                      NextStackFrame, ExceptionStackFrame) :-
    isBootstrapLoader(BL),
    validTypeTransition(Environment, [class('java/lang/Object', BL)], CP,
                        StackFrame, NextStackFrame),
    exceptionStackFrame(StackFrame, ExceptionStackFrame).
defaultvalue

A defaultvalue instruction with operand CP is type safe iff CP refers to a constant pool entry denoting a null-free inline class type, and and one can validly push type CP onto the incoming operand stack yielding the outgoing type state.

instructionIsTypeSafe(defaultvalue(CP), Environment, _Offset, StackFrame,
                      NextStackFrame, ExceptionStackFrame) :-
    CP = nullfree(_,_),
    validTypeTransition(Environment, [], CP, StackFrame, NextStackFrame),
    exceptionStackFrame(StackFrame, ExceptionStackFrame).
instanceof

An instanceof instruction with operand CP is type safe iff CP refers to a constant pool entry denoting a class, an interface, or an array a reference type, and one can validly replace the type Object on top of the incoming operand stack with type int yielding the outgoing type state.

instructionIsTypeSafe(instanceof(CP), Environment, _Offset, StackFrame,
                      NextStackFrame, ExceptionStackFrame) :-
    isBootstrapLoader(BL),
    validTypeTransition(Environment, [class('java/lang/Object', BL)], int,
                        StackFrame, NextStackFrame),
    exceptionStackFrame(StackFrame, ExceptionStackFrame).
withfield

A withfield instruction with operand CP is type safe iff its operand, CP, refers to a constant pool entry denoting a field whose declared type is FieldType, declared in a class FieldClassName; and one can validly replace types matching FieldType and the nullable type of FieldClassName with the null-free type of FieldClassName on the incoming operand stack, yielding the outgoing type state.

instructionIsTypeSafe(withfield(CP), Environment, _Offset, StackFrame,
                      NextStackFrame, ExceptionStackFrame) :-
    CP = field(FieldClassName, FieldName, FieldDescriptor),
    parseFieldDescriptor(FieldDescriptor, FieldType),
    currentClassLoader(Environment, CurrentLoader),
    validTypeTransition(Environment,
                        [FieldType, class(FieldClassName, CurrentLoader)],
                        nullfree(FieldClassName, CurrentLoader),
                        StackFrame, NextStackFrame),
    exceptionStackFrame(StackFrame, ExceptionStackFrame).

Chapter 5: Loading, Linking, and Initializing

5.1 The Run-Time Constant Pool

The Java Virtual Machine maintains a run-time constant pool for each class and interface (2.5.5). This data structure serves many of the purposes of the symbol table of a conventional programming language implementation. The constant_pool table in the binary representation of a class or interface (4.4) is used to construct the run-time constant pool upon class or interface creation (5.3).

There are two kinds of entry in the run-time constant pool: symbolic references, which may later be resolved (5.4.3), and static constants, which require no further processing.

The symbolic references in the run-time constant pool are derived from entries in the constant_pool table in accordance with the structure of each entry:

The static constants in the run-time constant pool are also derived from entries in the constant_pool table in accordance with the structure of each entry:

The remaining structures in the constant_pool table - the descriptive structures CONSTANT_NameAndType_info, CONSTANT_Module_info, and CONSTANT_Package_info, and the foundational structure CONSTANT_Utf8_info - are only used indirectly when constructing the run-time constant pool. No entries in the run-time constant pool correspond directly to these structures.

Some entries in the run-time constant pool are loadable, which means:

An entry in the run-time constant pool is loadable if it is derived from an entry in the constant_pool table that is loadable (see Table 4.4-C). Accordingly, the following entries in the run-time constant pool are loadable:

5.4 Linking

5.4.2 Preparation

Preparation involves creating the static fields for a class or interface and initializing such fields to their default values (2.3, 2.4). This does not require the execution of any Java Virtual Machine code; explicit initializers for static fields are executed as part of initialization (5.5), not preparation.

During preparation of a class or interface C, the Java Virtual Machine imposes constraints on field and method descriptors (4.3), as follows:

  1. For each occurrence of a NullFreeClassType in a descriptor of a field or method declared by C, the defining class loader of C is used to create the referenced class or interface.

    Any exception that can be thrown as a result of failure of class or interface creation can thus be thrown as a result of failure of preparation.

    If the result of creation is not an inline class, preparation fails with an IncompatibleClassChangeError.

  2. For each field of C with a null-free inline class type, the type is resolved, as if by resolution of an unresolved symbolic reference to a reference type (5.4.3.1), and the named inline class is prepared.

    Any exception that can be thrown as a result of failure of reference type resolution can thus be thrown as a result of failure of preparation.

    If preparation of the inline class recursively requires preparation of the class C, preparation fails with a ClassCircularityError.

    An inline class instance is not allowed to "contain" another instance of the same class in a "flattened" form, because the instance could have no finite "flattened" representation. Fields with nullable inline class types are not intended to support "flattening" in this way, and so are not subject to this constraint.

    After preparation of C, a field of C with a null-free inline class type will hold the default value instance of that inline class. This step ensures that the class has access to create the default value, and that the class of the default value has been prepared.

    Note the distinction between steps (1) and (2): step (1) applies to any null-free inline class type appearing in a field or method descriptor, while step (2) only applies to a null-free inline class type that is the type of a field. As a result, an inaccessible null-free inline class type may be used in a method descriptor, or as an array component type in a field descriptor, but may not be used as the type of a field.

    Preparation must occur for the inline class before any user code attempts to access the default value. We guarantee this by recursively preparing the referenced class. Ideally, initialization will occur as well, per 5.5, before user code accesses the field. But user code may execute during initialization before initialization has a chance to handle the field, so we can't guarantee it.

    Design discussion: the circularity check on field types should eventually be dropped for static fields, but there are outstanding tricky issues to work out.

    An alternative design could permit circularities among instance fields, and require the JVM to infer whether such circularities preclude flattening of the field.

During preparation of a class or interface C, the Java Virtual Machine also imposes loading constraints (5.3.4):

  1. Let L1 be the defining loader of C. For each instance method m declared in C that can override (5.4.5) an instance method declared in a superclass or superinterface <D, L2>, for each class or interface name N mentioned by the descriptor of m (4.3.3), the Java Virtual Machine imposes the loading constraint NL1 = NL2.

  2. For each instance method m declared in a superinterface <I, L3> of C, if C does not itself declare an instance method that can override m, then a method is selected (5.4.6) with respect to C and the method m in <I, L3>. Let <D, L2> be the class or interface that declares the selected method. For each class or interface name N mentioned by the descriptor of m, the Java Virtual Machine imposes the loading constraint NL2 = NL3.

Preparation may occur at any time following creation but must be completed prior to initialization.

5.4.3 Resolution

Many Java Virtual Machine instructions - anewarray, checkcast, defaultvalue, getfield, getstatic, instanceof, invokedynamic, invokeinterface, invokespecial, invokestatic, invokevirtual, ldc, ldc_w, ldc2_w, multianewarray, new, putfield, and putstatic, and withfield - rely on symbolic references in the run-time constant pool. Execution of any of these instructions requires resolution of the symbolic reference.

Resolution is the process of dynamically determining one or more concrete values from a symbolic reference in the run-time constant pool. Initially, all symbolic references in the run-time constant pool are unresolved.

Resolution of an unresolved symbolic reference to (i) a class, interface, or array reference type (ii) a field, (iii) a method, (iv) a method type, (v) a method handle, or (vi) a dynamically-computed constant, proceeds in accordance with the rules given in 5.4.3.1 through 5.4.3.5. In the first three of those sections, the class or interface in whose run-time constant pool the symbolic reference appears is labeled D. Then:

Because errors occurring on an initial attempt at resolution are thrown again on subsequent attempts, a class in one module that attempts to access, via resolution of a symbolic reference in its run-time constant pool, an unexported public type in a different module will always receive the same error indicating an inaccessible type (5.4.4), even if the Java SE Platform API is used to dynamically export the public type's package at some time after the class's first attempt.

Resolution of an unresolved symbolic reference to a dynamically-computed call site proceeds in accordance with the rules given in 5.4.3.6. Then:

Certain of the instructions above require additional linking checks when resolving symbolic references. For instance, in order for a getfield instruction to successfully resolve the symbolic reference to the field on which it operates, it must not only complete the field resolution steps given in 5.4.3.2 but also check that the field is not static. If it is a static field, a linking exception must be thrown.

Linking exceptions generated by checks that are specific to the execution of a particular Java Virtual Machine instruction are given in the description of that instruction and are not covered in this general discussion of resolution. Note that such exceptions, although described as part of the execution of Java Virtual Machine instructions rather than resolution, are still properly considered failures of resolution.

5.4.3.1 Class, Interface and Array Reference Type Resolution

To resolve an unresolved symbolic reference from D to a class or interface C denoted by N, the following steps are performed:

  1. The defining class loader of D is used to create a class or interface denoted by N. This class or interface is C. The details of the process are given in 5.3.

    Any exception that can be thrown as a result of failure of class or interface creation can thus be thrown as a result of failure of class and interface resolution.

  2. Access control is applied for the access from D to C (5.4.4).

To resolve an unresolved symbolic reference from D to an array a reference type T, the following steps are performed:

  1. If the element type of the array type is a class or interface type For any class or interface name N mentioned by the symbolic reference's descriptor (4.3.2), the named class or interface N is resolved, as if by resolution of an unresolved symbolic reference to the named a class or interface N.

  2. For any occurrence of a NullFreeClassType in the descriptor, if the resolved class is not an inline class, resolution fails with an IncompatibleClassChangeError.

  3. A representation of the array reference type denoted by the symbolic reference is created.

If resolution of a class, interface, or array reference type successfully loads a class or interface, but a subsequent step (such as access checking) fails, the class or interface is still valid and usable. Nevertheless, resolution fails, and the symbolic reference that was being resolved is invalid.

Design discussion: we tentatively allow malformed types like Qjava/lang/String; to appear in field and method references, even though we prohibit them here in types that are resolved. Since it's impossible to declare a field or method with such a type (see 5.4.2), resolution of these field and method references will fail anyway. But we could be more strict and perform the same check. In practice, this would mean an IncompatibleClassChangeError replaces a NoSuchFieldError or NoSuchMethodError. (Extra class loading would be called for, too, but if a matching field/method exists, it has already loaded the named class.)

5.4.3.5 Method Type and Method Handle Resolution

To resolve an unresolved symbolic reference to a method type, it is as if resolution occurs of unresolved symbolic references to classes and interfaces (5.4.3.1) whose names are mentioned by the method descriptor (4.3.3), in the order in which they are mentioned.

Any exception that can be thrown as a result of failure of resolution of a reference to a class or interface can thus be thrown as a result of failure of method type resolution.

For each occurrence of a NullFreeClassType in the method descriptor, if the resolved class is not an inline class, resolution fails with an IncompatibleClassChangeError.

The result of successful method type resolution is a reference to an instance of java.lang.invoke.MethodType which represents the method descriptor.

Method type resolution occurs regardless of whether the run-time constant pool actually contains symbolic references to classes and interfaces indicated in the method descriptor. Also, the resolution is deemed to occur on unresolved symbolic references, so a failure to resolve one method type will not necessarily lead to a later failure to resolve another method type with the same textual method descriptor, if suitable classes and interfaces can be loaded by the later time.

Resolution of an unresolved symbolic reference to a method handle is more complicated. Each method handle resolved by the Java Virtual Machine has an equivalent instruction sequence called its bytecode behavior, indicated by the method handle's kind. The integer values and descriptions of the nine kinds of method handle are given in Table 5.4.3.5-A.

Symbolic references by an instruction sequence to fields or methods are indicated by C.x:T, where x and T are the name and descriptor (4.3.2, 4.3.3) of the field or method, and C is the class or interface in which the field or method is to be found.

Table 5.4.3.5-A. Bytecode Behaviors for Method Handles

Kind Description Interpretation
1 REF_getField getfield C.f:T
2 REF_getStatic getstatic C.f:T
3 REF_putField putfield C.f:T
4 REF_putStatic putstatic C.f:T
5 REF_invokeVirtual invokevirtual C.m:(A*)T
6 REF_invokeStatic invokestatic C.m:(A*)T
7 REF_invokeSpecial invokespecial C.m:(A*)T
8 REF_newInvokeSpecial new C; dup; invokespecial C.<init>:(A*)V
9 REF_invokeInterface invokeinterface C.m:(A*)T

Let MH be the symbolic reference to a method handle (5.1) being resolved. Also:

To resolve MH, all symbolic references to classes, interfaces, fields, and methods in MH's bytecode behavior are resolved, using the following four steps:

  1. R is resolved. This occurs as if by field resolution (5.4.3.2) when MH's bytecode behavior is kind 1, 2, 3, or 4, and as if by method resolution (5.4.3.3) when MH's bytecode behavior is kind 5, 6, 7, or 8, and as if by interface method resolution (5.4.3.4) when MH's bytecode behavior is kind 9.

  2. The following constraints apply to the result of resolving R. These constraints correspond to those that would be enforced during verification or execution of the instruction sequence for the relevant bytecode behavior.

  3. A reference to an instance of java.lang.invoke.MethodType is obtained as if by resolution of an unresolved symbolic reference to a method type that contains the method descriptor specified in Table 5.4.3.5-B for the kind of MH.

    It is as if the symbolic reference to a method handle contains a symbolic reference to the method type that the resolved method handle will eventually have. The detailed structure of the method type is obtained by inspecting Table 5.4.3.5-B.

    Table 5.4.3.5-B. Method Descriptors for Method Handles

    Kind Description Method descriptor
    1 REF_getField (C)T
    2 REF_getStatic ()T
    3 REF_putField (C,T)V
    4 REF_putStatic (T)V
    5 REF_invokeVirtual (C,A*)T
    6 REF_invokeStatic (A*)T
    7 REF_invokeSpecial (C,A*)T
    8 REF_newInvokeSpecial (A*)C
    9 REF_invokeInterface (C,A*)T

In steps 1 and 3, any exception that can be thrown as a result of failure of resolution of a symbolic reference to a class, interface, field, or method, or method type can be thrown as a result of failure of method handle resolution. In step 2, any failure due to the specified constraints causes a failure of method handle resolution due to an IllegalAccessError.

The intent is that resolving a method handle can be done in exactly the same circumstances that the Java Virtual Machine would successfully verify and resolve the symbolic references in the bytecode behavior. In particular, method handles to private, protected, and static members can be created in exactly those classes for which the corresponding normal accesses are legal.

The result of successful method handle resolution is a reference to an instance of java.lang.invoke.MethodHandle which represents the method handle MH.

The type descriptor of this java.lang.invoke.MethodHandle instance is the java.lang.invoke.MethodType instance produced in the third step of method handle resolution above.

The type descriptor of a method handle is such that a valid call to invokeExact in java.lang.invoke.MethodHandle on the method handle has exactly the same stack effects as the bytecode behavior. Calling this method handle on a valid set of arguments has exactly the same effect and returns the same result (if any) as the corresponding bytecode behavior.

If the method referenced by R has the ACC_VARARGS flag set (4.6), then the java.lang.invoke.MethodHandle instance is a variable arity method handle; otherwise, it is a fixed arity method handle.

A variable arity method handle performs argument list boxing (JLS §15.12.4.2) when invoked via invoke, while its behavior with respect to invokeExact is as if the ACC_VARARGS flag were not set.

Method handle resolution throws an IncompatibleClassChangeError if the method referenced by R has the ACC_VARARGS flag set and either A* is an empty sequence or the last parameter type in A* is not an array type. That is, creation of a variable arity method handle fails.

An implementation of the Java Virtual Machine is not required to intern method types or method handles. That is, two distinct symbolic references to method types or method handles which are structurally identical might not resolve to the same instance of java.lang.invoke.MethodType or java.lang.invoke.MethodHandle respectively.

The java.lang.invoke.MethodHandles class in the Java SE Platform API allows creation of method handles with no bytecode behavior. Their behavior is defined by the method of java.lang.invoke.MethodHandles that creates them. For example, a method handle may, when invoked, first apply transformations to its argument values, then supply the transformed values to the invocation of another method handle, then apply a transformation to the value returned from that invocation, then return the transformed value as its own result.

5.5 Initialization

Initialization of a class or interface consists of executing its class or interface initialization method (2.9.2).

A class or interface C may be initialized only as a result of:

Prior to initialization, a class or interface must be linked, that is, verified, prepared, and optionally resolved.

Because the Java Virtual Machine is multithreaded, initialization of a class or interface requires careful synchronization, since some other thread may be trying to initialize the same class or interface at the same time. There is also the possibility that initialization of a class or interface may be requested recursively as part of the initialization of that class or interface. The implementation of the Java Virtual Machine is responsible for taking care of synchronization and recursive initialization by using the following procedure. It assumes that the class or interface has already been verified and prepared, and that the class or interface contains state that indicates one of four situations:

For each class or interface C, there is a unique initialization lock LC. The mapping from C to LC is left to the discretion of the Java Virtual Machine implementation. For example, LC could be the Class object for C, or the monitor associated with that Class object. The procedure for initializing C is then as follows:

  1. Synchronize on the initialization lock, LC, for C. This involves waiting until the current thread can acquire LC.

  2. If C indicates that initialization is in progress for C by some other thread, then release LC and block the current thread until informed that the in-progress initialization has completed, at which time repeat this procedure.

    Thread interrupt status is unaffected by execution of the initialization procedure.

  3. If C indicates that initialization is in progress for C by the current thread, then this must be a recursive request for initialization. Release LC and complete normally.

  4. If C indicates that it has already been initialized, then no further action is required. Release LC and complete normally.

  5. If C is in an erroneous state, then initialization is not possible. Release LC and throw a NoClassDefFoundError.

  6. Otherwise, record the fact that initialization of the Class object for C is in progress by the current thread, and release LC.

    Then, initialize each final static field of C with the constant value in its ConstantValue attribute (4.7.2), in the order the fields appear in the ClassFile structure.

  7. Next, if C is a class rather than an interface, then let SC be its superclass and let SI1, ..., SIn be all superinterfaces of C (whether direct or indirect) that declare at least one non-abstract, non-static method. The order of superinterfaces is given by a recursive enumeration over the superinterface hierarchy of each interface directly implemented by C. For each interface I directly implemented by C (in the order of the interfaces array of C), the enumeration recurs on I's superinterfaces (in the order of the interfaces array of I) before returning I.

    For each S in the list [ SC, SI1, ..., SIn ], if S has not yet been initialized, then recursively perform this entire procedure for S. If necessary, verify and prepare S first.

    If the initialization of S completes abruptly because of a thrown exception, then acquire LC, label C as erroneous, notify all waiting threads, release LC, and complete abruptly, throwing the same exception that resulted from initializing S.

  8. Next, for each field of C (in the order of the fields array of C), if the field has a null-free inline class type referencing a class F, recursively perform this entire procedure for F. If necessary, verify and prepare F first.

    Initialization of F is necessary because the initial value of the field is the default value instance of F.

    If the initialization of F completes abruptly because of a thrown exception, then acquire LC, label C as erroneous, notify all waiting threads, release LC, and complete abruptly, throwing the same exception that resulted from initializing F.

  9. Next, determine whether assertions are enabled for C by querying its defining class loader.

  10. Next, execute the class or interface initialization method of C.

  11. If the execution of the class or interface initialization method completes normally, then acquire LC, label the Class object for C as fully initialized, notify all waiting threads, release LC, and complete this procedure normally.

  12. Otherwise, the class or interface initialization method must have completed abruptly by throwing some exception E. If the class of E is not Error or one of its subclasses, then create a new instance of the class ExceptionInInitializerError with E as the argument, and use this object in place of E in the following step. If a new instance of ExceptionInInitializerError cannot be created because an OutOfMemoryError occurs, then use an OutOfMemoryError object in place of E in the following step.

  13. Acquire LC, label C as erroneous, notify all waiting threads, release LC, and complete this procedure abruptly with reason E or its replacement as determined in the previous step.

A Java Virtual Machine implementation may optimize this procedure by eliding the lock acquisition in step 1 (and release in step 4/5) when it can determine that the initialization of the class has already completed, provided that, in terms of the Java memory model, all happens-before orderings (JLS §17.4.5) that would exist if the lock were acquired, still exist when the optimization is performed.

Chapter 6: The Java Virtual Machine Instruction Set

6.5 Instructions

aastore

Operation

Store into reference array

Format

aastore

Forms

aastore = 83 (0x53)

Operand Stack

..., arrayref, index, value

...

Description

The arrayref must be of type reference and must refer to an array whose components are of type reference. The index must be of type int, and value must be of type reference. The arrayref, index, and value are popped from the operand stack.

If value is null and the component type of the array referenced by arrayref is not a null-free inline class type, then value is stored as the component of the array at index.

Otherwise, value is non-null. If value is a non-null value of the component type of the array referenced by arrayref, then value is stored as the component of the array at index.

Whether value is a value of the array component type is determined according to the rules given for checkcast.

Run-time Exceptions

If arrayref is null, aastore throws a NullPointerException.

Otherwise, if index is not within the bounds of the array referenced by arrayref, the aastore instruction throws an ArrayIndexOutOfBoundsException.

Otherwise, if value is null and the component type of the array referenced by arrayref is a null-free inline class type, aastore throws a NullPointerException.

Otherwise, if the non-null value is not a value of the array component type, aastore throws an ArrayStoreException.

anewarray

Operation

Create new array of reference

Format

anewarray
indexbyte1
indexbyte2

Forms

anewarray = 189 (0xbd)

Operand Stack

..., count

..., arrayref

Description

The count must be of type int. It is popped off the operand stack. The count represents the number of components of the array to be created. The unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The run-time constant pool entry at the index must be a symbolic reference to a class, interface, or array reference type.

The named class, interface, or array reference type is resolved (5.4.3.1). An array component type is derived from the symbolic reference: if the symbolic reference is to a class or interface, the array component type is the nullable type of the referenced class or interface; if the symbolic reference is to a reference type, the array component type is the resolved type.

If the array component type is a null-free inline class type, the resolved class named by the type is initialized if it has not already been initialized (5.5).

A new array with component type given by the resolved class, interface, or array type with the given component type, of length count, is allocated from the garbage-collected heap, and a reference arrayref to this new array object is pushed onto the operand stack. All components of the new array are initialized to null, the default value for reference types of the component type (2.4).

Linking Exceptions

During resolution of the symbolic reference to the class, interface, or array reference type, any of the exceptions documented in 5.4.3.1 can be thrown.

Run-time Exceptions

Otherwise, if execution of this anewarray instruction causes initialization of a referenced inline class, anewarray may throw an Error as detailed in 5.5.

Otherwise, if count is less than zero, the anewarray instruction throws a NegativeArraySizeException.

Notes

The anewarray instruction is used to create a single dimension of an array of object references or part of a multidimensional array.

checkcast

Operation

Check whether object is of given type

Format

checkcast
indexbyte1
indexbyte2

Forms

checkcast = 192 (0xc0)

Operand Stack

..., objectref

..., objectref

Description

The objectref must be of type reference. The unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The run-time constant pool entry at the index must be a symbolic reference to a class, interface, or array reference type.

If objectref is null and the symbolic reference does not name a null-free inline class type, then the operand stack is unchanged.

Otherwise If objectref is not null, the named class, interface, or array reference type is resolved (5.4.3.1). A checked type is derived from the symbolic reference: if the symbolic reference is to a class or interface, the checked type is the nullable type of the referenced class or interface; if the symbolic reference is to a reference type, the checked type is the resolved type. If objectref is a value of the type given by the resolved class, interface, or array type checked type, the operand stack is unchanged.

The following rules are used to determine whether a reference to an object is a value of a reference type, T.

Linking Exceptions

During resolution of the symbolic reference to the class, interface, or array reference type, any of the exceptions documented in 5.4.3.1 can be thrown.

Run-time Exception

Otherwise, if objectref is null and the symbolic reference names a null-free inline class type, the checkcast instruction throws a NullPointerException.

Otherwise, if objectref is not null and is not a value of the type given by the resolved class, interface, or array type checked type, the checkcast instruction throws a ClassCastException.

Notes

The checkcast instruction is very similar to the instanceof instruction (6.5.instanceof). It differs in its treatment of null, its behavior when its test fails (checkcast throws an exception, instanceof pushes a result code), and its effect on the operand stack.

defaultvalue

Operation

Push default value of a null-free type

Format

defaultvalue
indexbyte1
indexbyte2

Forms

defaultvalue = 203 (0xcb)

Operand Stack

...

..., objectref

Description

The unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The run-time constant pool entry at the index must be a symbolic reference to a null-free inline class type.

The referenced type is resolved (5.4.3.1). The named inline class is initialized if it has not already been initialized (5.5).

A reference to an instance of the inline class, with instance variable values set to the default initial values of their types (2.3, 2.4), is pushed onto the operand stack. Memory for the class instance may be newly allocated from the garbage-collected heap, or may have been allocated previously.

Linking Exceptions

During resolution of the symbolic reference to the null-free inline class type, any of the exceptions documented in 5.4.3.1 can be thrown.

Run-time Exception

Otherwise, if execution of this defaultvalue instruction causes initialization of the referenced class, defaultvalue may throw an Error as detailed in 5.5.

Notes

The defaultvalue instruction is similar to the new instruction. But unlike new, the class instance created by defaultvalue is completely initialized—there is no need to invoke an instance initialization method.

Default value instances of inline classes are also created implicitly when fields or array components with the null-free type of the class are initialized, via new, anewarray, multianewarray, or class preparation (5.4.2). Any class that can successfully resolve a reference to the inline class can also create a default value instance.

The withfield instruction is used to create inline class instances other than the default value instance.

Design discussion: another possible name for this instruction is aconst_default.

We could relax the restriction on the type to include other reference types—the result would always be null in those cases. Doing so doesn't seem particularly useful, but could become so when combined with a future type parameter feature. If so, since other instructions that operate on types (anewarray, checkcast, instanceof) allow class and interface names, interpreted as nullable types, we should probably allow them with defaultvalue too.

If we don't relax the restriction, then one could argue that there's no need for a null-free class type (QVal;)—just use an inline class name (Val). But this would be confusing, because "default value" is a property of a type, not a class—the default value of LVal; is null.

if_acmp<cond>

Operation

Branch if reference comparison succeeds

Format

if_acmp<cond>
branchbyte1
branchbyte2

Forms

if_acmpeq = 165 (0xa5)

if_acmpne = 166 (0xa6)

Operand Stack

..., value1, value2

...

Description

Both value1 and value2 must be of type reference. They are both popped from the operand stack and compared. The results of the comparison are as follows:

Two references are the same if one of the following cases applies:

If the comparison succeeds, the unsigned branchbyte1 and branchbyte2 are used to construct a signed 16-bit offset, where the offset is calculated to be (branchbyte1 << 8) | branchbyte2. Execution then proceeds at that offset from the address of the opcode of this if_acmp<cond> instruction. The target address must be that of an opcode of an instruction within the method that contains this if_acmp<cond> instruction.

Otherwise, if the comparison fails, execution proceeds at the address of the instruction following this if_acmp<cond> instruction.

Design discussion: this new behavior carries some performance and security risks. Two instances of a large inline class may take a surprisingly long time to compare. An attacker with the ability to create arbitrary inline class instances can use if_acmpeq to infer the contents of a private field. But it may be that the best course of action is to educate users about these risks and discourage them from making inappropriate use of inline classes.

instanceof

Operation

Determine if object is of given type

Format

instanceof
indexbyte1
indexbyte2

Forms

instanceof = 193 (0xc1)

Operand Stack

..., objectref

..., result

Description

The objectref, which must be of type reference, is popped from the operand stack. The unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The run-time constant pool entry at the index must be a symbolic reference to a class, interface, or array type.

If objectref is null, the instanceof instruction pushes an int result of 0 onto the operand stack.

Otherwise If objectref is not null, the named class, interface, or array reference type is resolved (5.4.3.1). A checked type is derived from the symbolic reference: if the symbolic reference is to a class or interface, the checked type is the nullable type of the referenced class or interface; if the symbolic reference is to a reference type, the checked type is the resolved type. If objectref is a value of the type given by the resolved class, interface, or array type checked type, the instanceof instruction pushes an int result of 1 onto the operand stack; otherwise, it pushes an int result of 0.

Whether objectref is a value of the type given by the resolved class, interface, or array type checked type is determined according to the rules given for checkcast.

Linking Exceptions

During resolution of the symbolic reference to the class, interface, or array reference type, any of the exceptions documented in 5.4.3.1 can be thrown.

Notes

The instanceof instruction is very similar to the checkcast instruction (6.5.checkcast). It differs in its treatment of null, its behavior when its test fails (checkcast throws an exception, instanceof pushes a result code), and its effect on the operand stack.

ldc

Operation

Push item from run-time constant pool

Format

ldc
index

Forms

ldc = 18 (0x12)

Operand Stack

...

..., value

Description

The index is an unsigned byte that must be a valid index into the run-time constant pool of the current class (2.5.5). The run-time constant pool entry at index must be loadable (5.1), and not any of the following:

If the run-time constant pool entry is a numeric constant of type int or float, then the value of that numeric constant is pushed onto the operand stack as an int or float, respectively.

Otherwise, if the run-time constant pool entry is a string constant, that is, a reference to an instance of class String, then value, a reference to that instance, is pushed onto the operand stack.

Otherwise, if the run-time constant pool entry is a symbolic reference to a class, interface, or array reference type, then the symbolic reference is resolved (5.4.3.1) and value, a reference to the Class object representing that class, interface, or array reference type, is pushed onto the operand stack. If the symbolic reference is to a class or interface, value represents the nullable type of the referenced class or interface.

Otherwise, the run-time constant pool entry is a symbolic reference to a method type, a method handle, or a dynamically-computed constant. The symbolic reference is resolved (5.4.3.5, 5.4.3.6) and value, the result of resolution, is pushed onto the operand stack.

Linking Exceptions

During resolution of a symbolic reference, any of the exceptions pertaining to resolution of that kind of symbolic reference can be thrown.

Notes

The ldc instruction can only be used to push a value of type float taken from the float value set ([2.3.2]) because a constant of type float in the constant pool (4.4.4) must be taken from the float value set.

ldc_w

Operation

Push item from run-time constant pool (wide index)

Format

ldc_w
indexbyte1
indexbyte2

Forms

ldc_w = 19 (0x13)

Operand Stack

...

..., value

Description

The unsigned indexbyte1 and indexbyte2 are assembled into an unsigned 16-bit index into the run-time constant pool of the current class (2.5.5), where the value of the index is calculated as (indexbyte1 << 8) | indexbyte2. The index must be a valid index into the run-time constant pool of the current class. The run-time constant pool entry at the index must be loadable (5.1), and not any of the following:

If the run-time constant pool entry is a numeric constant of type int or float, or a string constant, then value is determined and pushed onto the operand stack according to the rules given for the ldc instruction.

Otherwise, the run-time constant pool entry is a symbolic reference to a class, interface, array reference type, method type, method handle, or dynamically-computed constant. It is resolved and value is determined and pushed onto the operand stack according to the rules given for the ldc instruction.

Linking Exceptions

During resolution of a symbolic reference, any of the exceptions pertaining to resolution of that kind of symbolic reference can be thrown.

Notes

The ldc_w instruction is identical to the ldc instruction (6.5.ldc) except for its wider run-time constant pool index.

The ldc_w instruction can only be used to push a value of type float taken from the float value set ([2.3.2]) because a constant of type float in the constant pool (4.4.4) must be taken from the float value set.

monitorenter

Operation

Enter monitor for object

Format

monitorenter

Forms

monitorenter = 194 (0xc2)

Operand Stack

..., objectref

...

Description

The objectref must be of type reference.

Each object instance of an identity class, instance of class Object, and array is associated with a monitor. A monitor is locked if and only if it has an owner. The thread that executes monitorenter attempts to gain ownership of the monitor associated with objectref, as follows:

Run-time Exception

If objectref is null, monitorenter throws a NullPointerException.

Otherwise, if objectref is an inline class instance, monitorenter throws an IllegalMonitorStateException.

Design discussion: we might wish, instead, to support inline class instances by associating a monitor with each unique field-value vector. In that approach, two references have the same monitor iff they are acmpeq. There is some risk, though, that unexpected clashes would lead to subtle bugs, and as a matter of best practice we don't think it's appropriate to use inline class instances for locking, because they can't be guaranteed to be unique.

Further discussion may be warranted on the choice of exception type to throw.

Notes

A monitorenter instruction may be used with one or more monitorexit instructions (6.5.monitorexit) to implement a synchronized statement in the Java programming language (3.14). The monitorenter and monitorexit instructions are not used in the implementation of synchronized methods, although they can be used to provide equivalent locking semantics. Monitor entry on invocation of a synchronized method, and monitor exit on its return, are handled implicitly by the Java Virtual Machine's method invocation and return instructions, as if monitorenter and monitorexit were used.

The association of a monitor with an object may be managed in various ways that are beyond the scope of this specification. For instance, the monitor may be allocated and deallocated at the same time as the object. Alternatively, it may be dynamically allocated at the time when a thread attempts to gain exclusive access to the object and freed at some later time when no thread remains in the monitor for the object.

The synchronization constructs of the Java programming language require support for operations on monitors besides entry and exit. These include waiting on a monitor (Object.wait) and notifying other threads waiting on a monitor (Object.notifyAll and Object.notify). These operations are supported in the standard package java.lang supplied with the Java Virtual Machine. No explicit support for these operations appears in the instruction set of the Java Virtual Machine.

monitorexit

Operation

Exit monitor for object

Format

monitorexit

Forms

monitorexit = 195 (0xc3)

Operand Stack

..., objectref

...

Description

The objectref must be of type reference.

The thread that executes monitorexit must be the owner of the monitor associated with the instance instance of an identity class, instance of class Object, or array referenced by objectref.

The thread decrements the entry count of the monitor associated with objectref. If as a result the value of the entry count is zero, the thread exits the monitor and is no longer its owner. Other threads that are blocking to enter the monitor are allowed to attempt to do so.

Run-time Exceptions

If objectref is null, monitorexit throws a NullPointerException.

Otherwise, if objectref is an inline class instance, monitorexit throws an IllegalMonitorStateException.

Otherwise, if the thread that executes monitorexit is not the owner of the monitor associated with the instance referenced by objectref, monitorexit throws an IllegalMonitorStateException.

Otherwise, if the Java Virtual Machine implementation enforces the rules on structured locking described in 2.11.10 and if the second of those rules is violated by the execution of this monitorexit instruction, then monitorexit throws an IllegalMonitorStateException.

Notes

One or more monitorexit instructions may be used with a monitorenter instruction (6.5.monitorenter) to implement a synchronized statement in the Java programming language (3.14). The monitorenter and monitorexit instructions are not used in the implementation of synchronized methods, although they can be used to provide equivalent locking semantics.

The Java Virtual Machine supports exceptions thrown within synchronized methods and synchronized statements differently:

multianewarray

Operation

Create new multidimensional array

Format

multianewarray
indexbyte1
indexbyte2
dimensions

Forms

multianewarray = 197 (0xc5)

Operand Stack

..., count1, [count2, ...]

..., arrayref

Description

The dimensions operand is an unsigned byte that must be greater than or equal to 1. It represents the number of dimensions of the array to be created. The operand stack must contain dimensions values. Each such value represents the number of components in a dimension of the array to be created, must be of type int, and must be non-negative. The count1 is the desired length in the first dimension, count2 in the second, etc.

All of the count values are popped off the operand stack. The unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The run-time constant pool entry at the index must be a symbolic reference to an array type. The referenced array type is resolved (5.4.3.1). The resulting entry must be an array type of dimensionality greater than or equal to dimensions.

If the array type has a null-free inline class element type, and dimensions matches the number of dimensions of the array type, the inline class is initialized if it has not already been initialized (5.5).

A new multidimensional array of the array type is allocated from the garbage-collected heap. If any count value is zero, no subsequent dimensions are allocated. The components of the array in the first dimension are initialized to subarrays of the type of the second dimension, and so on. The components of the last allocated dimension of the array are initialized to the default initial value (2.3, 2.4) for the component type of that dimension. A reference arrayref to the new array is pushed onto the operand stack.

Linking Exceptions

During resolution of the symbolic reference to the array type, any of the exceptions documented in 5.4.3.1 can be thrown.

Run-time Exception

Otherwise, if execution of this multianewarray instruction causes initialization of a referenced inline class, multianewarray may throw an Error as detailed in 5.5.

Otherwise, if any of the dimensions values on the operand stack are less than zero, the multianewarray instruction throws a NegativeArraySizeException.

Notes

It may be more efficient to use newarray or anewarray (6.5.newarray, 6.5.anewarray) when creating an array of a single dimension.

The array type referenced via the run-time constant pool may have more dimensions than the dimensions operand of the multianewarray instruction. In that case, only the first dimensions of the dimensions of the array are created.

new

Operation

Create new object

Format

new
indexbyte1
indexbyte2

Forms

new = 187 (0xbb)

Operand Stack

...

..., objectref

Description

The unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The run-time constant pool entry at the index must be a symbolic reference to a class or interface. The named class or interface is resolved (5.4.3.1) and should result in a non-abstract identity class or the class Object. Memory for a new instance of that class is allocated from the garbage-collected heap, and the instance variables of the new object are initialized to the default initial values of their types (2.3, 2.4). The objectref, a reference to the instance, is pushed onto the operand stack.

On successful resolution of the class, it is initialized if it has not already been initialized (5.5).

Linking Exceptions

During resolution of the symbolic reference to the class or interface, any of the exceptions documented in 5.4.3.1 can be thrown.

Otherwise, if the symbolic reference to the class or interface type resolves to an interface, or an abstract class, or an inline class, new throws an InstantiationError.

Run-time Exception

Otherwise, if execution of this new instruction causes initialization of the referenced class, new may throw an Error as detailed in 5.5.

Notes

The new instruction does not completely create a new instance; instance creation is not completed until an instance initialization method (2.9.1) has been invoked on the uninitialized instance.

withfield

Operation

Duplicate inline class instance with new field value

Format

withfield
indexbyte1
indexbyte2

Forms

withfield = 204 (0xcc)

Operand Stack

..., objectref1, value

..., objectref2

Description

The unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The run-time constant pool entry at the index must be a symbolic reference to a field (5.1), which gives the name and descriptor of the field as well as a symbolic reference to the class in which the field is to be found. The referenced field is resolved (5.4.3.2).

The objectref1 must be an instance of an inline class, and the resolved field must be declared by that class.

The type of a value stored by a withfield instruction must be compatible with the descriptor of the referenced field (4.3.2). If the field descriptor type is boolean, byte, char, short, or int, then the value must be an int. If the field descriptor type is float, long, or double, then the value must be a float, long, or double, respectively. If the field descriptor type is a reference type, then the value must be of a type that is assignment compatible (JLS §5.2) with the field descriptor type.

The resolved field must be declared by a class that belongs to the same nest as the current class, according to the nestmate test in 5.4.4.

The value and objectref1 are popped from the operand stack.

If the value is of type int and the field descriptor type is boolean, then the int value is narrowed by taking the bitwise AND of value and 1, resulting in value'. Otherwise, the value undergoes value set conversion (2.8.3), resulting in value'.

A reference to an instance of the inline class, objectref2, is pushed onto the operand stack. The referenced field in objectref2 is set to value'. Every other instance field in objectref2 is set to the corresponding field's value in objectref1. Memory for objectref2 may be newly allocated from the garbage-collected heap, or may have been allocated previously.

Linking Exceptions

During resolution of the symbolic reference to the field, any of the exceptions pertaining to field resolution (5.4.3.2) can be thrown.

Otherwise, if the resolved field is a static field, or the resolved field is not declared by an inline class, withfield throws an IncompatibleClassChangeError.

Otherwise, if the resolved field is not declared by a class that belongs to the same nest as the current class, any of the exceptions pertaining to the nestmate test (5.4.4) may be thrown.

Run-time Exception

Otherwise, if objectref1 is null, the withfield instruction throws a NullPointerException.

Design discussion: the access restriction is intended to limit unauthorized creation of inline class instances. Without it, there would be no way to prevent unauthorized inline class instances with arbitrary public field values. For instance creation outside of the class (and its nestmates), inline classes should declare factory methods with appropriate access restrictions and input validation logic.

However, some inline classes do not care to control instance creation. These classes can declare trivial public factory methods, but we might also want to give their clients direct access to the withfield mechanism. To do so, we would need new accessibility attributes on fields or classes, independent of the "read" access described by ACC_PUBLIC, etc.