Find JSRs
Submit this Search


Ad Banner
 
 
 
 

Maintenance Review of JSR 924 (JavaTM Virtual Machine Specification) for Java SE 7

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.)


Clarifications and Amendments to the Java Virtual Machine Specification, Second Edition

Compliance with JSR 901 (The Java Language Specification)

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".)

Compliance with JSR 133 (Java Memory Model)

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.

Compliance with JSR 202 (Java Class File Specification Update)

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.

Compliance with dynamic linking in JVM implementations

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.

ClassFile

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.

Instruction set

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.

General

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.


Further Clarifications and Amendments to the Java Virtual Machine Specification, Second Edition

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.

Linking

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.

Deprecation of jsr

4.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.

Non-normative material

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.