Last updated 2011-04-15 by Alex Buckley
The clarifications and amendments below are proposed to the Java Virtual Machine Specification, Second Edition. They build on the clarifications and amendments for Java SE 5.0 made by the first Maintenance Review of JSR 924. They incorporate changes proposed for Java SE 6 by the second Maintenance Review of JSR 924.
The complete amended specification is the Java Virtual Machine Specification, Java SE 7 Edition. (The next edition of the Java Language Specification will also be known as the Java SE 7 Edition.)
Download the PDF of the Java Virtual Machine Specification, Java SE 7 Edition. (Change bars are relative to the chapters for Java SE 5.0 as amended by JSR 202.)
In the Java Virtual Machine Specification, Second Edition, it was the case that Chapter 2, "Java Programming Language Concepts", incorporated significant amounts of text from the First Edition of Java Language Specification. Rather than incorporating text from a more recent edition of the Java Language Specification into Chapter 2, the authors decided that the Java Virtual Machine Specification should cross-reference the Java Language Specification where necessary, though as little as possible. The out-of-date body of Chapter 2 has been removed.
The cross-references imply no material change in the Java Virtual Machine Specification. In particular, Section 4.3, "The Internal Form of Names", and Section 5.1, "The Runtime Constant Pool", use binary names (JLS 13.1) rather than qualified names, which reflects the behavior of the JVM Reference Implementation.
Chapter 3, "The Structure of the Java Virtual Machine", is renumbered to be chapter 2. Definitions for array types and default values are added to sections 2.3 and 2.4.
Chapter 7, "Compiling for the Java Virtual Machine", is renumbered to be chapter 3. (While "Compiling for the Java Virtual Machine" is non-normative, it is an interesting topic that usefully follows the instruction set overview at the end of "The Structure of the Java Virtual Machine".)
Chapter 8, "Threads and Locks", is superceded by JSR 133. The out-of-date body of Chapter 8 has been removed, in accordance with the Maintenance Review of JSR 924 for Java SE 5.0.
Terminology for monitors in Chapter 6, "The Java Virtual Machine Instruction Set", and for structured locking in Section 2.11.10 (formerly 3.11.10), "Synchronization", has been made consistent with JSR 133 by uniformly discussing entry and exit of monitors.
Chapter 4, "The class File Format", describes verification by
typechecking. ClassFile structures with version number
number 50.0 and above are subject to verification via
typechecking. There is no failover to verification by type inferencing
for ClassFile structures with version number 51.0 and
higher.
The Prolog rule for a type-safe exception handler has been modified to
incorporate knowledge of the single Throwable item on the
stack at entry to the handler. This was an oversight in the JSR 202
specification, and brings the Java Virtual Machine Specification in
line with the JVM Reference Implementation in Java SE 6. A typo is
also corrected in the rule for invokespecial, which
caused an obviously wrong stack frame to be used.
The rule for invokespecial in type-inferencing
verification is strengthened so that the named instance initialization
method must belong to the newly instantiated class. This rule reflects
the behavior of the JVM Reference Implementation, and is already
specified in the Prolog rules for type-checking verification.
The rule for jsr in type-inferencing
verification is loosened so that a jsr which behaves as
a goto (i.e. is never returned to) is permitted to call a
subroutine recursively even if that subroutine is already present in
the subroutine call chain. This rule reflects the behavior of the JVM
Reference Implementation.
The specification of two containers of type information in
the StackMapTable attribute
(Object_variable_info and
Uninitialized_variable_info) are clarified.
A linking step that previously failed may now be repeated provided
it did not fail with a LinkageError. Failure with another
kind of Error typically reflects an internal VM problem
and not a linking failure per se, so repetition of the linking step
may well succeed and should be allowed. This rule reflects the
behavior of the JVM Reference Implementation.
The JVM throws a NoClassDefFoundError when
JVM-triggered class loading fails. (The JVM triggers class loading
during verification, constant pool resolution, and the loading of
superclasses.) Prior to Java SE 7, the underlying class loading
failure, embodied by a ClassNotFoundException from the
bootstrap loader or a user-defined loader, was lost. In Java SE 7, the
the JVM improves diagnostics by wrapping
the ClassNotFoundException in
the NoClassDefFoundError. The specification handles this
by a) stating that any class loading failure is explicitly
a ClassNotFoundException, and b) requiring any
JVM-triggered loading to wrap a ClassNotFoundException in
a NoClassDefFoundError.
The initialization procedure for a class or interface relaxes the
requirement to lock on the user-visible Class object of
the class or interface being initialized. Few JVM implementations
actually lock on this object. Most use an internal lock invisible to
user code, and this practice is now permitted by the initialization
procedure.
The initialization procedure for a class or interface is more aggressive about initializing the values of constant fields in the class or interface. Rather than happening as part of the class or interface initialization method in step 9, constant value assignment now occurs in step 6, before superclass initialization. This rule reflects the behavior of the JVM Reference Implementation.
Section 5.4.2, "Preparation", clarifies that a loader constraint is never formed from an array type, but rather from the element type of an array type. The same concern applies to loader constraint generation during resolution in sections 5.4.3.2, 5.4.3.3, and 5.4.3.4. This reflects the behavior of the JVM Reference Implementation.
Section 4.3.4, "Signatures", clarifies the role and definition of
an Identifier in generic signatures.
Section 4.7, "Attributes", specifies the ClassFile
version in which each pre-defined attribute first appeared.
Section 4.7.6, "The InnerClasses Attribute", clarifies
the meaning of a reference to a nested class, and the definition
of inner_class_info_index, and the definition
of outer_class_info_index when the attribute references a
class which is not a "member". In addition, a consistency check on the
last two items is added for a ClassFile whose version is
>=51.0.
Section 4.7.8, "The Synthetic Attribute", clarifies that
Enum.values/valueOf are not synthetic
methods, since they are not implementation artifacts.
Section 4.7.11, "The SourceDebugExtension Attribute", clarifies that
the debug_extension array is raw debugging information
rather than a JVM string.
Sections 4.7.21 and 4.7.22 document the SourceID
and CompilationID attributes that may be emitted by the
Reference Implementation of a compiler for the Java programming
language in ClassFile structures of version >=48.0.
The invokevirtual instruction is revised in accordance
with clarifications
and amendments made prior to Java SE 5.0, themselves
informed
by an
earlier change in overriding made between the First and Second
Editions of the Java Language Specification. The Java Virtual
Machine Specification, Java SE 7 Edition, has gained its own
definition of method overriding (5.4.3.5) to support the revision
of invokevirtual.
Incorrect statements about the treatment of components of boolean
arrays by the baload and bastore
instructions have been removed.
The checkcast and instanceof instructions
must not resolve the named class, array, or interface type if the
expression being cast is null. This rule reflects the
behavior of the JVM Reference Implementation. The rule is driven by
the desire to avoid a resolution failure if the named type is not
present, since a cast from null can succeed with or
without the named type.
The lookupswitch and tableswitch
instructions have been relaxed so that any byte may act as padding,
not just the zero byte.
The linking and runtime exceptions for the invokespecial
instruction have been brought into line with those
for invokevirtual and invokeinterface.
The iinc instruction is clarified with respect to
two-byte values.
A normative reference to Unicode 6.0.0 has been added, and Unicode
terminology has been clarified (2.3, 4.2, 4.3, 4.4, 5.1). Notably, the
term "character" has been replaced with "code point". Notice that both
a String object on the heap and
a CONSTANT_String_info structure in
a ClassFile express a sequence of Unicode code points,
but a String is a sequence of 16-bit code units (encoded
in UTF-16) while a CONSTANT_String_info references a
sequence of 8-bit code units (encoded in "modified UTF-8").
The Java Naming and Versioning rules are followed throughout.
Sections have been moved or reworded to clarify synchronization (2.11.10 (formerly 3.11.10), 3.15 (formerly 7.15)), linking errors (5.4) and virtual machine errors (6.3).
Section 3.14 (formerly 7.14), "Synchronization", shows the
contemporary output of javac for the example code.
Section 3.15 (formerly 7.15), "Annotations", specifies the
structure of a ClassFile that
holds package-level
annotations.
A number of comments were received on the proposed text of the Java Virtual Machine Specification, Java SE 7 Edition during a Maintenance Review in February/March 2011. Further amendments to the text are made, below, as a result of these comments.
4.7.4 "The StackMapTable Attribute" says "If a method's Code attribute
does not have a StackMapTable attribute, it has an implicit stack map
attribute." This clause will be noted as applicable only when the Code
attribute is in a class file of version 50.0 or above.
4.9.2 "Structural Constraints" says "There must never be an uninitialized class instance on the operand stack or in a local variable when any backwards branch is taken." This is too strong because there can be an uninitialized class type in the model operand stack/variable array at the target of a backward branch, provided the same uninitialized class type occurred in the same location in the model at the source of the branch. (This is noted in 4.10.2.4 "Instance Initialization Methods and Newly Created Objects", per CR 6594979.) Since an uninitialized class type can only ever be type-merged with itself, any branch is safe w.r.t. uninitialized class types in the source and target models; hence, the 4.9.2 clause will be removed.
5.3 "Creation and Loading" says "If a user-defined classloader prefetches binary representations of classes and interfaces, or loads a group of related classes together, then it must reflect loading errors only at points in the program where they could have arisen without prefetching or group loading." While this appears to be a new constraint on user-defined loaders, the behavior of a class loader has never been arbitrary. JLS3 12.2 states two invariants for a well-behaved loader, and a loader must also respect the general principle of the Java virtual machine that "Errors detected during linkage are thrown at a point in the program where some action is taken by the program that might, directly or indirectly, require linkage to the class or interface involved in the error." This principle gives rise to the invariant about prefetching. For clarity, invariants for a user-defined class loader have been centralized in 5.3, using the word "should" rather than "must" to indicate that a JVM implementation is not expected to enforce them.
5.4.3.5 "Method overriding" embodies the definition of overriding proposed in the clarifications and amendments for Java SE 5.0 made by the first Maintenance Review of JSR 924. (The proposal was in line with a global change from many years earlier, that made overriding a transitive relation.) As such, the definition is simply a restatement of the definition in the Java Language Specification with generics artifacts removed.
5.5 "Initialization" says "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." This clause will be expanded to exemplify that LC can be the Class object for C, or the monitor associated with that object.
5.7 "Virtual Machine Exit" makes statements that assume the JNI Invocation API is used to load and unload the JVM. Use of this API is not mandatory. The section will be changed to specify that JVM exit can be controlled by certain Java SE API calls, and that JNI may further be used to terminate the JVM.
jsr4.9.1 "Static Constraints" says "If the class file version number
is 51.0 or above, then neither the jsr opcode or the jsr_w opcode may
appear in the code array." The jsr and jsr_w
instructions in chapter 6 will also note the class file
restriction.
4.10.2.5 "Exceptions and finally" and 3.13 "Compiling finally" will
note that use of jsr to implement try-finally is only
possible in a ClassFile of version 50.0 and below.
4.3.4 "Signatures" and 4.7.6 "The InnerClasses Attribute" have text about the behavior of Oracle's Java virtual machine implementation. This text will be marked as non-normative.
4.7.21 "The SourceID Attribute" and 4.7.22 "The CompilationID Attribute" were intended to be non-normative, and will be removed until such time as the Java Virtual Machine Specification is available in both normative-only and normative-plus-informative versions.