Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Status of JSR/RET in JVM spec

There are some parts of the JVM specification which suggest that the operations JSR (Jump SubRoutine), JSR_W (Jump SubRoutine Wide) and RET (RETurn from subroutine) may be used only up to class file version 50.0 (JDK 1.6):

3.13 Compiling Finally

(This section assumes a compiler generates class files with version number 50.0 or below, so that the jsr instruction may be used. See also §4.10.2.5.)

And later:

4.10.2.5. Exceptions and finally

To implement the try-finally construct, a compiler for the Java programming language that generates class files with version number 50.0 or below may use the exception-handling facilities together with two special instructions: jsr ("jump to subroutine") and ret ("return from subroutine").

On the other hand, the opcode descriptions themselves say nothing about a deprecation of these features. And the quoted texts only say how things used to be in versions up to 50.0, but doesn't explicitely state the state of affairs after that.

This comment (to a question which asks about the motivation behind this deprecation or removal) indicates a similar level of confusion, so apparently I'm not the only one looking for this.

like image 349
MvG Avatar asked May 03 '16 20:05

MvG


People also ask

What is opcodes in Java?

A Java Virtual Machine instruction consists of an opcode specifying the operation to be performed, followed by zero or more operands embodying values to be operated upon. This chapter gives details about the format of each Java Virtual Machine instruction and the operation it performs.

Does JVM have registers?

The JVM has a program counter and three registers that manage the stack. It has few registers because the bytecode instructions of the JVM operate primarily on the stack. This stack-oriented design helps keep the JVM's instruction set and implementation small.

How is Java bytecode executed?

They can be executed by intepretation, just-in-time compiling, or any other technique that was chosen by the designer of a particular JVM. A method's bytecode stream is a sequence of instructions for the Java virtual machine. Each instruction consists of a one-byte opcode followed by zero or more operands.

What is LDC in Java?

ByteCode:ldc pushes a one-word constant onto the operand stack. ldc takes a single parameter, , which is the value to push. Most of the bytecodes in JVM can figure out their name by the code description.


1 Answers

While adding links to my question, I noticed that the opcodes in question are absent from §4.10.1.9: Type Checking Instructions. So this shows that the new strackframe-based type verification scheme can't handle them, and §4.10: Verification of class Files writes:

Verification by type checking must be used to verify class files whose version number is greater than or equal to 50.0.

Or in more detail in §4.10.1: Verification by Type Checking:

A class file whose version number is 50.0 or above (§4.1) must be verified using the type checking rules given in this section.

If, and only if, a class file's version number equals 50.0, then if the type checking fails, a Java Virtual Machine implementation may choose to attempt to perform verification by type inference (§4.10.2).

So I'd say a version 50.0 class may still contain jsr and ret, but runs some risk that a JVM implementation won't verify said class and as a consequence will fail loading it.

But then I found an even more explicit rule, in §4.9.1: Static Constraints:

Only instances of the instructions documented in §6.5 may appear in the code array. Instances of instructions using the reserved opcodes (§6.2) or any opcodes not documented in this specification must not appear in the code array.

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 first paragraph is irrelevant for this question, since the instructions are listed in §6.5, and are not reserved according to §6.2. But the second paragraph explicitely marks them as forbidden in version 51.0 and up. The ret opcode, on the other hand, is useless without jsr or jsr_w, since only these two instructions can create a stack element of type returnAddress (and via some astore a local variable of that type) to by used by ret.


I still think that some notice to this effect should have been included in §6.5. Unfortunately, the Java bug report webpage hides the Continue button if one selects Type: Bug, Category: Java Platform Standard Edition, Subcategory: specification. It states that

This subcategory is for reporting technical errors and ambiguities in the text of the Java Language Specification and the JVM Specification. It is not the venue to propose new features in the Java language or JVM. Ongoing feature development is carried out in OpenJDK; corresponding enhancements to the Java Language Specification and the JVM Specification are managed through the Java Community Process.

But going through the JCP just to get some clarifying notes added to the descriptions of these three opcodes feels like massive overkill. So I hope that this post here helps those who on their own fail to find an answer in the specification itself.

like image 72
MvG Avatar answered Nov 15 '22 18:11

MvG