This document describes changes to the Java Virtual Machine Specification to support JEP 306.
The concept of floating-point modes, FP-strict and not FP-strict, is not needed and is removed since all floating-point methods only have a single, strict mode of operation. This single strict mode corresponds to the FP-strict mode.
Value sets and value set conversion are removed from the specification since each floating-point type can only hold a single set of values. This removal involves small edits to most floating-point instructions.
The method access flag
ACC_STRICT
remains defined for major class file versions 46 through 60, but undefined for class file version 61. This implies the prohibitions against a method having bothACC_ABSTRACT
andACC_STRICT
set remain in place for major class file versions 46 through 60, but not for version 61.JVM's may choose to issue a warning for
ACC_STRICT
being set on a major version 61 class file.Future releases and later major class file versions may assign a differing meaning to the 0x0800 bit position previously used by
ACC_STRICT
, including rejecting a later major version class file if 0x0800 is set.
Changes are described with respect to existing sections of the JVMS. New text is indicated like this and deleted text is indicated like this. Explanation and discussion, as needed, is set aside in grey boxes.
Chapter 2: The Structure of the Java Virtual Machine
2.3 Primitive Types and Values
The primitive data types supported by the Java Virtual Machine are the numeric types, the boolean
type (2.3.4), and the returnAddress
type (2.3.3).
The numeric types consist of the integral types (2.3.1) and the floating-point types (2.3.2).
The integral types are:
byte
, whose values are 8-bit signed two's-complement integers, and whose default value is zeroshort
, whose values are 16-bit signed two's-complement integers, and whose default value is zeroint
, whose values are 32-bit signed two's-complement integers, and whose default value is zerolong
, whose values are 64-bit signed two's-complement integers, and whose default value is zerochar
, whose values are 16-bit unsigned integers representing Unicode code points in the Basic Multilingual Plane, encoded with UTF-16, and whose default value is the null code point ('\u0000'
)
The floating-point types are:
float
, whose valuesare elements of the float value set or, where supported, the float-extended-exponent value set,correspond to the values of the IEEE 754 binary32 format and whose default value is positive zerodouble
, whose valuesare elements of the double value set or, where supported, the double-extended-exponent value set,correspond to the values of the IEEE 754 binary64 format and whose default value is positive zero
The values of the boolean
type encode the truth values true
and false
, and the default value is false
.
The First Edition of The Java® Virtual Machine Specification did not consider
boolean
to be a Java Virtual Machine type. However,boolean
values do have limited support in the Java Virtual Machine. The Second Edition of The Java® Virtual Machine Specification clarified the issue by treatingboolean
as a type.
The values of the returnAddress
type are pointers to the opcodes of Java Virtual Machine instructions. Of the primitive types, only the returnAddress
type is not directly associated with a Java programming language type.
2.3.2 Floating-Point Types, Value Sets, and Values
Note to readers: this section is very similar in structure and content to JLS 4.2.3.
The floating-point types are float
and double
, which are conceptually associated with the 32-bit binary32 and 64-bit binary64 floating-point formats for IEEE 754 values and operations, as specified in the IEEE 754 Standard (JLS §1.7).
In Java SE 15 and later, the Java Virtual Machine uses the 2019 version of the IEEE 754 Standard. Prior to Java SE 15, the Java Virtual Machine used the 1985 version of the IEEE 754 Standard, where the binary32 format was known as the single format and the binary64 format was known as the double format.
IEEE 754 includes not only positive and negative sign-magnitude numbers, but also positive and negative zeros, positive and negative infinities, and a special Not-a-Number value (hereafter abbreviated as "NaN"). The NaN value is used to represent the result of certain invalid operations such as dividing zero by zero.
Every implementation of the Java Virtual Machine is required to support two standard sets of floating-point values, called the float value set and the double value set. In addition, an implementation of the Java Virtual Machine may, at its option, support either or both of two extended-exponent floating-point value sets, called the float-extended-exponent value set and the double-extended-exponent value set. These extended-exponent value sets may, under certain circumstances, be used instead of the standard value sets to represent the values of type float
or double
.
The finite nonzero values of any binary floating-point value settype can all be expressed in the form s ⋅ m ⋅ 2^(e\ −\ N\ +\ 1)^, where s is +1 or −1, m is a positive integer less than 2N, and e is an integer between Emin = −(2K−1−2) and Emax = 2K−1−1, inclusive, and where N and K are parameters that depend on the value setassociated format. Some values can be represented in this form in more than one way; for example, supposing that a value v in a value set might be represented in this form using certain values for s, m, and e, then if it happened that m were even and e were less than 2K-1, one could halve m and increase e by 1 to produce a second representation for the same value v. A representation in this form is called normalized if m ≥ 2N-1; otherwise the representation is said to be subnormal. If a value in a value settype cannot be represented in such a way that m ≥ 2N-1, then the value is said to be a subnormal value, because its magnitude is below the magnitude of the smallest normalized value.
The constraints on the parameters N and K (and on the derived parameters Emin and Emax) for float
and double
the two required and two optional floating-point value sets are summarized in Table 2.3.2-A.
Table 2.3.2-A. Floating-point value set parameters
Parameter | float | float-extended-exponent | double | double-extended-exponent |
---|---|---|---|---|
N | 24 | 24 | 53 | 53 |
K | 8 | ≥ 11 | 11 | ≥ 15 |
Emax | +127 | ≥ +1023 | +1023 | ≥ +16383 |
Emin | -126 | ≤ -1022 | -1022 | ≤ -16382 |
Table 2.3.2-A. Floating-point value set parameters
Parameter | float | double | |
---|---|---|---|
N | 24 | 53 | |
K | 8 | 11 | |
Emax | +127 | +1023 | |
Emin | -126 | -1022 |
Where one or both extended-exponent value sets are supported by an implementation, then for each supported extended-exponent value set there is a specific implementation-dependent constant K, whose value is constrained by Table 2.3.2-A; this value K in turn dictates the values for Emin and Emax.
Each of the four value sets includes not only the finite nonzero values that are ascribed to it above, but also the five values: positive zero, negative zero, positive infinity, negative infinity, and NaN.
Note that the constraints in Table 2.3.2-A are designed so that every element of the float value set is necessarily also an element of the float-extended-exponent value set, the double value set, and the double-extended-exponent value set. Likewise, each element of the double value set is necessarily also an element of the double-extended-exponent value set. Each extended-exponent value set has a larger range of exponent values than the corresponding standard value set, but does not have more precision.
The elements of the float value set are exactly the values that can be represented using the binary32 floating-point format defined by IEEE 754, except that there is only one NaN value (IEEE 754 specifies 224-2 distinct NaN values). The elements of the double value set are exactly the values that can be represented using the binary64 floating-point format defined by IEEE 754, except that there is only one NaN value (IEEE 754 specifies 253-2 distinct NaN values). Note, however, that the elements of the float-extended-exponent and double-extended-exponent value sets defined here do not correspond to the values that can be represented using, respectively, the binary32 extended and binary64 extended floating-point formats defined by IEEE 754. This specification does not mandate a specific representation for the values of the floating-point value sets except where floating-point values must be represented in the class
file format (4.4.4, 4.4.5).
The float, float-extended-exponent, double, and double-extended-exponent value sets are not types. It is always correct for an implementation of the Java Virtual Machine to use an element of the float value set to represent a value of type float
; however, it may be permissible in certain contexts for an implementation to use an element of the float-extended-exponent value set instead. Similarly, it is always correct for an implementation to use an element of the double value set to represent a value of type double
; however, it may be permissible in certain contexts for an implementation to use an element of the double-extended-exponent value set instead.
Except for NaNs, values of the floating-point value setsfloating-point values are ordered. When arranged from smallest to largest, they are negative infinity, negative finite values, positive and negative zero, positive finite values, and positive infinity.
Floating-point positive zero and floating-point negative zero compare as equal, but there are other operations that can distinguish them; for example, dividing 1.0
by 0.0
produces positive infinity, but dividing 1.0
by -0.0
produces negative infinity.
NaNs are unordered, so numerical comparisons and tests for numerical equality have the value false
if either or both of their operands are NaN. In particular, a test for numerical equality of a value against itself has the value false
if and only if the value is NaN. A test for numerical inequality has the value true
if either operand is NaN.
2.8 Floating-Point Arithmetic
The full content of section (2.8.3) is deleted. The content previous in sections (2.8.1) and (2.8.2) is edited and incoroprated into 2.8 itself.
The Java Virtual Machine incorporates a subset of the floating-point arithmetic specified in the IEEE 754 Standard (JLS §1.7).
In Java SE 15 and later, the Java Virtual Machine uses the 2019 version of the IEEE 754 Standard. Prior to Java SE 15, the Java Virtual Machine used the 1985 version of the IEEE 754 Standard, where the binary32 format was known as the single format and the binary64 format was known as the double format.
Many of the Java Virtual Machine instructions for arithmetic (2.11.3) and type conversion (2.11.4) work with floating-point numbers. Java Virtual Machine These instructions on floating-point numbers behave as specified in IEEE 754, correspond to IEEE 754 operations [Table 2.8-A], with the exception of certain instructions described below.
Table 2.8-A Mapping JVM instructions to IEEE 754 operations
JVM Instruction | Corresponding IEEE 754 Operation |
---|---|
dadd (6.5.dadd), fadd (6.5.fadd) | addition |
dsub (6.5.dsub), fsub (6.5.fsub) | subtraction |
dmul (6.5.dmul), fsub (6.5.fmul) | multiplication |
ddiv (6.5.ddiv), fdiv (6.5.fdiv) | division |
dneg (6.5.dneg), fneg (6.5.fneg) | negate |
i2d (6.5.i2d), i2f (6.5.i2f), l2d (6.5.l2d), l2f (6.5.l2f) | convertFromInt |
d2i (6.5.d2i), d2l (6.5.d2l), f2i (6.5.f2i), f2l (6.5.f2l) | convertToIntegerTowardZero |
d2f (6.5.d2f), f2d (6.5.f2d) | convertFormat |
dcmp<op> (6.5.dcmp_op), fcmp<op> (6.5.fcmp_op) | compareQuietEqual, compareQuietNotEqual, compareQuietGreater, compareQuietGreaterEqual, compareQuietLess, compareQuietLessEqual |
Discussion of key differences moved up from the old section 2.8.1 and edited.
The key differences between the floating-point arithmetic supported by the Java Virtual Machine and the IEEE 754 Standard are:
The floating-point negate instructions dneg (6.5.dneg) and fneg (6.5.fneg) do not correspond precisely to the IEEE 754 negate operation. In particular, they do not require the sign bit of a NaN operand to be flipped.
While the Java Virtual machine does not directly have instructions that expose a NaN's sign bit, the bit can be inferred through the library methods
Double.doubleToRawLongBits
fordouble
values andFloat.floatToRawIntBits
forfloat
values.The floating-point operations of the Java Virtual Machine do not throw exceptions, trap, or otherwise signal the IEEE 754 exceptional conditions of invalid operation, division by zero, overflow, underflow, or inexact. The Java Virtual Machine has no signaling NaN value.
The Java Virtual Machine does not support IEEE 754 signaling floating-point comparisons.
IEEE 754 includes rounding-direction attributes that do not correspond to a rounding policy in the Java Virtual Machine. (Rounding policies defined below.) The Java Virtual Machine does not provide any means to change the rounding policy used by a given floating-point instruction.
The Java Virtual Machine does not support the binary32 extended and binary64 extended floating-point formats defined by IEEE 754. Neither extended range nor extended precision beyond those specified for the
float
anddouble
type may be used for operating on or storing floating-point values.
Not all operations required by IEEE 754 have corresponding Java Virtual Machine instructions. Some IEEE 754 operations without corresponding Java instructions have methods in the java.lang.Math and java.lang.StrictMath classes including the sqrt method for the squareRoot operation and the fma method for the fusedMultiplyAdd operation.
The floating-point remainder instructions drem (6.5.drem) and frem (6.5.frem) are defined differently than the IEEE 754 remainder. The drem and frem instructions are based on an implied division using the round toward zero rounding policy. The IEEE 754 remainder is instead based on an implied division using the round to nearest rounding policy.
The IEEE 754 remainder operation is provided by the library method Math.IEEEremainder or StrictMath.IEEEremainder.
In particular, the The Java Virtual Machine requires full support of IEEE 754 subnormal floating-point numbers and gradual underflow, which make it easier to prove desirable properties of particular numerical algorithms.
Java 1.0 and 1.1 required strict floating-point expression evaluation. In a strict floating-point expression evaluation policy, each
float
operand corresponds to a value representable in the IEEE 754 binary32 format, eachdouble
operand corresponds to a value representable in the IEEE 754 binary64 format, and each floating-point instruction with a corresponding IEEE 754 operation must match the IEEE 754 result for the same operands.
This model provides predictable results for the evaluation of floating-point expressions. However, there were performance problems when this model was delivered in Java Virtual Machine implementations for some processor families common in the Java 1.0/1.1 era.
In Java 1.2. through Java SE 16, the platform allowed an implementation to have one or two value sets associated with each floating-point type. The
float
type was associated with the float value set and float-extended-exponent value set. Likewise, thedouble
type was associated with the double value set and double-extended-exponent value set. The float value set corresponded to the values representable in the IEEE 754binary32
format. The float-extended-exponent value set had the same number of precision bits as thebinary32
format, but larger exponent range. The double value set corresponded to the values representable in the IEEE 754binary64
format. The double-extended-exponent value set had the same number of precision bits as thebinary64
format, but larger exponent range. Allowing use of the extended exponent value sets by default ameliorated the performance problems on some processor families.
The
ACC_STRICT
flag on a method forbade the use of extended exponent value sets. In other words,ACC_STRICT
constrained the floating-point semantics of any enclosed expressions to strictly use the float value set forfloat
expressions and the double value set fordouble
expressions, meaning the results of such expressions were fully predictable. Methods modified byACC_STRICT
had equivalent floating-point semantics to those specified in the Java 1.0 and 1.1 platforms.
As of Java SE 17, implementations are once again required to only support the original, strict, floating-point execution model. The concepts of value sets and value set conversion have been removed from the specification. Value sets and value set conversion were threaded throughout the specification, including several dozen instructions in chapter 6. The
ACC_STRICT
flag no longer has any effect on the semantics of a method since all floating-point arithmetic must be evaluated strictly. Due to design and implementation changes made subsequent to Java 1.2, newer members of the processor families that had performance problems executing strict evaluation no longer have that difficulty.
The bit position used for the method flag
ACC_STRICT
(4.6) is unassigned for class files with a major version of 61 or greater and may be repurposed for other uses in later major class file versions.
Floating-point arithmetic is an approximation to real arithmetic. While there are an infinite number of real numbers, a particular floating-point format only has a finite number of values. In the Java Virtual Machine, a rounding policy is a function used to map from a real number to a floating-point value in a given format. For real numbers in the representable range of a floating-point format, a continuous segment of the real number line is mapped to a single floating-point value. The real number whose value is numerically equal to a floating-point value is mapped to that floating-point value; for example, the real number 1.5 is mapped to the floating-point value 1.5 in a given format. The Java Virtual Machine defines two rounding policies, as follows:
The round to nearest rounding policy applies to all floating-point instructions except for (i) conversion to an integer value and (ii) remainder. Under the round to nearest rounding policy, inexact results must be rounded to the representable value nearest to the infinitely precise result; if the two nearest representable values are equally near, then the value whose least significant bit is zero is chosen.
The round to nearest rounding policy corresponds to the default rounding-direction attribute for binary arithmetic in IEEE 754, roundTiesToEven.
The roundTiesToEven rounding-direction attribute was known as the "round to nearest" rounding mode in the 1985 version of the IEEE 754 Standard. The rounding policy in the Java Virtual Machine is named after this rounding mode.
The round toward zero rounding policy applies to (i) conversion of a floating-point value to an integer value by the d2i, d2l, f2i, and f2l instructions (6.5.d2i, 6.5.d2l, 6.5.f2i, 6.5.f2l), and (ii) the floating-point remainder instructions drem and frem (6.5.drem, 6.5.frem). Under the round toward zero rounding policy, inexact results are rounded to the nearest representable value that is not greater in magnitude than the infinitely precise result. For conversion to integer, the round toward zero rounding policy is equivalent to truncation where fractional significand bits are discarded.
The round toward zero rounding policy corresponds to the roundTowardZero rounding-direction attribute for binary arithmetic in IEEE 754.
The roundTowardZero rounding-direction attribute was known as the "round toward zero" rounding mode in the 1985 version of the IEEE 754 Standard. The rounding policy in the Java Virtual Machine is named after this rounding mode.
The Java Virtual Machine requires that floating-point arithmetic behave as if every floating-point instruction rounds its floating-point result to the result precision. The rounding policy used by each instruction is either round to nearest or round toward zero, as specified above.
2.8.1 Java Virtual Machine Floating-Point Arithmetic and IEEE 754 Subsection text folding into parent section
The key differences between the floating-point arithmetic supported by the Java Virtual Machine and the IEEE 754 Standard are:
The floating-point operations of the Java Virtual Machine do not throw exceptions, trap, or otherwise signal the IEEE 754 exceptional conditions of invalid operation, division by zero, overflow, underflow, or inexact. The Java Virtual Machine has no signaling NaN value.
The Java Virtual Machine does not support IEEE 754 signaling floating-point comparisons.
IEEE 754 includes rounding-direction attributes that do not correspond to a rounding policy in the Java Virtual Machine. The Java Virtual Machine does not provide any means to change the rounding policy used by a given floating-point instruction.
The floating-point remainder instructions drem and frem are based on an implied division using the round toward zero rounding policy. The IEEE 754 remainder is instead based on an implied division using the round to nearest rounding policy.
The Java Virtual Machine does not support the binary32 extended and binary64 extended floating-point formats defined by IEEE 754
, except insofar as the double and double-extended-exponent value sets may be said to support the binary32 extended format.The float-extended-exponent and double-extended-exponent value sets, which may optionally be supported, do not correspond to the values of the IEEE 754 extended formats: the IEEE 754 extended formats require extended precision as well as extended exponent range.
2.8.2 Floating-Point Modes Subsection text folding into parent section
Every method has a floating-point mode, which is either FP-strict or not FP-strict. The floating-point mode of a method is determined by the setting of the ACC_STRICT
flag of the access_flags
item of the method_info
structure (4.6) defining the method. A method for which this flag is set is FP-strict; otherwise, the method is not FP-strict.
Note that this mapping of the
ACC_STRICT
flag implies that methods in classes compiled by a compiler in JDK release 1.1 or earlier are effectively not FP-strict.
We will refer to an operand stack as having a given floating-point mode when the method whose invocation created the frame containing the operand stack has that floating-point mode. Similarly, we will refer to a Java Virtual Machine instruction as having a given floating-point mode when the method containing that instruction has that floating-point mode.
If a float-extended-exponent value set is supported (2.3.2), values of type float
on an operand stack that is not FP-strict may range over that value set except where prohibited by value set conversion (2.8.3). If a double-extended-exponent value set is supported (2.3.2), values of type double
on an operand stack that is not FP-strict may range over that value set except where prohibited by value set conversion.
In all other contexts, whether on the operand stack or elsewhere, and regardless of floating-point mode, floating-point values of type float
and double
may only range over the float value set and double value set, respectively. In particular, class and instance fields, array elements, local variables, and method parameters may only contain values drawn from the standard value sets.
2.8.3 Value Set Conversion Deleted Subsection
An implementation of the Java Virtual Machine that supports an extended floating-point value set is permitted or required, under specified circumstances, to map a value of the associated floating-point type between the extended and the standard value sets. Such a value set conversion is not a type conversion, but a mapping between the value sets associated with the same type.
Where value set conversion is indicated, an implementation is permitted to perform one of the following operations on a value:
If the value is of type
float
and is not an element of the float value set, it maps the value to the nearest element of the float value set.If the value is of type
double
and is not an element of the double value set, it maps the value to the nearest element of the double value set.
In addition, where value set conversion is indicated, certain operations are required:
Suppose execution of a Java Virtual Machine instruction that is not FP-strict causes a value of type
float
to be pushed onto an operand stack that is FP-strict, passed as a parameter, or stored into a local variable, a field, or an element of an array. If the value is not an element of the float value set, it maps the value to the nearest element of the float value set.Suppose execution of a Java Virtual Machine instruction that is not FP-strict causes a value of type
double
to be pushed onto an operand stack that is FP-strict, passed as a parameter, or stored into a local variable, a field, or an element of an array. If the value is not an element of the double value set, it maps the value to the nearest element of the double value set.
Such required value set conversions may occur as a result of passing a parameter of a floating-point type during method invocation, including native
method invocation; returning a value of a floating-point type from a method that is not FP-strict to a method that is FP-strict; or storing a value of a floating-point type into a local variable, a field, or an array in a method that is not FP-strict.
Not all values from an extended-exponent value set can be mapped exactly to a value in the corresponding standard value set. If a value being mapped is too large to be represented exactly (its exponent is greater than that permitted by the standard value set), it is converted to a (positive or negative) infinity of the corresponding type. If a value being mapped is too small to be represented exactly (its exponent is smaller than that permitted by the standard value set), it is rounded to the nearest of a representable subnormal value or zero of the same sign.
Value set conversion preserves infinities and NaNs and cannot change the sign of the value being converted. Value set conversion has no effect on a value that is not of a floating-point type.
2.11 Instruction Set Summary
2.11.4 Type Conversion Instructions
The type conversion instructions allow conversion between Java Virtual Machine numeric types. These may be used to implement explicit conversions in user code or to mitigate the lack of orthogonality in the instruction set of the Java Virtual Machine.
The Java Virtual Machine directly supports the following widening numeric conversions:
int
tolong
,float
, ordouble
long
tofloat
ordouble
float
todouble
The widening numeric conversion instructions are i2l, i2f, i2d, l2f, l2d, and f2d. The mnemonics for these opcodes are straightforward given the naming conventions for typed instructions and the punning use of 2 to mean "to." For instance, the i2d instruction converts an int
value to a double
.
Most widening numeric conversions do not lose information about the overall magnitude of a numeric value. Indeed, conversions widening from int
to long
and int
to double
do not lose any information at all; the numeric value is preserved exactly. Conversions widening from float
to double
that are FP-strict (2.8.2) also preserve the numeric value exactly ; only such conversions that are not FP-strict may lose information about the overall magnitude of the converted value.
Conversions from int
to float
, or from long
to float
, or from long
to double
, may lose precision, that is, may lose some of the least significant bits of the value; the resulting floating-point value is a correctly rounded version of the integer value, using the round to nearest rounding policy (2.8).
Despite the fact that loss of precision may occur, widening numeric conversions never cause the Java Virtual Machine to throw a run-time exception (not to be confused with an IEEE 754 floating-point exception).
A widening numeric conversion of an int
to a long
simply sign-extends the two's-complement representation of the int
value to fill the wider format. A widening numeric conversion of a char
to an integral type zero-extends the representation of the char
value to fill the wider format.
Note that widening numeric conversions do not exist from integral types byte
, char
, and short
to type int
. As noted in 2.11.1, values of type byte
, char
, and short
are internally widened to type int
, making these conversions implicit.
The Java Virtual Machine also directly supports the following narrowing numeric conversions:
int
tobyte
,short
, orchar
long
toint
float
toint
orlong
double
toint
,long
, orfloat
The narrowing numeric conversion instructions are i2b, i2c, i2s, l2i, f2i, f2l, d2i, d2l, and d2f. A narrowing numeric conversion can result in a value of different sign, a different order of magnitude, or both; it may thereby lose precision.
A narrowing numeric conversion of an int
or long
to an integral type T simply discards all but the n lowest-order bits, where n is the number of bits used to represent type T. This may cause the resulting value not to have the same sign as the input value.
In a narrowing numeric conversion of a floating-point value to an integral type T, where T is either int
or long
, the floating-point value is converted as follows:
If the floating-point value is NaN, the result of the conversion is an
int
orlong
0
.Otherwise, if the floating-point value is not an infinity, the floating-point value is rounded to an integer value V using the round toward zero rounding policy (2.8). There are two cases:
If T is
long
and this integer value can be represented as along
, then the result is thelong
value V.If T is of type
int
and this integer value can be represented as anint
, then the result is theint
value V.
Otherwise:
Either the value must be too small (a negative value of large magnitude or negative infinity), and the result is the smallest representable value of type
int
orlong
.Or the value must be too large (a positive value of large magnitude or positive infinity), and the result is the largest representable value of type
int
orlong
.
A narrowing numeric conversion from double
to float
behaves in accordance with IEEE 754. The result is correctly rounded using the round to nearest rounding policy (2.8). A value too small to be represented as a float
is converted to a positive or negative zero of type float
; a value too large to be represented as a float
is converted to a positive or negative infinity. A double
NaN is always converted to a float
NaN.
Despite the fact that overflow, underflow, or loss of precision may occur, narrowing conversions among numeric types never cause the Java Virtual Machine to throw a run-time exception (not to be confused with an IEEE 754 floating-point exception).
Chapter 4: The class
File Format
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-strictif the major version number of theclass
file is at least 46 and at most 60ACC_SYNTHETIC
0x1000 Declared synthetic; not present in the source code. The value 0x0800 is interpreted as the
ACC_STRICT
flag only in aclass
file whose major version number is at least 46 and at most 60. For methods in such aclass
file, the rules of this section determine whetherACC_STRICT
may be set in combination with other flags. (The setting of theACC_STRICT
flag constrained thefloat
anddouble
operands and results of a method's floating-point instructions in Java SE 1.2 through 16, inclusive (2.8).) For methods in aclass
file whose major version number is less than 46 or greater than 60, the value 0x0800 is not interpreted as theACC_STRICT
flag, but rather is unassigned; it is not meaningful to "set" theACC_STRICT
flag for methods in such aclass
file.Methods of classes may have any of the flags in Table 4.6-A set. However, each method of a class may have at most one of its
ACC_PUBLIC
,ACC_PRIVATE
, andACC_PROTECTED
flags set (JLS §8.4.3).Methods of interfaces may have any of the flags in Table 4.6-A set except
ACC_PROTECTED
,ACC_FINAL
,ACC_SYNCHRONIZED
, andACC_NATIVE
(JLS §9.4). In aclass
file whose version number is less than 52.0, each method of an interface must have itsACC_PUBLIC
andACC_ABSTRACT
flags set; in aclass
file whose version number is 52.0 or above, each method of an interface must have exactly one of itsACC_PUBLIC
andACC_PRIVATE
flags set.If a method of a class or interface has its
ACC_ABSTRACT
flag set, it must not have any of itsACC_PRIVATE
,ACC_STATIC
,ACC_FINAL
,ACC_SYNCHRONIZED
,ACC_NATIVE
,ornor, if theACC_STRICT
flags setclass
file's major version number is at least 46 and at most 60, itsACC_STRICT
flag set.An instance initialization method (2.9.1) may have at most one of its
ACC_PUBLIC
,ACC_PRIVATE
, andACC_PROTECTED
flags set, and may also have itsACC_VARARGS
,ACC_STRICT
(in aclass
file whose major version number is at least 46 and at most 60), andACC_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 51.0 or above, a method whose name is<clinit>
must have itsACC_STATIC
flag set.A class or interface initialization method (2.9.2) is called implicitly by the Java Virtual Machine. The value of its
access_flags
item is ignored except for the setting of theACC_STATIC
flag and (in aclass
file whose major version number is at least 46 and at most 60)ACC_STRICT
flagflags, and the method is exempt from the preceding rules about legal combinations of flags.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. A method declared to take a variable number of arguments must be compiled with theACC_VARARGS
flag set to 1. All other methods must be compiled with theACC_VARARGS
flag set to 0.The
ACC_SYNTHETIC
flag indicates that this method was generated by a compiler and does not appear in source code, unless it is 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 generatedclass
files and should be ignored by Java Virtual Machine implementations. This includes the bit corresponding to 0x0800 in aclass
file whose major version number is less than 46 or greater than 60.- name_index
The value of the
name_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure (4.4.7) representing either a valid unqualified name denoting a method (4.2.2), or (if this method is in a class rather than an interface) the special method name<init>
, or the special method name<clinit>
.- descriptor_index
The value of the
descriptor_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure representing a valid method descriptor (4.3.3). Furthermore:If this method is in a class rather than an interface, and the name of the method is
<init>
, then the descriptor must denote avoid
method.If the name of the method is
<clinit>
, then the descriptor must denote avoid
method, and, in aclass
file whose version number is 51.0 or above, a method that takes no arguments.
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 theaccess_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 anattribute_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 amethod_info
structure are listed in Table 4.7-C.The rules concerning attributes defined to appear in the
attributes
table of amethod_info
structure are given in 4.7.The rules concerning non-predefined attributes in the
attributes
table of amethod_info
structure are given in 4.7.1.
Chapter 6: The Java Virtual Machine Instruction Set
6.5 Instructions
d2f
- Operation
Convert
double
tofloat
- Format
d2f
- Forms
d2f = 144 (0x90)
- Operand Stack
..., value →
..., result
- Description
The value on the top of the operand stack must be of type
double
. It is popped from the operand stackand undergoes value set conversion (2.8.3) resulting in value'. Thenvalue'value is converted to afloat
result using the round to nearest rounding policy (2.8). The result is pushed onto the operand stack.Where an d2f instruction is FP-strict (2.8.2), the result of the conversion is always rounded to the nearest representable value in the float value set (2.3.2).Where an d2f instruction is not FP-strict, the result of the conversion may be taken from the float-extended-exponent value set (2.3.2); it is not necessarily rounded to the nearest representable value in the float value set.A finite
value'value too small to be represented as afloat
is converted to a zero of the same sign; a finitevalue'value too large to be represented as afloat
is converted to an infinity of the same sign. Adouble
NaN is converted to afloat
NaN.- Notes
The d2f instruction performs a narrowing primitive conversion (JLS §5.1.3). It may lose information about the overall magnitude of
value'value and may also lose precision.
d2i
- Operation
Convert
double
toint
- Format
d2i
- Forms
d2i = 142 (0x8e)
- Operand Stack
..., value →
..., result
- Description
The value on the top of the operand stack must be of type
double
. It is popped from the operand stackand undergoes value set conversion (2.8.3) resulting in value'. Thenvalue'value is converted to anint
result. The result is pushed onto the operand stack:If the
value'value is NaN, the result of the conversion is anint
0.Otherwise, if the
value'value is not an infinity, it is rounded to an integer value V using the round toward zero rounding policy (2.8). If this integer value V can be represented as anint
, then the result is theint
value V.Otherwise, either the
value'value must be too small (a negative value of large magnitude or negative infinity), and the result is the smallest representable value of typeint
, or thevalue'value must be too large (a positive value of large magnitude or positive infinity), and the result is the largest representable value of typeint
.
- Notes
The d2i instruction performs a narrowing primitive conversion (JLS §5.1.3). It may lose information about the overall magnitude of
value'value and may also lose precision.
d2l
- Operation
Convert
double
tolong
- Format
d2l
- Forms
d2l = 143 (0x8f)
- Operand Stack
..., value →
..., result
- Description
The value on the top of the operand stack must be of type
double
. It is popped from the operand stackand undergoes value set conversion (2.8.3) resulting in value'. Thenvalue'value is converted to along
. The result is pushed onto the operand stack:If the
value'value is NaN, the result of the conversion is along
0.Otherwise, if the
value'value is not an infinity, it is rounded to an integer value V using the round toward zero rounding policy (2.8). If this integer value V can be represented as along
, then the result is thelong
value V.Otherwise, either the
value'value must be too small (a negative value of large magnitude or negative infinity), and the result is the smallest representable value of typelong
, or thevalue'value must be too large (a positive value of large magnitude or positive infinity), and the result is the largest representable value of typelong
.
- Notes
The d2l instruction performs a narrowing primitive conversion (JLS §5.1.3). It may lose information about the overall magnitude of
value'value and may also lose precision.
dadd
- Operation
Add
double
- Format
dadd
- Forms
dadd = 99 (0x63)
- Operand Stack
..., value1, value2 →
..., result
- Description
Both value1 and value2 must be of type
double
. The values are popped from the operand stackand undergo value set conversion (2.8.3), resulting in value1' and value2'. Thedouble
result isvalue1''value1 +value2'value2. The result is pushed onto the operand stack.The result of a dadd instruction is governed by the rules of IEEE 754 arithmetic:
If either
value1''value1 orvalue2'value2 is NaN, the result is NaN.The sum of two infinities of opposite sign is NaN.
The sum of two infinities of the same sign is the infinity of that sign.
The sum of an infinity and any finite value is equal to the infinity.
The sum of two zeroes of opposite sign is positive zero.
The sum of two zeroes of the same sign is the zero of that sign.
The sum of a zero and a nonzero finite value is equal to the nonzero value.
The sum of two nonzero finite values of the same magnitude and opposite sign is positive zero.
In the remaining cases, where neither operand is an infinity, a zero, or NaN and the values have the same sign or have different magnitudes, the sum is computed and rounded to the nearest representable value using the round to nearest rounding policy (2.8). If the magnitude is too large to represent as a
double
, we say the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent as adouble
, we say the operation underflows; the result is then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, or loss of precision may occur, execution of a dadd instruction never throws a run-time exception.
dastore
- Operation
Store into
double
array- Format
dastore
- Forms
dastore = 82 (0x52)
- Operand Stack
..., arrayref, index, value →
...
- Description
The arrayref must be of type
reference
and must refer to an array whose components are of typedouble
. The index must be of typeint
, and value must be of typedouble
. The arrayref, index, and value are popped from the operand stack. Thedouble
valueundergoes value set conversion (2.8.3), resulting in value', whichis stored as the component of the array indexed by index.- Run-time Exceptions
If arrayref is
null
, dastore throws aNullPointerException
.Otherwise, if index is not within the bounds of the array referenced by arrayref, the dastore instruction throws an
ArrayIndexOutOfBoundsException
.
dcmp<op>
- Operation
Compare
double
- Format
dcmp<op>
- Forms
dcmpg = 152 (0x98)
dcmpl = 151 (0x97)
- Operand Stack
..., value1, value2 →
..., result
- Description
Both value1 and value2 must be of type
double
.The values are popped from the operand stack and undergo value set conversion (2.8.3), resulting in value1' and value2'.A floating-point comparison is performed:If
value1'value1 is greater thanvalue2'value2, theint
value 1 is pushed onto the operand stack.Otherwise, if
value1'value1 is equal tovalue2'value2, theint
value 0 is pushed onto the operand stack.Otherwise, if
value1'value1 is less thanvalue2'value2, theint
value -1 is pushed onto the operand stack.Otherwise, at least one of
value1'value1 orvalue2'value2 is NaN. The dcmpg instruction pushes theint
value 1 onto the operand stack and the dcmpl instruction pushes theint
value -1 onto the operand stack.
Floating-point comparison is performed in accordance with IEEE 754. All values other than NaN are ordered, with negative infinity less than all finite values and positive infinity greater than all finite values. Positive zero and negative zero are considered equal.
- Notes
The dcmpg and dcmpl instructions differ only in their treatment of a comparison involving NaN. NaN is unordered, so any
double
comparison fails if either or both of its operands are NaN. With both dcmpg and dcmpl available, anydouble
comparison may be compiled to push the same result onto the operand stack whether the comparison fails on non-NaN values or fails because it encountered a NaN. For more information, see 3.5.
ddiv
- Operation
Divide
double
- Format
ddiv
- Forms
ddiv = 111 (0x6f)
- Operand Stack
..., value1, value2 →
..., result
- Description
Both value1 and value2 must be of type
double
. The values are popped from the operand stack andundergo value set conversion (2.8.3), resulting in value1' and value2'. Thedouble
result isvalue1'value1 /value2'value2. The result is pushed onto the operand stack.The result of a ddiv instruction is governed by the rules of IEEE 754 arithmetic:
If either
value1'value1 orvalue2'value2 is NaN, the result is NaN.If neither
value1'value1 norvalue2'value2 is NaN, the sign of the result is positive if both values have the same sign, negative if the values have different signs.Division of an infinity by an infinity results in NaN.
Division of an infinity by a finite value results in a signed infinity, with the sign-producing rule just given.
Division of a finite value by an infinity results in a signed zero, with the sign-producing rule just given.
Division of a zero by a zero results in NaN; division of zero by any other finite value results in a signed zero, with the sign-producing rule just given.
Division of a nonzero finite value by a zero results in a signed infinity, with the sign-producing rule just given.
In the remaining cases, where neither operand is an infinity, a zero, or NaN, the quotient is computed and rounded to the nearest
double
using the round to nearest rounding policy (2.8). If the magnitude is too large to represent as adouble
, we say the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent as adouble
, we say the operation underflows; the result is then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, division by zero, or loss of precision may occur, execution of a ddiv instruction never throws a run-time exception.
dmul
- Operation
Multiply
double
- Format
dmul
- Forms
dmul = 107 (0x6b)
- Operand Stack
..., value1, value2 →
..., result
- Description
Both value1 and value2 must be of type
double
. The values are popped from the operand stackand undergo value set conversion (2.8.3), resulting in value1' and value2'. Thedouble
result isvalue1'value1 *value2'value2. The result is pushed onto the operand stack.The result of a dmul instruction is governed by the rules of IEEE 754 arithmetic:
If either
value1'value1 orvalue2'value2 is NaN, the result is NaN.If neither
value1'value1 norvalue2'value2 is NaN, the sign of the result is positive if both values have the same sign and negative if the values have different signs.Multiplication of an infinity by a zero results in NaN.
Multiplication of an infinity by a finite value results in a signed infinity, with the sign-producing rule just given.
In the remaining cases, where neither an infinity nor NaN is involved, the product is computed and rounded to the nearest representable value using the round to nearest rounding policy (2.8). If the magnitude is too large to represent as a
double
, we say the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent as adouble
, we say the operation underflows; the result is then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, or loss of precision may occur, execution of a dmul instruction never throws a run-time exception.
dneg
- Operation
Negate
double
- Format
dneg
- Forms
dneg = 119 (0x77)
- Operand Stack
..., value →
..., result
- Description
The value must be of type
double
. It is popped from the operand stackand undergoes value set conversion (2.8.3), resulting in value'. Thedouble
result is the arithmetic negation ofvalue'value. The result is pushed onto the operand stack.For
double
values, negation is not the same as subtraction from zero. Ifx
is+0.0
, then0.0-x
equals+0.0
, but-x
equals-0.0
. Unary minus merely inverts the sign of adouble
.Special cases of interest:
If the operand is NaN, the result is NaN (recall that NaN has no sign).
Note that the Java Virtual Machine has not adopted the stronger requirement from the IEEE 754-2019 standard that negation inverts the sign bit for all inputs, including NaN.
If the operand is an infinity, the result is the infinity of opposite sign.
If the operand is a zero, the result is the zero of opposite sign.
drem
- Operation
Remainder
double
- Format
drem
- Forms
drem = 115 (0x73)
- Operand Stack
..., value1, value2 →
..., result
- Description
Both value1 and value2 must be of type
double
. The values are popped from the operand stackand undergo value set conversion (2.8.3), resulting in value1' and value2'. Thedouble
result is calculated and pushed onto the operand stack.The result of a drem instruction is not the same as the result of the remainder operation defined by IEEE 754, due to the choice of rounding policy in the Java Virtual Machine (2.8). The IEEE 754 remainder operation computes the remainder from a rounding division, not a truncating division, and so its behavior is not analogous to that of the usual integer remainder operator. Instead, the Java Virtual Machine defines drem to behave in a manner analogous to that of the integer remainder instructions irem and lrem, with an implied division using the round toward zero rounding policy; this may be compared with the C library function
fmod
.The result of a drem instruction is governed by the following rules, which match IEEE 754 arithmetic except for how the implied division is computed:
If either
value1'value1 orvalue2'value2 is NaN, the result is NaN.If neither
value1'value1 norvalue2'value2 is NaN, the sign of the result equals the sign of the dividend.If the dividend is an infinity or the divisor is a zero or both, the result is NaN.
If the dividend is finite and the divisor is an infinity, the result equals the dividend.
If the dividend is a zero and the divisor is finite, the result equals the dividend.
In the remaining cases, where neither operand is an infinity, a zero, or NaN, the floating-point remainder result from a dividend
value1'value1 and a divisorvalue2'value2 is defined by the mathematical relation result =value1'value1 - (value2'value2 * q), where q is an integer that is negative only ifvalue1'value1 /value2'value2 is negative, and positive only ifvalue1'value1 /value2'value2 is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient ofvalue1'value1 andvalue2'value2.
Despite the fact that division by zero may occur, evaluation of a drem instruction never throws a run-time exception. Overflow, underflow, or loss of precision cannot occur.
- Notes
The IEEE 754 remainder operation may be computed by the library routine
Math.IEEEremainder
orStrictMath.IEEEremainder
.
dreturn
- Operation
Return
double
from method- Format
dreturn
- Forms
dreturn = 175 (0xaf)
- Operand Stack
..., value →
[empty]
- Description
The current method must have return type
double
. The value must be of typedouble
. If the current method is asynchronized
method, the monitor entered or reentered on invocation of the method is updated and possibly exited as if by execution of a monitorexit instruction (6.5.monitorexit) in the current thread. If no exception is thrown, value is popped from the operand stack of the current frame (2.6)and undergoes value set conversion (2.8.3), resulting in value'. Thevalue'value is pushed onto the operand stack of the frame of the invoker. Any other values on the operand stack of the current method are discarded.The interpreter then returns control to the invoker of the method, reinstating the frame of the invoker.
- Run-time Exceptions
If the Java Virtual Machine implementation does not enforce the rules on structured locking described in 2.11.10, then if the current method is a
synchronized
method and the current thread is not the owner of the monitor entered or reentered on invocation of the method, dreturn throws anIllegalMonitorStateException
. This can happen, for example, if asynchronized
method contains a monitorexit instruction, but no monitorenter instruction, on the object on which the method is synchronized.Otherwise, if the Java Virtual Machine implementation enforces the rules on structured locking described in 2.11.10 and if the first of those rules is violated during invocation of the current method, then dreturn throws an
IllegalMonitorStateException
.
dstore
- Operation
Store
double
into local variable- Format
dstore
index- Forms
dstore = 57 (0x39)
- Operand Stack
..., value →
...
- Description
The index is an unsigned byte. Both index and index+1 must be indices into the local variable array of the current frame (2.6). The value on the top of the operand stack must be of type
double
.It is popped from the operand stack and undergoes value set conversion (2.8.3), resulting in value'.The local variables at index and index+1 are set tovalue'value.- Notes
The dstore opcode can be used in conjunction with the wide instruction (6.5.wide) to access a local variable using a two-byte unsigned index.
dstore_<n>
- Operation
Store
double
into local variable- Format
dstore_<n>
- Forms
dstore_0 = 71 (0x47)
dstore_1 = 72 (0x48)
dstore_2 = 73 (0x49)
dstore_3 = 74 (0x4a)
- Operand Stack
..., value →
...
- Description
Both <n> and <n>+1 must be indices into the local variable array of the current frame (2.6). The value on the top of the operand stack must be of type
double
.It is popped from the operand stack and undergoes value set conversion (2.8.3), resulting in value'.The local variables at <n> and <n>+1 are set tovalue'value.- Notes
Each of the dstore_<n> instructions is the same as dstore with an index of <n>, except that the operand <n> is implicit.
dsub
- Operation
Subtract
double
- Format
dsub
- Forms
dsub = 103 (0x67)
- Operand Stack
..., value1, value2 →
..., result
- Description
Both value1 and value2 must be of type
double
. The values are popped from the operand stackand undergo value set conversion (2.8.3), resulting in value1' and value2'. Thedouble
result isvalue1'value1 -value2'value2. The result is pushed onto the operand stack.For
double
subtraction, it is always the case thata-b
produces the same result asa+(-b)
. However, for the dsub instruction, subtraction from zero is not the same as negation, because ifx
is+0.0
, then0.0-x
equals+0.0
, but-x
equals-0.0
.The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, or loss of precision may occur, execution of a dsub instruction never throws a run-time exception.
f2d
- Operation
Convert
float
todouble
- Format
f2d
- Forms
f2d = 141 (0x8d)
- Operand Stack
..., value →
..., result
- Description
The value on the top of the operand stack must be of type
float
. It is popped from the operand stackand undergoes value set conversion (2.8.3), resulting in value'. Thenvalue'value is converted to adouble
result. This result is pushed onto the operand stack.- Notes
Where an f2d instruction is FP-strict (2.8.2) it performs a widening primitive conversion (JLS §5.1.2). Because all values of the float value set (2.3.2) are exactly representable by values of the double value set (2.3.2), such a conversion is exact.Where an f2d instruction is not FP-strict, the result of the conversion may be taken from the double-extended-exponent value set; it is not necessarily rounded to the nearest representable value in the double value set. However, if the operand value is taken from the float-extended-exponent value set and the target result is constrained to the double value set, rounding of value may be required.The f2d instruction performs a widening primitive conversion (JLS §5.1.2).
f2i
- Operation
Convert
float
toint
- Format
f2i
- Forms
f2i = 139 (0x8b)
- Operand Stack
..., value →
..., result
- Description
The value on the top of the operand stack must be of type
float
. It is popped from the operand stackand undergoes value set conversion (2.8.3), resulting in value'. Thenvalue'value is converted to anint
result. This result is pushed onto the operand stack:If the
value'value is NaN, the result of the conversion is anint
0.Otherwise, if the
value'value is not an infinity, it is rounded to an integer value V using the round toward zero rounding policy (2.8). If this integer value V can be represented as anint
, then the result is theint
value V.Otherwise, either the
value'value must be too small (a negative value of large magnitude or negative infinity), and the result is the smallest representable value of typeint
, or the value' must be too large (a positive value of large magnitude or positive infinity), and the result is the largest representable value of typeint
.
- Notes
The f2i instruction performs a narrowing primitive conversion (JLS §5.1.3). It may lose information about the overall magnitude of
value'value and may also lose precision.
f2l
- Operation
Convert
float
tolong
- Format
f2l
- Forms
f2l = 140 (0x8c)
- Operand Stack
..., value →
..., result
- Description
The value on the top of the operand stack must be of type
float
. It is popped from the operand stackand undergoes value set conversion (2.8.3), resulting in value'. Thenvalue'value is converted to along
result. This result is pushed onto the operand stack:If the
value'value is NaN, the result of the conversion is along
0.Otherwise, if the
value'value is not an infinity, it is rounded to an integer value V using the round toward zero rounding policy (2.8). If this integer value V can be represented as along
, then the result is thelong
value V.Otherwise, either the
value'value must be too small (a negative value of large magnitude or negative infinity), and the result is the smallest representable value of typelong
, or thevalue'value must be too large (a positive value of large magnitude or positive infinity), and the result is the largest representable value of typelong
.
- Notes
The f2l instruction performs a narrowing primitive conversion (JLS §5.1.3). It may lose information about the overall magnitude of
value'value and may also lose precision.
fadd
- Operation
Add
float
- Format
fadd
- Forms
fadd = 98 (0x62)
- Operand Stack
..., value1, value2 →
..., result
- Description
Both value1 and value2 must be of type
float
. The values are popped from the operand stackand undergo value set conversion (2.8.3), resulting in value1' and value2'. Thefloat
result isvalue1'value1 +value2'value2. The result is pushed onto the operand stack.The result of an fadd instruction is governed by the rules of IEEE 754 arithmetic:
If either
value1'value1 orvalue2'value2 is NaN, the result is NaN.The sum of two infinities of opposite sign is NaN.
The sum of two infinities of the same sign is the infinity of that sign.
The sum of an infinity and any finite value is equal to the infinity.
The sum of two zeroes of opposite sign is positive zero.
The sum of two zeroes of the same sign is the zero of that sign.
The sum of a zero and a nonzero finite value is equal to the nonzero value.
The sum of two nonzero finite values of the same magnitude and opposite sign is positive zero.
In the remaining cases, where neither operand is an infinity, a zero, or NaN and the values have the same sign or have different magnitudes, the sum is computed and rounded to the nearest representable value using the round to nearest rounding policy (2.8). If the magnitude is too large to represent as a
float
, we say the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent as afloat
, we say the operation underflows; the result is then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, or loss of precision may occur, execution of an fadd instruction never throws a run-time exception.
fastore
- Operation
Store into
float
array- Format
fastore
- Forms
fastore = 81 (0x51)
- Operand Stack
..., arrayref, index, value →
...
- Description
The arrayref must be of type
reference
and must refer to an array whose components are of typefloat
. The index must be of typeint
, and the value must be of typefloat
. The arrayref, index, and value are popped from the operand stack. Thefloat
valueundergoes value set conversion (2.8.3), resulting in value', and value'is stored as the component of the array indexed by index.- Run-time Exceptions
If arrayref is
null
, fastore throws aNullPointerException
.Otherwise, if index is not within the bounds of the array referenced by arrayref, the fastore instruction throws an
ArrayIndexOutOfBoundsException
.
fcmp<op>
- Operation
Compare
float
- Format
fcmp<op>
- Forms
fcmpg = 150 (0x96)
fcmpl = 149 (0x95)
- Operand Stack
..., value1, value2 →
..., result
- Description
Both value1 and value2 must be of type
float
. The values are popped from the operand stackand undergo value set conversion (2.8.3), resulting in value1' and value2'. A floating-point comparison is performed:If
value1'value1 is greater thanvalue2'value2, theint
value 1 is pushed onto the operand stack.Otherwise, if
value1'value1 is equal tovalue2'value2, theint
value 0 is pushed onto the operand stack.Otherwise, if
value1'value1 is less thanvalue2'value2, theint
value -1 is pushed onto the operand stack.Otherwise, at least one of
value1'value1 orvalue2'value2 is NaN. The fcmpg instruction pushes theint
value 1 onto the operand stack and the fcmpl instruction pushes theint
value -1 onto the operand stack.
Floating-point comparison is performed in accordance with IEEE 754. All values other than NaN are ordered, with negative infinity less than all finite values and positive infinity greater than all finite values. Positive zero and negative zero are considered equal.
- Notes
The fcmpg and fcmpl instructions differ only in their treatment of a comparison involving NaN. NaN is unordered, so any
float
comparison fails if either or both of its operands are NaN. With both fcmpg and fcmpl available, anyfloat
comparison may be compiled to push the same result onto the operand stack whether the comparison fails on non-NaN values or fails because it encountered a NaN. For more information, see 3.5.
fdiv
- Operation
Divide
float
- Format
fdiv
- Forms
fdiv = 110 (0x6e)
- Operand Stack
..., value1, value2 →
..., result
- Description
Both value1 and value2 must be of type
float
. The values are popped from the operand stackand undergo value set conversion (2.8.3), resulting in value1' and value2'. Thefloat
result isvalue1'value1 /value2'value2. The result is pushed onto the operand stack.The result of an fdiv instruction is governed by the rules of IEEE 754 arithmetic:
If either
value1'value1 orvalue2'value2 is NaN, the result is NaN.If neither
value1'value1 orvalue2'value2 is NaN, the sign of the result is positive if both values have the same sign, negative if the values have different signs.Division of an infinity by an infinity results in NaN.
Division of an infinity by a finite value results in a signed infinity, with the sign-producing rule just given.
Division of a finite value by an infinity results in a signed zero, with the sign-producing rule just given.
Division of a zero by a zero results in NaN; division of zero by any other finite value results in a signed zero, with the sign-producing rule just given.
Division of a nonzero finite value by a zero results in a signed infinity, with the sign-producing rule just given.
In the remaining cases, where neither operand is an infinity, a zero, or NaN, the quotient is computed and rounded to the nearest
float
using the round to nearest rounding policy (2.8). If the magnitude is too large to represent as afloat
, we say the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent as afloat
, we say the operation underflows; the result is then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, division by zero, or loss of precision may occur, execution of an fdiv instruction never throws a run-time exception.
fmul
- Operation
Multiply
float
- Format
fmul
- Forms
fmul = 106 (0x6a)
- Operand Stack
..., value1, value2 →
..., result
- Description
Both value1 and value2 must be of type
float
. The values are popped from the operand stackand undergo value set conversion (2.8.3), resulting in value1' and value2'. Thefloat
result isvalue1'value1 *value2'value2. The result is pushed onto the operand stack.The result of an fmul instruction is governed by the rules of IEEE 754 arithmetic:
If either
value1'value1 orvalue2'value2 is NaN, the result is NaN.If neither
value1'value1 norvalue2'value2 is NaN, the sign of the result is positive if both values have the same sign, and negative if the values have different signs.Multiplication of an infinity by a zero results in NaN.
Multiplication of an infinity by a finite value results in a signed infinity, with the sign-producing rule just given.
In the remaining cases, where neither an infinity nor NaN is involved, the product is computed and rounded to the nearest representable value using the round to nearest rounding policy (2.8). If the magnitude is too large to represent as a
float
, we say the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent as afloat
, we say the operation underflows; the result is then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, or loss of precision may occur, execution of an fmul instruction never throws a run-time exception.
fneg
- Operation
Negate
float
- Format
fneg
- Forms
fneg = 118 (0x76)
- Operand Stack
..., value →
..., result
- Description
The value must be of type
float
. It is popped from the operand stackand undergoes value set conversion (2.8.3), resulting in value'. Thefloat
result is the arithmetic negation ofvalue'value. This result is pushed onto the operand stack.For
float
values, negation is not the same as subtraction from zero. Ifx
is+0.0
, then0.0-x
equals+0.0
, but-x
equals-0.0
. Unary minus merely inverts the sign of afloat
.Special cases of interest:
If the operand is NaN, the result is NaN (recall that NaN has no sign).
Note that the Java Virtual Machine has not adopted the stronger requirement from the IEEE 754-2019 standard that negation inverts the sign bit for all inputs, including NaN.
If the operand is an infinity, the result is the infinity of opposite sign.
If the operand is a zero, the result is the zero of opposite sign.
frem
- Operation
Remainder
float
- Format
frem
- Forms
frem = 114 (0x72)
- Operand Stack
..., value1, value2 →
..., result
- Description
Both value1 and value2 must be of type
float
. The values are popped from the operand stackand undergo value set conversion (2.8.3), resulting in value1' and value2'. Thefloat
result is calculated and pushed onto the operand stack.The result of an frem instruction is not the same as the result of the remainder operation defined by IEEE 754, due to the choice of rounding policy in the Java Virtual Machine (2.8). The IEEE 754 remainder operation computes the remainder from a rounding division, not a truncating division, and so its behavior is not analogous to that of the usual integer remainder operator. Instead, the Java Virtual Machine defines frem to behave in a manner analogous to that of the integer remainder instructions irem and lrem, with an implied division using the round toward zero rounding policy; this may be compared with the C library function
fmod
.The result of an frem instruction is governed by the following rules, which match IEEE 754 arithmetic except for how the implied division is computed:
If either
value1'value1 orvalue2'value2 is NaN, the result is NaN.If neither
value1'value1 norvalue2'value2 is NaN, the sign of the result equals the sign of the dividend.If the dividend is an infinity or the divisor is a zero or both, the result is NaN.
If the dividend is finite and the divisor is an infinity, the result equals the dividend.
If the dividend is a zero and the divisor is finite, the result equals the dividend.
In the remaining cases, where neither operand is an infinity, a zero, or NaN, the floating-point remainder result from a dividend
value1'value1 and a divisorvalue2'value2 is defined by the mathematical relation result =value1'value1 - (value2'value2 * q), where q is an integer that is negative only ifvalue1'value1 /value2'value2 is negative and positive only ifvalue1'value1 /value2'value2 is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient ofvalue1'value1 andvalue2'value2.
Despite the fact that division by zero may occur, evaluation of an frem instruction never throws a run-time exception. Overflow, underflow, or loss of precision cannot occur.
- Notes
The IEEE 754 remainder operation may be computed by the library routine
Math.IEEEremainder
orStrictMath.IEEEremainder
.
freturn
- Operation
Return
float
from method- Format
freturn
- Forms
freturn = 174 (0xae)
- Operand Stack
..., value →
[empty]
- Description
The current method must have return type
float
. The value must be of typefloat
. If the current method is asynchronized
method, the monitor entered or reentered on invocation of the method is updated and possibly exited as if by execution of a monitorexit instruction (6.5.monitorexit) in the current thread. If no exception is thrown, value is popped from the operand stack of the current frame (2.6)and undergoes value set conversion (2.8.3), resulting in value'. Thevalue'value is pushed onto the operand stack of the frame of the invoker. Any other values on the operand stack of the current method are discarded.The interpreter then returns control to the invoker of the method, reinstating the frame of the invoker.
- Run-time Exceptions
If the Java Virtual Machine implementation does not enforce the rules on structured locking described in 2.11.10, then if the current method is a
synchronized
method and the current thread is not the owner of the monitor entered or reentered on invocation of the method, freturn throws anIllegalMonitorStateException
. This can happen, for example, if asynchronized
method contains a monitorexit instruction, but no monitorenter instruction, on the object on which the method is synchronized.Otherwise, if the Java Virtual Machine implementation enforces the rules on structured locking described in 2.11.10 and if the first of those rules is violated during invocation of the current method, then freturn throws an
IllegalMonitorStateException
.
fstore
- Operation
Store
float
into local variable- Format
fstore
index- Forms
fstore = 56 (0x38)
- Operand Stack
..., value →
...
- Description
The index is an unsigned byte that must be an index into the local variable array of the current frame (2.6). The value on the top of the operand stack must be of type
float
.It is popped from the operand stack and undergoes value set conversion (2.8.3), resulting in value'.The value of the local variable at index is set tovalue'value.- Notes
The fstore opcode can be used in conjunction with the wide instruction (6.5.wide) to access a local variable using a two-byte unsigned index.
fstore_<n>
- Operation
Store
float
into local variable- Format
fstore_<n>
- Forms
fstore_0 = 67 (0x43)
fstore_1 = 68 (0x44)
fstore_2 = 69 (0x45)
fstore_3 = 70 (0x46)
- Operand Stack
..., value →
...
- Description
The <n> must be an index into the local variable array of the current frame (2.6). The value on the top of the operand stack must be of type
float
.It is popped from the operand stack and undergoes value set conversion (2.8.3), resulting in value'.The value of the local variable at <n> is set tovalue'value.- Notes
Each of the fstore_<n> instructions is the same as fstore with an index of <n>, except that the operand <n> is implicit.
fsub
- Operation
Subtract
float
- Format
fsub
- Forms
fsub = 102 (0x66)
- Operand Stack
..., value1, value2 →
..., result
- Description
Both value1 and value2 must be of type
float
.The values are popped from the operand stack and undergo value set conversion (2.8.3), resulting in value1' and value2'.Thefloat
result isvalue1'value1 -value2'value2. The result is pushed onto the operand stack.For
float
subtraction, it is always the case thata-b
produces the same result asa+(-b)
. However, for the fsub instruction, subtraction from zero is not the same as negation, because ifx
is+0.0
, then0.0-x
equals+0.0
, but-x
equals-0.0
.The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, or loss of precision may occur, execution of an fsub instruction never throws a run-time exception.
invokedynamic
The invokedynamic instruction does not mention value set conversion and thus does not need to be updated for JEP 306.
invokeinterface
- Operation
Invoke interface method
- Format
invokeinterface
indexbyte1
indexbyte2
count
0- Forms
invokeinterface = 185 (0xb9)
- Operand Stack
..., objectref, [arg1, [arg2 ...]] →
...
- 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 an interface method (5.1), which gives the name and descriptor (4.3.3) of the interface method as well as a symbolic reference to the interface in which the interface method is to be found. The named interface method is resolved ([5.4.3.4]).The resolved interface method must not be an instance initialization method, or the class or interface initialization method (2.9.1, 2.9.2).
The count operand is an unsigned byte that must not be zero. The objectref must be of type
reference
and must be followed on the operand stack by nargs argument values, where the number, type, and order of the values must be consistent with the descriptor of the resolved interface method. The value of the fourth operand byte must always be zero.Let C be the class of objectref. A method is selected with respect to C and the resolved method ([5.4.6]). This is the method to be invoked.
If the method to be invoked is
synchronized
, the monitor associated with objectref is entered or reentered as if by execution of a monitorenter instruction ([6.5.monitorenter]) in the current thread.If the method to be invoked is not
native
, the nargs argument values and objectref are popped from the operand stack. A new frame is created on the Java Virtual Machine stack for the method being invoked. The objectref and the argument values are consecutively made the values of local variables of the new frame, with objectref in local variable 0, arg1 in local variable 1 (or, if arg1 is of typelong
ordouble
, in local variables 1 and 2), and so on.Any argument value that is of a floating-point type undergoes value set conversion (2.8.3) prior to being stored in a local variable.The new frame is then made current, and the Java Virtual Machinepc
is set to the opcode of the first instruction of the method to be invoked. Execution continues with the first instruction of the method.If the method to be invoked is
native
and the platform-dependent code that implements it has not yet been bound ([5.6]) into the Java Virtual Machine, then that is done. The nargs argument values and objectref are popped from the operand stack and are passed as parameters to the code that implements the method.Any argument value that is of a floating-point type undergoes value set conversion (2.8.3) prior to being passed as a parameter.The parameters are passed and the code is invoked in an implementation-dependent manner. When the platform-dependent code returns:If the
native
method issynchronized
, the monitor associated with objectref is updated and possibly exited as if by execution of a monitorexit instruction (6.5.monitorexit) in the current thread.If the
native
method returns a value, the return value of the platform-dependent code is converted in an implementation-dependent way to the return type of thenative
method and pushed onto the operand stack.
- Linking Exceptions
During resolution of the symbolic reference to the interface method, any of the exceptions pertaining to interface method resolution ([5.4.3.4]) can be thrown.
Otherwise, if the resolved method is
static
, the invokeinterface instruction throws anIncompatibleClassChangeError
.Note that invokeinterface may refer to
private
methods declared in interfaces, including nestmate interfaces.- Run-time Exceptions
Otherwise, if objectref is
null
, the invokeinterface instruction throws aNullPointerException
.Otherwise, if the class of objectref does not implement the resolved interface, invokeinterface throws an
IncompatibleClassChangeError
.Otherwise, if the selected method is neither
public
norprivate
, invokeinterface throws anIllegalAccessError
.Otherwise, if the selected method is
abstract
, invokeinterface throws anAbstractMethodError
.Otherwise, if the selected method is
native
and the code that implements the method cannot be bound, invokeinterface throws anUnsatisfiedLinkError
.Otherwise, if no method is selected, and there are multiple maximally-specific superinterface methods of C that match the resolved method's name and descriptor and are not
abstract
, invokeinterface throws anIncompatibleClassChangeError
Otherwise, if no method is selected, and there are no maximally-specific superinterface methods of C that match the resolved method's name and descriptor and are not
abstract
, invokeinterface throws anAbstractMethodError
.- Notes
The count operand of the invokeinterface instruction records a measure of the number of argument values, where an argument value of type
long
or typedouble
contributes two units to the count value and an argument of any other type contributes one unit. This information can also be derived from the descriptor of the selected method. The redundancy is historical.The fourth operand byte exists to reserve space for an additional operand used in certain of Oracle's Java Virtual Machine implementations, which replace the invokeinterface instruction by a specialized pseudo-instruction at run time. It must be retained for backwards compatibility.
The nargs argument values and objectref are not one-to-one with the first nargs+1 local variables. Argument values of types
long
anddouble
must be stored in two consecutive local variables, thus more than nargs local variables may be required to pass nargs argument values to the invoked method.The selection logic allows a non-
abstract
method declared in a superinterface to be selected. Methods in interfaces are only considered if there is no matching method in the class hierarchy. In the event that there are two non-abstract
methods in the superinterface hierarchy, with neither more specific than the other, an error occurs; there is no attempt to disambiguate (for example, one may be the referenced method and one may be unrelated, but we do not prefer the referenced method). On the other hand, if there are manyabstract
methods but only one non-abstract
method, the non-abstract
method is selected (unless anabstract
method is more specific).
invokespecial
- Operation
Invoke instance method; direct invocation of instance initialization methods and methods of the current class and its supertypes
- Format
invokespecial
indexbyte1
indexbyte2- Forms
invokespecial = 183 (0xb7)
- Operand Stack
..., objectref, [arg1, [arg2 ...]] →
...
- 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 method or an interface method (5.1), which gives the name and descriptor (4.3.3) of the method or interface method as well as a symbolic reference to the class or interface in which the method or interface method is to be found. The named method is resolved ([5.4.3.3], [5.4.3.4]).If all of the following are true, let C be the direct superclass of the current class:
The resolved method is not an instance initialization method (2.9.1).
The symbolic reference names a class (not an interface), and that class is a superclass of the current class.
The
ACC_SUPER
flag is set for theclass
file ([4.1]).
Otherwise, let C be the class or interface named by the symbolic reference.
The actual method to be invoked is selected by the following lookup procedure:
If C contains a declaration for an instance method with the same name and descriptor as the resolved method, then it is the method to be invoked.
Otherwise, if C is a class and has a superclass, a search for a declaration of an instance method with the same name and descriptor as the resolved method is performed, starting with the direct superclass of C and continuing with the direct superclass of that class, and so forth, until a match is found or no further superclasses exist. If a match is found, then it is the method to be invoked.
Otherwise, if C is an interface and the class
Object
contains a declaration of apublic
instance method with the same name and descriptor as the resolved method, then it is the method to be invoked.Otherwise, if there is exactly one maximally-specific method ([5.4.3.3]) in the superinterfaces of C that matches the resolved method's name and descriptor and is not
abstract
, then it is the method to be invoked.
The objectref must be of type
reference
and must be followed on the operand stack by nargs argument values, where the number, type, and order of the values must be consistent with the descriptor of the selected instance method.If the method is
synchronized
, the monitor associated with objectref is entered or reentered as if by execution of a monitorenter instruction ([6.5.monitorenter]) in the current thread.If the method is not
native
, the nargs argument values and objectref are popped from the operand stack. A new frame is created on the Java Virtual Machine stack for the method being invoked. The objectref and the argument values are consecutively made the values of local variables of the new frame, with objectref in local variable 0, arg1 in local variable 1 (or, if arg1 is of typelong
ordouble
, in local variables 1 and 2), and so on.Any argument value that is of a floating-point type undergoes value set conversion (2.8.3) prior to being stored in a local variable.The new frame is then made current, and the Java Virtual Machinepc
is set to the opcode of the first instruction of the method to be invoked. Execution continues with the first instruction of the method.If the method is
native
and the platform-dependent code that implements it has not yet been bound ([5.6]) into the Java Virtual Machine, that is done. The nargs argument values and objectref are popped from the operand stack and are passed as parameters to the code that implements the method.Any argument value that is of a floating-point type undergoes value set conversion (2.8.3) prior to being passed as a parameter.The parameters are passed and the code is invoked in an implementation-dependent manner. When the platform-dependent code returns, the following take place:If the
native
method issynchronized
, the monitor associated with objectref is updated and possibly exited as if by execution of a monitorexit instruction (6.5.monitorexit) in the current thread.If the
native
method returns a value, the return value of the platform-dependent code is converted in an implementation-dependent way to the return type of thenative
method and pushed onto the operand stack.
- Linking Exceptions
During resolution of the symbolic reference to the method, any of the exceptions pertaining to method resolution ([5.4.3.3]) can be thrown.
Otherwise, if the resolved method is an instance initialization method, and the class in which it is declared is not the class symbolically referenced by the instruction, a
NoSuchMethodError
is thrown.Otherwise, if the resolved method is a class (
static
) method, the invokespecial instruction throws anIncompatibleClassChangeError
.- Run-time Exceptions
Otherwise, if objectref is
null
, the invokespecial instruction throws aNullPointerException
.Otherwise, if step 1, step 2, or step 3 of the lookup procedure selects an
abstract
method, invokespecial throws anAbstractMethodError
.Otherwise, if step 1, step 2, or step 3 of the lookup procedure selects a
native
method and the code that implements the method cannot be bound, invokespecial throws anUnsatisfiedLinkError
.Otherwise, if step 4 of the lookup procedure determines there are multiple maximally-specific superinterface methods of C that match the resolved method's name and descriptor and are not
abstract
, invokespecial throws anIncompatibleClassChangeError
Otherwise, if step 4 of the lookup procedure determines there are no maximally-specific superinterface methods of C that match the resolved method's name and descriptor and are not
abstract
, invokespecial throws anAbstractMethodError
.- Notes
The difference between the invokespecial instruction and the invokevirtual instruction ([6.5.invokevirtual]) is that invokevirtual invokes a method based on the class of the object. The invokespecial instruction is used to directly invoke instance initialization methods (2.9.1) as well as methods of the current class and its supertypes.
The invokespecial instruction was named
invokenonvirtual
prior to JDK release 1.0.2.The nargs argument values and objectref are not one-to-one with the first nargs+1 local variables. Argument values of types
long
anddouble
must be stored in two consecutive local variables, thus more than nargs local variables may be required to pass nargs argument values to the invoked method.The invokespecial instruction handles invocation of a non-
abstract
interface method, referenced either via a direct superinterface or via a superclass. In these cases, the rules for selection are essentially the same as those for invokeinterface (except that the search starts from a different class).
invokestatic
- Operation
Invoke a class (
static
) method- Format
invokestatic
indexbyte1
indexbyte2- Forms
invokestatic = 184 (0xb8)
- Operand Stack
..., [arg1, [arg2 ...]] →
...
- 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 method or an interface method (5.1), which gives the name and descriptor (4.3.3) of the method or interface method as well as a symbolic reference to the class or interface in which the method or interface method is to be found. The named method is resolved ([5.4.3.3], [5.4.3.4]).The resolved method must not be an instance initialization method, or the class or interface initialization method (2.9.1, 2.9.2).
The resolved method must be
static
, and therefore cannot beabstract
.On successful resolution of the method, the class or interface that declared the resolved method is initialized if that class or interface has not already been initialized (5.5).
The operand stack must contain nargs argument values, where the number, type, and order of the values must be consistent with the descriptor of the resolved method.
If the method is
synchronized
, the monitor associated with the resolvedClass
object is entered or reentered as if by execution of a monitorenter instruction ([6.5.monitorenter]) in the current thread.If the method is not
native
, the nargs argument values are popped from the operand stack. A new frame is created on the Java Virtual Machine stack for the method being invoked. The nargs argument values are consecutively made the values of local variables of the new frame, with arg1 in local variable 0 (or, if arg1 is of typelong
ordouble
, in local variables 0 and 1) and so on.Any argument value that is of a floating-point type undergoes value set conversion (2.8.3) prior to being stored in a local variable.The new frame is then made current, and the Java Virtual Machinepc
is set to the opcode of the first instruction of the method to be invoked. Execution continues with the first instruction of the method.If the method is
native
and the platform-dependent code that implements it has not yet been bound ([5.6]) into the Java Virtual Machine, that is done. The nargs argument values are popped from the operand stack and are passed as parameters to the code that implements the method.Any argument value that is of a floating-point type undergoes value set conversion (2.8.3) prior to being passed as a parameter.The parameters are passed and the code is invoked in an implementation-dependent manner. When the platform-dependent code returns, the following take place:If the
native
method issynchronized
, the monitor associated with the resolvedClass
object is updated and possibly exited as if by execution of a monitorexit instruction (6.5.monitorexit) in the current thread.If the
native
method returns a value, the return value of the platform-dependent code is converted in an implementation-dependent way to the return type of thenative
method and pushed onto the operand stack.
- Linking Exceptions
During resolution of the symbolic reference to the method, any of the exceptions pertaining to method resolution ([5.4.3.3]) can be thrown.
Otherwise, if the resolved method is an instance method, the invokestatic instruction throws an
IncompatibleClassChangeError
.- Run-time Exceptions
Otherwise, if execution of this invokestatic instruction causes initialization of the referenced class or interface, invokestatic may throw an
Error
as detailed in 5.5.Otherwise, if the resolved method is
native
and the code that implements the method cannot be bound, invokestatic throws anUnsatisfiedLinkError
.- Notes
The nargs argument values are not one-to-one with the first nargs local variables. Argument values of types
long
anddouble
must be stored in two consecutive local variables, thus more than nargs local variables may be required to pass nargs argument values to the invoked method.
invokevirtual
- Operation
Invoke instance method; dispatch based on class
- Format
invokevirtual
indexbyte1
indexbyte2- Forms
invokevirtual = 182 (0xb6)
- Operand Stack
..., objectref, [arg1, [arg2 ...]] →
...
- 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 method (5.1), which gives the name and descriptor (4.3.3) of the method as well as a symbolic reference to the class in which the method is to be found. The named method is resolved ([5.4.3.3]).If the resolved method is not signature polymorphic ([2.9.3]), then the invokevirtual instruction proceeds as follows.
Let C be the class of objectref. A method is selected with respect to C and the resolved method ([5.4.6]). This is the method to be invoked.
The objectref must be followed on the operand stack by nargs argument values, where the number, type, and order of the values must be consistent with the descriptor of the selected instance method.
If the method to be invoked is
synchronized
, the monitor associated with objectref is entered or reentered as if by execution of a monitorenter instruction ([6.5.monitorenter]) in the current thread.If the method to be invoked is not
native
, the nargs argument values and objectref are popped from the operand stack. A new frame is created on the Java Virtual Machine stack for the method being invoked. The objectref and the argument values are consecutively made the values of local variables of the new frame, with objectref in local variable 0, arg1 in local variable 1 (or, if arg1 is of typelong
ordouble
, in local variables 1 and 2), and so on.Any argument value that is of a floating-point type undergoes value set conversion (2.8.3) prior to being stored in a local variable.The new frame is then made current, and the Java Virtual Machinepc
is set to the opcode of the first instruction of the method to be invoked. Execution continues with the first instruction of the method.If the method to be invoked is
native
and the platform-dependent code that implements it has not yet been bound ([5.6]) into the Java Virtual Machine, that is done. The nargs argument values and objectref are popped from the operand stack and are passed as parameters to the code that implements the method.Any argument value that is of a floating-point type undergoes value set conversion (2.8.3) prior to being passed as a parameter.The parameters are passed and the code is invoked in an implementation-dependent manner. When the platform-dependent code returns, the following take place:If the
native
method issynchronized
, the monitor associated with objectref is updated and possibly exited as if by execution of a monitorexit instruction (6.5.monitorexit) in the current thread.If the
native
method returns a value, the return value of the platform-dependent code is converted in an implementation-dependent way to the return type of thenative
method and pushed onto the operand stack.
If the resolved method is signature polymorphic ([2.9.3]), and declared in the
java.lang.invoke.MethodHandle
class, then the invokevirtual instruction proceeds as follows, where D is the descriptor of the method symbolically referenced by the instruction.First, a
reference
to an instance ofjava.lang.invoke.MethodType
is obtained as if by resolution of a symbolic reference to a method type (5.4.3.5) with the same parameter and return types as D.If the named method is
invokeExact
, the instance ofjava.lang.invoke.MethodType
must be semantically equal to the type descriptor of the receiving method handle objectref. The method handle to be invoked is objectref.If the named method is
invoke
, and the instance ofjava.lang.invoke.MethodType
is semantically equal to the type descriptor of the receiving method handle objectref, then the method handle to be invoked is objectref.If the named method is
invoke
, and the instance ofjava.lang.invoke.MethodType
is not semantically equal to the type descriptor of the receiving method handle objectref, then the Java Virtual Machine attempts to adjust the type descriptor of the receiving method handle, as if by invocation of theasType
method ofjava.lang.invoke.MethodHandle
, to obtain an exactly invokable method handle m. The method handle to be invoked is m.
The objectref must be followed on the operand stack by nargs argument values, where the number, type, and order of the values must be consistent with the type descriptor of the method handle to be invoked. (This type descriptor will correspond to the method descriptor appropriate for the kind of the method handle to be invoked, as specified in 5.4.3.5.)
Then, if the method handle to be invoked has bytecode behavior, the Java Virtual Machine invokes the method handle as if by execution of the bytecode behavior associated with the method handle's kind. If the kind is 5 (
REF_invokeVirtual
), 6 (REF_invokeStatic
), 7 (REF_invokeSpecial
), 8 (REF_newInvokeSpecial
), or 9 (REF_invokeInterface
), then a frame will be created and made current in the course of executing the bytecode behavior; however, this frame is not visible, and when the method invoked by the bytecode behavior completes (normally or abruptly), the frame of its invoker is considered to be the frame for the method containing this invokevirtual instruction.Otherwise, if the method handle to be invoked has no bytecode behavior, the Java Virtual Machine invokes it in an implementation-dependent manner.
If the resolved method is signature polymorphic and declared in the
java.lang.invoke.VarHandle
class, then the invokevirtual instruction proceeds as follows, where N and D are the name and descriptor of the method symbolically referenced by the instruction.First, a
reference
to an instance ofjava.lang.invoke.VarHandle.AccessMode
is obtained as if by invocation of thevalueFromMethodName
method ofjava.lang.invoke.VarHandle.AccessMode
with aString
argument denoting N.Second, a
reference
to an instance ofjava.lang.invoke.MethodType
is obtained as if by invocation of theaccessModeType
method ofjava.lang.invoke.VarHandle
on the instance objectref, with the instance ofjava.lang.invoke.VarHandle.AccessMode
as the argument.Third, a
reference
to an instance ofjava.lang.invoke.MethodHandle
is obtained as if by invocation of thevarHandleExactInvoker
method ofjava.lang.invoke.MethodHandles
with the instance ofjava.lang.invoke.VarHandle.AccessMode
as the first argument and the instance ofjava.lang.invoke.MethodType
as the second argument. The resulting instance is called the invoker method handle.Finally, the nargs argument values and objectref are popped from the operand stack, and the invoker method handle is invoked. The invocation occurs as if by execution of an invokevirtual instruction that indicates a run-time constant pool index to a symbolic reference R where:
R is a symbolic reference to a method of a class;
for the symbolic reference to the class in which the method is to be found, R specifies
java.lang.invoke.MethodHandle
;for the name of the method, R specifies
invoke
;for the descriptor of the method, R specifies a return type indicated by the return descriptor of D, and specifies a first parameter type of
java.lang.invoke.VarHandle
followed by the parameter types indicated by the parameter descriptors of D (if any) in order.
and where it is as if the following items were pushed, in order, onto the operand stack:
a
reference
to the instance ofjava.lang.invoke.MethodHandle
(the invoker method handle);objectref;
the nargs argument values, where the number, type, and order of the values must be consistent with the type descriptor of the invoker method handle.
- Linking Exceptions
During resolution of the symbolic reference to the method, any of the exceptions pertaining to method resolution ([5.4.3.3]) can be thrown.
Otherwise, if the resolved method is a class (
static
) method, the invokevirtual instruction throws anIncompatibleClassChangeError
.Otherwise, if the resolved method is signature polymorphic and declared in the
java.lang.invoke.MethodHandle
class, then during resolution of the method type derived from the descriptor in the symbolic reference to the method, any of the exceptions pertaining to method type resolution (5.4.3.5) can be thrown.Otherwise, if the resolved method is signature polymorphic and declared in the
java.lang.invoke.VarHandle
class, then any linking exception that may arise from invocation of the invoker method handle can be thrown. No linking exceptions are thrown from invocation of thevalueFromMethodName
,accessModeType
, andvarHandleExactInvoker
methods.- Run-time Exceptions
Otherwise, if objectref is
null
, the invokevirtual instruction throws aNullPointerException
.Otherwise, if the resolved method is not signature polymorphic:
If the selected method is
abstract
, invokevirtual throws anAbstractMethodError
.Otherwise, if the selected method is
native
and the code that implements the method cannot be bound, invokevirtual throws anUnsatisfiedLinkError
.Otherwise, if no method is selected, and there are multiple maximally-specific superinterface methods of C that match the resolved method's name and descriptor and are not
abstract
, invokevirtual throws anIncompatibleClassChangeError
Otherwise, if no method is selected, and there are no maximally-specific superinterface methods of C that match the resolved method's name and descriptor and are not
abstract
, invokevirtual throws anAbstractMethodError
.
Otherwise, if the resolved method is signature polymorphic and declared in the
java.lang.invoke.MethodHandle
class, then:If the method name is
invokeExact
, and the obtained instance ofjava.lang.invoke.MethodType
is not semantically equal to the type descriptor of the receiving method handle objectref, the invokevirtual instruction throws ajava.lang.invoke.WrongMethodTypeException
.If the method name is
invoke
, and the obtained instance ofjava.lang.invoke.MethodType
is not a valid argument to theasType
method ofjava.lang.invoke.MethodHandle
invoked on the receiving method handle objectref, the invokevirtual instruction throws ajava.lang.invoke.WrongMethodTypeException
.
Otherwise, if the resolved method is signature polymorphic and declared in the
java.lang.invoke.VarHandle
class, then any run-time exception that may arise from invocation of the invoker method handle can be thrown. No run-time exceptions are thrown from invocation of thevalueFromMethodName
,accessModeType
, andvarHandleExactInvoker
methods, exceptNullPointerException
if objectref isnull
.- Notes
The nargs argument values and objectref are not one-to-one with the first nargs+1 local variables. Argument values of types
long
anddouble
must be stored in two consecutive local variables, thus more than nargs local variables may be required to pass nargs argument values to the invoked method.It is possible that the symbolic reference of an invokevirtual instruction resolves to an interface method. In this case, it is possible that there is no overriding method in the class hierarchy, but that a non-
abstract
interface method matches the resolved method's descriptor. The selection logic matches such a method, using the same rules as for invokeinterface.
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:
A numeric constant of type
long
ordouble
.A symbolic reference to a dynamically-computed constant whose field descriptor is
J
(denotinglong
) orD
(denotingdouble
).
If the run-time constant pool entry is a numeric constant of type
int
orfloat
, then the value of that numeric constant is pushed onto the operand stack as anint
orfloat
, respectively.Otherwise, if the run-time constant pool entry is a string constant, that is, a
reference
to an instance of classString
, then value, areference
to that instance, is pushed onto the operand stack.Otherwise, if the run-time constant pool entry is a symbolic reference to a class or interface, then the named class or interface is resolved (5.4.3.1) and value, a
reference
to theClass
object representing that class or interface, is pushed onto the operand stack.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.
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:A numeric constant of type
long
ordouble
.A symbolic reference to a dynamically-computed constant whose field descriptor is
J
(denotinglong
) orD
(denotingdouble
).
If the run-time constant pool entry is a numeric constant of type
int
orfloat
, 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, 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 typefloat
taken from the float value set (2.3.2) because a constant of typefloat
in the constant pool (4.4.4) must be taken from the float value set.
ldc2_w
- Operation
Push
long
ordouble
from run-time constant pool (wide index)- Format
ldc2_w
indexbyte1
indexbyte2- Forms
ldc2_w = 20 (0x14)
- 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 in particular one of the following:A numeric constant of type
long
ordouble
.A symbolic reference to a dynamically-computed constant whose field descriptor is
J
(denotinglong
) orD
(denotingdouble
).
If the run-time constant pool entry is a numeric constant of type
long
ordouble
, then the value of that numeric constant is pushed onto the operand stack as along
ordouble
, respectively.Otherwise, the run-time constant pool entry is a symbolic reference to a dynamically-computed constant. The symbolic reference is resolved (5.4.3.6) and value, the result of resolution, is pushed onto the operand stack.
- Linking Exceptions
During resolution of a symbolic reference to a dynamically-computed constant, any of the exceptions pertaining to dynamically-computed constant resolution can be thrown.
- Notes
Only a wide-index version of the ldc2_w instruction exists; there is no ldc2 instruction that pushes a
long
ordouble
with a single-byte index.The ldc2_w instruction can only be used to push a value of typedouble
taken from the double value set (2.3.2) because a constant of typedouble
in the constant pool (4.4.5) must be taken from the double value set.
putfield
- Operation
Set field in object
- Format
putfield
indexbyte1
indexbyte2- Forms
putfield = 181 (0xb5)
- Operand Stack
..., objectref, value →
...
- 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 type of a value stored by a putfield instruction must be compatible with the descriptor of the referenced field (4.3.2). If the field descriptor type is
boolean
,byte
,char
,short
, orint
, then the value must be anint
. If the field descriptor type isfloat
,long
, ordouble
, then the value must be afloat
,long
, ordouble
, 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. If the field isfinal
, it must be declared in the current class, and the instruction must occur in an instance initialization method of the current class (2.9.1).The value and objectref are popped from the operand stack.
The objectref must be of type
reference
but not an array type.If the value is of type
int
and the field descriptor type isboolean
, then theint
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'.The referenced field in objectref is set to value'.Otherwise, the referenced field in objectref is set to value.
- 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, putfield throws anIncompatibleClassChangeError
.Otherwise, if the resolved field is
final
, it must be declared in the current class, and the instruction must occur in an instance initialization method of the current class. Otherwise, anIllegalAccessError
is thrown.- Run-time Exception
Otherwise, if objectref is
null
, the putfield instruction throws aNullPointerException
.
putstatic
- Operation
Set static field in class
- Format
putstatic
indexbyte1
indexbyte2- Forms
putstatic = 179 (0xb3)
- Operand Stack
..., value →
...
- 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 or interface in which the field is to be found. The referenced field is resolved (5.4.3.2).On successful resolution of the field, the class or interface that declared the resolved field is initialized if that class or interface has not already been initialized (5.5).
The type of a value stored by a putstatic instruction must be compatible with the descriptor of the referenced field (4.3.2). If the field descriptor type is
boolean
,byte
,char
,short
, orint
, then the value must be anint
. If the field descriptor type isfloat
,long
, ordouble
, then the value must be afloat
,long
, ordouble
, 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. If the field isfinal
, it must be declared in the current class or interface, and the instruction must occur in the class or interface initialization method of the current class or interface (2.9.2).The value is popped from the operand stack.
If the value is of type
int
and the field descriptor type isboolean
, then theint
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'.The referenced field in the class or interface is set to value'.Otherwise, The referenced field in the class or interface is set to value.
- Linking Exceptions
During resolution of the symbolic reference to the class or interface field, any of the exceptions pertaining to field resolution (5.4.3.2) can be thrown.
Otherwise, if the resolved field is not a
static
(class) field or an interface field, putstatic throws anIncompatibleClassChangeError
.Otherwise, if the resolved field is
final
, it must be declared in the current class or interface, and the instruction must occur in the class or interface initialization method of the current class or interface. Otherwise, anIllegalAccessError
is thrown.- Run-time Exception
Otherwise, if execution of this putstatic instruction causes initialization of the referenced class or interface, putstatic may throw an
Error
as detailed in 5.5.- Notes
A putstatic instruction may be used only to set the value of an interface field on the initialization of that field. Interface fields may be assigned to only once, on execution of an interface variable initialization expression when the interface is initialized (5.5, JLS §9.3.1).