Table of Contents
A Java Virtual Machine instruction consists of an opcode specifying the operation to be performed, followed by zero or more operands embodying values to be operated upon. This chapter gives details about the format of each Java Virtual Machine instruction and the operation it performs.
The description of each
instruction is always given in the context of Java Virtual Machine code that
satisfies the static and structural constraints of
§4 (The class
File Format). In the description of individual Java Virtual
Machine
instructions, we frequently state that some situation "must" or "must
not" be the case: "The value2 must be of type int
."
The
constraints of §4
(The class
File Format) guarantee that all such
expectations will in fact be met. If some constraint (a "must" or
"must not") in an instruction description is not satisfied at run
time, the behavior of the Java Virtual Machine is undefined.
The Java Virtual Machine checks that Java Virtual Machine
code satisfies the static and structural constraints at link time
using a class
file verifier (§4.10).
Thus, a
Java Virtual Machine will only attempt to execute code from valid class
files. Performing verification at link time is attractive in that the
checks are performed just once, substantially reducing the amount of
work that must be done at run time. Other implementation strategies
are possible, provided that they comply with The Java Language Specification, Java SE
8 Edition and
The Java Virtual Machine Specification, Java SE 8 Edition.
In addition to the opcodes of
the instructions specified later in this chapter, which are used in
class
files (§4 (The
class
File Format)), three opcodes are reserved
for internal use by a Java Virtual Machine implementation. If the instruction set of
the Java Virtual Machine is extended in the future, these reserved opcodes are
guaranteed not to be used.
Two of the reserved opcodes, numbers 254 (0xfe) and 255 (0xff), have the mnemonics impdep1 and impdep2, respectively. These instructions are intended to provide "back doors" or traps to implementation-specific functionality implemented in software and hardware, respectively. The third reserved opcode, number 202 (0xca), has the mnemonic breakpoint and is intended to be used by debuggers to implement breakpoints.
Although these opcodes have
been reserved, they may be used only inside a Java Virtual Machine
implementation. They cannot appear in valid class
files. Tools such
as debuggers or JIT code generators (§2.13)
that
might directly interact with Java Virtual Machine code that has been already loaded
and executed may encounter these opcodes. Such tools should attempt to
behave gracefully if they encounter any of these reserved
instructions.
A Java Virtual Machine implementation throws
an object that is an instance of a subclass of the class VirtualMachineError
when an
internal error or resource limitation prevents it from implementing
the semantics described in this chapter. This specification cannot
predict where internal errors or resource limitations may be
encountered and does not mandate precisely when they can be
reported. Thus, any of the VirtualMachineError
subclasses defined below may be
thrown at any time during the operation of the Java Virtual Machine:
InternalError
: An
internal error has occurred in the Java Virtual Machine implementation because of
a fault in the software implementing the virtual machine, a fault
in the underlying host system software, or a fault in the
hardware. This error is delivered asynchronously
(§2.10) when
it is detected and may occur at
any point in a program.
OutOfMemoryError
: The Java
Virtual Machine
implementation has run out of either virtual or physical memory,
and the automatic storage manager was unable to reclaim enough
memory to satisfy an object creation request.
StackOverflowError
: The
Java Virtual Machine
implementation has run out of stack space for a thread, typically
because the thread is doing an unbounded number of recursive
invocations as a result of a fault in the executing
program.
UnknownError
: An
exception or error has occurred, but the Java Virtual Machine implementation is
unable to report the actual exception or error.
Java Virtual Machine instructions are represented in this chapter by entries of the form shown below, in alphabetical order and each beginning on a new page.
A longer description detailing constraints on operand stack contents or constant pool entries, the operation performed, the type of the results, etc.
If any linking exceptions may be thrown by the execution of this instruction, they are set off one to a line, in the order in which they must be thrown.
If any run-time exceptions can be thrown by the execution of an instruction, they are set off one to a line, in the order in which they must be thrown.
Other than the linking and run-time exceptions, if
any, listed for an instruction, that instruction must not throw any
run-time exceptions except for instances of VirtualMachineError
or its
subclasses.
Each cell in the instruction
format diagram represents a single 8-bit byte. The instruction's
mnemonic is its name. Its opcode is its numeric
representation and is given in both decimal and hexadecimal
forms. Only the numeric representation is actually present in the
Java Virtual Machine code in a class
file.
Keep in mind that there are "operands" generated at compile time and embedded within Java Virtual Machine instructions, as well as "operands" calculated at run time and supplied on the operand stack. Although they are supplied from several different areas, all these operands represent the same thing: values to be operated upon by the Java Virtual Machine instruction being executed. By implicitly taking many of its operands from its operand stack, rather than representing them explicitly in its compiled code as additional operand bytes, register numbers, etc., the Java Virtual Machine's code stays compact.
Some instructions are presented as members of a family of related instructions sharing a single description, format, and operand stack diagram. As such, a family of instructions includes several opcodes and opcode mnemonics; only the family mnemonic appears in the instruction format diagram, and a separate forms line lists all member mnemonics and opcodes. For example, the Forms line for the lconst_<l> family of instructions, giving mnemonic and opcode information for the two instructions in that family (lconst_0 and lconst_1), is
In the description of the Java Virtual Machine instructions, the effect of an instruction's execution on the operand stack (§2.6.2) of the current frame (§2.6) is represented textually, with the stack growing from left to right and each value represented separately. Thus,
shows an operation that begins by having value2 on top of the operand stack with value1 just beneath it. As a result of the execution of the instruction, value1 and value2 are popped from the operand stack and replaced by result value, which has been calculated by the instruction. The remainder of the operand stack, represented by an ellipsis (...), is unaffected by the instruction's execution.
Values of types long
and
double
are represented by a single entry on the operand
stack.
In the First Edition of The Java®
Virtual Machine Specification, values on the
operand stack of types long
and double
were each
represented in
the stack diagram by two entries.
The arrayref must be of type reference
and must refer to an array
whose components are of type reference
. The index
must be of type
int
. Both arrayref and index are popped from the operand
stack. The reference
value in
the component of the array at index
is retrieved and pushed onto the operand stack.
The arrayref must be of type reference
and must refer to an array
whose components are of type reference
. The index
must be of type
int
and value must be of type reference
.
The arrayref, index,
and value are popped from the operand stack. The reference
value
is stored as the component of the array at index.
At run time, the type of value must be compatible with the type of the components of the array referenced by arrayref. Specifically, assignment of a value of reference type S (source) to an array component of reference type T (target) is allowed only if:
If arrayref is null
, aastore throws a NullPointerException
.
Otherwise, if index is not within the bounds of the array
referenced by arrayref, the aastore
instruction throws an
ArrayIndexOutOfBoundsException
.
Otherwise, if arrayref is not null
and the actual type of
value is not assignment compatible (JLS §5.2) with the
actual
type of the components of the array, aastore throws an
ArrayStoreException
.
The index is an unsigned byte that must be an index into the
local variable array of the current frame
(§2.6). The local
variable at index must
contain a reference
. The objectref in the local variable at index
is pushed onto the operand stack.
The aload instruction cannot be used to load a value of type
returnAddress
from a local variable onto the operand stack. This
asymmetry with the astore instruction
(§astore)
is intentional.
The aload opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
The <n> must be an index into the local variable array
of the current frame (§2.6). The local
variable at <n> must contain a reference
.
The objectref
in the local variable at <n> is pushed onto the operand
stack.
An aload_<n> instruction cannot be used to load a value
of type
returnAddress
from a local variable onto the operand stack. This
asymmetry with the corresponding astore_<n> instruction
(§astore_<n>) is intentional.
Each of the aload_<n> instructions is the same as aload with an index of <n>, except that the operand <n> is implicit.
The count must be of type int
.
It is popped off the operand
stack. The count represents the number of components of the
array to be created. The unsigned indexbyte1 and indexbyte2
are used to construct an index into the run-time constant pool of
the current class (§2.6), where the value of
the index is (indexbyte1 <<
8) | indexbyte2. The
run-time constant pool item at that index must be a symbolic
reference to a class, array, or interface type. The named class,
array, or interface type is resolved
(§<IP_ADDRESS>). A new array with
components of
that type, of length count, is allocated from the
garbage-collected heap, and a reference
arrayref
to this new array
object is pushed onto the operand stack. All components of the new
array are initialized to null
, the default value for reference
types
(§2.4).
During resolution of the symbolic reference to the class, array, or interface type, any of the exceptions documented in §<IP_ADDRESS> can be thrown.
The objectref must be of type reference
and must refer to an object
of a type that is assignment compatible (JLS §5.2) with the type
represented by the return descriptor
(§4.3.3) of the current method. If the
current method is a synchronized
method, the monitor entered or
reentered on invocation of the method is updated and possibly
exited as if by execution of a monitorexit instruction
(§monitorexit) in the current thread. If
no exception is thrown, objectref is popped from the operand
stack of the current frame (§2.6)
and 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 reinstates the frame of the invoker and returns control to the invoker.
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, areturn throws an
IllegalMonitorStateException
. This can happen, for example, if a
synchronized
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 areturn throws an
IllegalMonitorStateException
.
The index is an unsigned byte that must be an index into the
local variable array of the current frame
(§2.6). The objectref on the top of the
operand stack must be of type returnAddress
or of type reference
. It
is popped from the operand stack, and the value of the local
variable at index is set to objectref.
The astore instruction is used with an objectref of type
returnAddress
when implementing the finally
clause of the
Java programming language (§3.13).
The aload instruction (§aload) cannot
be used to load a value of type returnAddress
from a local
variable onto the operand stack. This asymmetry with the astore
instruction is intentional.
The astore opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
The <n> must be an index into the local variable array
of the current frame (§2.6). The objectref
on the top of the operand stack must be of type returnAddress
or
of type reference
. It is popped from the operand stack, and the value
of the local variable at <n> is set to
objectref.
An astore_<n> instruction is used with an objectref of type
returnAddress
when implementing the finally
clauses of the
Java programming language (§3.13).
An aload_<n> instruction (§aload_<n>)
cannot be used to load a value of type returnAddress
from a
local variable onto the operand stack. This asymmetry with the
corresponding astore_<n> instruction is intentional.
Each of the astore_<n> instructions is the same as astore with an index of <n>, except that the operand <n> is implicit.
The objectref must be of type reference
and must refer to an object
that is an instance of class Throwable
or of a subclass of
Throwable
. It is popped from the operand stack. The objectref
is then thrown by searching the current method
(§2.6) for the first
exception handler that
matches the class of objectref, as given by the algorithm in
§2.10.
If an exception handler that matches objectref is found, it
contains the location of the code intended to handle this
exception. The pc
register is reset to that location, the
operand stack of the current frame is cleared, objectref is
pushed back onto the operand stack, and execution
continues.
If no matching exception handler is found in the current frame,
that frame is popped. If the current frame represents an
invocation of a synchronized
method, the monitor entered or
reentered on invocation of the method is exited as if by execution
of a monitorexit instruction
(§monitorexit). Finally, the frame of
its invoker is reinstated, if such a frame exists, and the
objectref is rethrown. If no such frame exists, the current
thread exits.
If objectref is null
, athrow throws a NullPointerException
instead of
objectref.
Otherwise, if the Java Virtual Machine implementation does not enforce the rules
on structured locking described in §2.11.10,
then if the method of the current frame is a synchronized
method
and the current thread is not the owner of the monitor entered or
reentered on invocation of the method, athrow throws an
IllegalMonitorStateException
instead of the object previously
being thrown. This can happen, for example, if an abruptly
completing synchronized
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 athrow throws an
IllegalMonitorStateException
instead of the object previously
being thrown.
The operand stack diagram for the athrow instruction may be misleading: If a handler for this exception is matched in the current method, the athrow instruction discards all the values on the operand stack, then pushes the thrown object onto the operand stack. However, if no handler is matched in the current method and the exception is thrown farther up the method invocation chain, then the operand stack of the method (if any) that handles the exception is cleared and objectref is pushed onto that empty operand stack. All intervening frames from the method that threw the exception up to, but not including, the method that handles the exception are discarded.
The arrayref must be of type reference
and must refer to an array
whose components are of type byte
or of type boolean
.
The
index must be of type int
. Both
arrayref and index are
popped from the operand stack. The byte
value
in the component
of the array at index is retrieved, sign-extended to an int
value, and pushed onto the top of the operand stack.
If arrayref is null
, baload throws a NullPointerException
.
Otherwise, if index is not within the bounds of the array
referenced by arrayref, the baload instruction throws an
ArrayIndexOutOfBoundsException
.
The baload instruction is used to load values from both byte
and boolean
arrays. In Oracle's Java Virtual Machine implementation,
boolean
arrays - that is, arrays of type T_BOOLEAN
(§2.2, §newarray)
- are implemented as arrays of 8-bit values. Other implementations
may implement packed boolean
arrays; the baload
instruction of
such implementations must be used to access those arrays.
The arrayref must be of type reference
and must refer to an array
whose components are of type byte
or of type boolean
.
The
index and the value
must both be of type int
. The
arrayref, index, and
value are popped from the operand
stack. The int
value is
truncated to a byte
and stored as
the component of the array indexed by index.
If arrayref is null
, bastore throws a NullPointerException
.
Otherwise, if index is not within the bounds of the array
referenced by arrayref, the bastore
instruction throws an
ArrayIndexOutOfBoundsException
.
The bastore instruction is used to store values into both
byte
and boolean
arrays. In Oracle's Java Virtual Machine implementation,
boolean
arrays - that is, arrays of type T_BOOLEAN
(§2.2, §newarray)
- are implemented as arrays of 8-bit values. Other implementations
may implement packed boolean
arrays; in such implementations the
bastore instruction must be able to store boolean
values into
packed boolean
arrays as well as byte
values into byte
arrays.
The arrayref must be of type reference
and must refer to an array
whose components are of type char
. The index must be of type
int
. Both arrayref and index are popped from the operand
stack. The component of the array at index is retrieved and
zero-extended to an int
value.
That value is pushed onto the
operand stack.
The arrayref must be of type reference
and must refer to an array
whose components are of type char
. The index and the value
must both be of type int
. The arrayref,
index, and value
are popped from the operand stack. The int
value
is truncated
to a char
and stored as the component of the array indexed by
index.
The objectref must be of type reference
. The unsigned indexbyte1
and indexbyte2 are used to construct an index into the
run-time
constant pool of the current class (§2.6),
where the value of the index is (indexbyte1 <<
8) |
indexbyte2. The run-time constant pool item at the index must
be
a symbolic reference to a class, array, or interface type.
If objectref is null
, then the
operand stack is
unchanged.
Otherwise, the named class, array, or interface type is resolved
(§<IP_ADDRESS>). If objectref can be cast to
the resolved class, array, or interface type, the operand stack is
unchanged; otherwise, the checkcast instruction throws a
ClassCastException
.
The following rules are used to determine whether an objectref
that is not null
can be cast to the resolved type: if S is the
class of the object referred to by objectref and T is the
resolved class, array, or interface type, checkcast
determines
whether objectref can be cast to type T as follows:
During resolution of the symbolic reference to the class, array, or interface type, any of the exceptions documented in §<IP_ADDRESS> can be thrown.
Otherwise, if objectref cannot be cast to the resolved class,
array, or interface type, the checkcast instruction throws a
ClassCastException
.
The checkcast instruction is very similar to the instanceof
instruction (§instanceof). It differs in
its treatment of null
, its behavior when its test fails
(checkcast throws an exception, instanceof
pushes a result
code), and its effect on the operand stack.
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'. Then value' is
converted to a float
result using
IEEE 754 round to nearest mode. 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' too small to be represented as a float
is
converted to a zero of the same sign; a finite value' too
large
to be represented as a float
is converted to an infinity of the
same sign. A double
NaN is converted to a float
NaN.
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'. Then value' is
converted to an int
. The result is
pushed onto the operand stack:
If the value' is NaN, the result
of the conversion is an
int
0.
Otherwise, if the value' is not an infinity, it
is rounded
to an integer value V, rounding towards zero using IEEE 754
round towards zero mode. If this integer value V can be
represented as an int
, then the result is the int
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
, 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
.
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'. Then value' is
converted to a long
. The result
is
pushed onto the operand stack:
If the value' is NaN, the result
of the conversion is a
long
0.
Otherwise, if the value' is not an infinity, it
is rounded
to an integer value V, rounding towards zero using IEEE 754
round towards zero mode. If this integer value V can be
represented as a long
, then the result
is the long
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 long
, 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 long
.
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'. The double
result is value1' +
value2'. The
result is pushed onto the operand stack.
The result of a dadd instruction is governed by the rules of IEEE arithmetic:
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 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 IEEE 754 round to nearest
mode. 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 a double
, we say the operation underflows;
the result is then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. Despite the fact that overflow, underflow, or loss of precision may occur, execution of a dadd instruction never throws a run-time exception.
The arrayref must be of type reference
and must refer to an array
whose components are of type double
. The index
must be of type
int
, and value must be of type double
. The
arrayref,
index, and value are
popped from the operand stack. The
double
value undergoes value set
conversion
(§2.8.3), resulting in value', which is
stored as the component of the array indexed by index.
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' is greater than value2', the int
value 1 is
pushed onto the operand stack.
Otherwise, if value1' is equal to value2', the int
value
0 is pushed onto the operand stack.
Otherwise, if value1' is less than value2', the int
value -1 is pushed onto the operand stack.
Otherwise, at least one of value1' or value2' is NaN. The
dcmpg instruction pushes the int
value 1 onto the operand
stack and the dcmpl instruction pushes the int
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.
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, any double
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.
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'. The double
result is value1' /
value2'. The
result is pushed onto the operand stack.
The result of a ddiv instruction is governed by the rules of IEEE arithmetic:
If neither value1' nor 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 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 IEEE 754 round to nearest mode. 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 a double
, we say the operation underflows; the result is
then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. 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.
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 local
variable at index must
contain a double
. The value of
the local variable at index
is pushed onto the operand stack.
The dload opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
Both <n> and <n>+1 must be indices into the
local variable array of the current frame
(§2.6). The local
variable at <n>
must contain a double
. The value
of the local variable at
<n> is pushed onto the operand stack.
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'. The double
result is
value1' * value2'. The
result is pushed onto the operand stack.
The result of a dmul instruction is governed by the rules of IEEE arithmetic:
If neither value1' nor 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 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 IEEE 754 round to nearest mode. 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 a double
, we say the operation underflows; the result is
then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. Despite the fact that overflow, underflow, or loss of precision may occur, execution of a dmul instruction never throws a run-time exception.
The value must be of type double
. It is popped from the operand
stack and undergoes value set conversion
(§2.8.3), resulting in value'. The
double
result is the arithmetic
negation of value'. The
result is pushed onto the operand stack.
For double
values, negation is not the same as subtraction from
zero. If x
is +0.0
,
then 0.0-x
equals +0.0
,
but -x
equals -0.0
. Unary
minus merely inverts the sign of a double
.
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'. The result is
calculated and pushed onto the operand
stack as a double
.
The result of a drem instruction is not the same as that of
the
so-called remainder operation defined by IEEE 754. 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 Java Virtual Machine integer remainder
instructions (irem and lrem); this may be compared with the C
library function fmod
.
The result of a drem instruction is governed by these rules:
If neither value1' nor 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' and a divisor value2' is defined by the mathematical relation result = value1' - (value2' * q), where q is an integer that is negative only if value1' / value2' is negative, and positive only if value1' / value2' is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of value1' and 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.
The current method must have return type double
. The value
must be of type double
. If the current method is a
synchronized
method, the monitor entered or reentered on
invocation of the method is updated and possibly exited as if by
execution of a monitorexit instruction
(§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'. The 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.
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 an
IllegalMonitorStateException
. This can happen, for example, if a
synchronized
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
.
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 to value'.
The dstore opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
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 to
value'.
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'. The double
result is value1' -
value2'. The
result is pushed onto the operand stack.
For double
subtraction, it is always the case
that a-b
produces the same result
as a+(-b)
. However, for the dsub
instruction,
subtraction from zero is not the same as negation, because
if x
is +0.0
,
then 0.0-x
equals +0.0
,
but -x
equals -0.0
.
The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. Despite the fact that overflow, underflow, or loss of precision may occur, execution of a dsub instruction never throws a run-time exception.
Duplicate the top value on the operand stack and push the duplicated value onto the operand stack.
The dup instruction must not be used unless value is a value of a category 1 computational type (§2.11.1).
Duplicate the top value on the operand stack and insert the duplicated value two values down in the operand stack.
The dup_x1 instruction must not be used unless both value1 and value2 are values of a category 1 computational type (§2.11.1).
Duplicate the top one or two operand stack values and insert two, three, or four values down
..., value4, value3, value2, value1 →
..., value2, value1, value4, value3, value2, value1
where value1, value2, value3, and value4 are all values of a category 1 computational type (§2.11.1).
..., value1, value3, value2, value1
where value1 is a value of a category 2 computational type and value2 and value3 are both values of a category 1 computational type (§2.11.1).
..., value2, value1, value3, value2, value1
where value1 and value2 are both values of a category 1 computational type and value3 is a value of a category 2 computational type (§2.11.1).
where value1 and value2 are both values of a category 2 computational type (§2.11.1).
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'. Then value' is
converted to a double
result.
This
result is pushed onto the operand stack.
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 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'. Then value' is
converted to an int
result. This
result is pushed onto the operand stack:
If the value' is NaN, the result
of the conversion is an
int
0.
Otherwise, if the value' is not an infinity, it
is rounded
to an integer value V, rounding towards zero using IEEE 754
round towards zero mode. If this integer value V can be
represented as an int
, then the result
is the int
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
, 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
.
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'. Then value' is
converted to a long
result. This
result is pushed onto the operand stack:
If the value' is NaN, the result of the
conversion is a
long
0.
Otherwise, if the value' is not an infinity, it
is rounded
to an integer value V, rounding towards zero using IEEE 754
round towards zero mode. If this integer value V can be
represented as a long
, then the result
is the long
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 long
,
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 long
.
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'. The float
result is value1' +
value2'. The
result is pushed onto the operand stack.
The result of an fadd instruction is governed by the rules of IEEE arithmetic:
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 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 IEEE 754 round to nearest
mode. 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 a float
, we say the operation underflows; the
result is then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. Despite the fact that overflow, underflow, or loss of precision may occur, execution of an fadd instruction never throws a run-time exception.
The arrayref must be of type reference
and must refer to an array
whose components are of type float
. The index
must be of type
int
, and the value must be of
type float
. The arrayref,
index, and value are
popped from the operand stack. The
float
value undergoes value set
conversion
(§2.8.3), resulting in value', and
value' is stored as the component of the array indexed by
index.
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'. A floating-point comparison is performed:
If value1' is greater than value2', the int
value 1 is
pushed onto the operand stack.
Otherwise, if value1' is equal to value2', the int
value
0 is pushed onto the operand stack.
Otherwise, if value1' is less than value2', the int
value -1 is pushed onto the operand stack.
Otherwise, at least one of value1' or value2' is NaN. The
fcmpg instruction pushes the int
value 1 onto the operand
stack and the fcmpl instruction pushes the int
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.
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, any float
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.
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'. The float
result is value1' /
value2'. The
result is pushed onto the operand stack.
The result of an fdiv instruction is governed by the rules of IEEE arithmetic:
If neither value1' nor 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 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 IEEE 754 round to nearest mode. 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 a float
, we say the operation underflows; the result is
then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. 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.
The index is an unsigned byte that must be an index into the
local variable array of the current frame
(§2.6). The local
variable at index must
contain a float
. The value of
the local variable at index is
pushed onto the operand stack.
The fload opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
The <n> must be an index into the local variable array
of the current frame (§2.6). The local
variable at <n> must contain a float
.
The value of
the local variable at <n> is pushed onto the operand
stack.
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'. The float
result is value1' *
value2'. The
result is pushed onto the operand stack.
The result of an fmul instruction is governed by the rules of IEEE arithmetic:
If neither value1' nor 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 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 IEEE 754 round to nearest mode. 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 a float
, we say the operation underflows; the result is
then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. Despite the fact that overflow, underflow, or loss of precision may occur, execution of an fmul instruction never throws a run-time exception.
The value must be of type float
.
It is popped from the operand
stack and undergoes value set conversion
(§2.8.3), resulting in value'. The float
result is the arithmetic negation of value'. This result
is
pushed onto the operand stack.
For float
values, negation is not the same as subtraction from
zero. If x
is +0.0
,
then 0.0-x
equals +0.0
,
but -x
equals -0.0
. Unary
minus merely inverts the sign of a float
.
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'. The result is
calculated and pushed onto the operand
stack as a float
.
The result of an frem
instruction is not the same as that of
the so-called remainder operation defined by IEEE 754. 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 Java Virtual Machine integer remainder
instructions (irem and lrem); this may be compared with the C
library function fmod
.
The result of an frem instruction is governed by these rules:
If neither value1' nor 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' and a divisor value2' is defined by the mathematical relation result = value1' - (value2' * q), where q is an integer that is negative only if value1' / value2' is negative and positive only if value1' / value2' is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of value1' and 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.
The current method must have return type float
. The value must
be of type float
. If the current method is a synchronized
method, the monitor entered or reentered on invocation of the
method is updated and possibly exited as if by execution of a
monitorexit instruction (§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'. The
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.
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 an
IllegalMonitorStateException
. This can happen, for example, if a
synchronized
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
.
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 to value'.
The fstore opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
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 to value'.
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'. The float
result is value1' -
value2'. The
result is pushed onto the operand stack.
For float
subtraction, it is always the case
that a-b
produces the same result
as a+(-b)
. However, for the fsub
instruction,
subtraction from zero is not the same as negation, because
if x
is +0.0
,
then 0.0-x
equals +0.0
,
but -x
equals -0.0
.
The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. Despite the fact that overflow, underflow, or loss of precision may occur, execution of an fsub instruction never throws a run-time exception.
The objectref, which must be of type reference
,
is popped from the
operand stack. The unsigned indexbyte1 and indexbyte2 are used
to construct an index into the run-time constant pool of the
current class (§2.6),
where the value of the
index is (indexbyte1 <<
8)
| indexbyte2. The run-time
constant pool item at that 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 (§<IP_ADDRESS>).
The value of the
referenced field in objectref is fetched and pushed onto the
operand stack.
The type of objectref must not be an array type. If the field
is
protected
, and it is a member of a superclass of the current
class, and the field is not declared in the same run-time package
(§5.3)
as the current class, then the class
of objectref must be either the current class or a subclass
of
the current class.
During resolution of the symbolic reference to the field, any of the errors pertaining to field resolution (§<IP_ADDRESS>) can be thrown.
Otherwise, if the resolved field is a static
field, getfield
throws an IncompatibleClassChangeError
.
The getfield instruction cannot be used to access the length
field of an array. The arraylength instruction
(§arraylength) is used instead.
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 item at that 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 (§<IP_ADDRESS>).
On successful resolution of the field, the class or interface that declared the resolved field is initialized (§5.5) if that class or interface has not already been initialized.
The value of the class or interface field is fetched and pushed onto the operand stack.
During resolution of the symbolic reference to the class or interface field, any of the exceptions pertaining to field resolution (§<IP_ADDRESS>) can be thrown.
Otherwise, if the resolved field is not a static
(class) field
or an interface field, getstatic throws an IncompatibleClassChangeError
.
Otherwise, if execution of this getstatic instruction causes
initialization of the referenced class or interface, getstatic
may throw an Error
as detailed in §5.5.
The unsigned bytes branchbyte1 and branchbyte2 are used to
construct a signed 16-bit branchoffset, where branchoffset is
(branchbyte1 <<
8) | branchbyte2. Execution proceeds at
that offset from the address of the opcode of this goto
instruction. The target address must be that of an opcode of an
instruction within the method that contains this goto
instruction.
The unsigned bytes branchbyte1, branchbyte2,
branchbyte3,
and branchbyte4 are used to construct a signed 32-bit
branchoffset, where branchoffset is (branchbyte1 <<
24) | (branchbyte2 <<
16)
| (branchbyte3 <<
8) |
branchbyte4. Execution proceeds at that offset from the
address
of the opcode of this goto_w instruction. The target address
must be that of an opcode of an instruction within the method that
contains this goto_w instruction.
Although the goto_w instruction takes a 4-byte branch offset, other factors limit the size of a method to 65535 bytes (§4.11). This limit may be raised in a future release of the Java Virtual Machine.
Both value1 and value2
must be of type int
. The values are
popped from the operand stack. The int
result
is value1 +
value2. The result is
pushed onto the operand stack.
The result is the 32 low-order bits of the true mathematical
result in a sufficiently wide two's-complement format, represented
as a value of type int
. If overflow occurs, then the sign of the
result may not be the same as the sign of the mathematical sum of
the two values.
Despite the fact that overflow may occur, execution of an iadd instruction never throws a run-time exception.
iconst_m1 = 2 (0x2)
iconst_0 = 3 (0x3)
iconst_1 = 4 (0x4)
iconst_2 = 5 (0x5)
iconst_3 = 6 (0x6)
iconst_4 = 7 (0x7)
iconst_5 = 8 (0x8)
Both value1 and value2
must be of type int
. The values are
popped from the operand stack. The int
result
is the value of
the Java programming language expression value1 / value2. The result
is
pushed onto the operand stack.
An int
division rounds towards 0; that is, the quotient produced
for int
values in n/d is an int
value q whose
magnitude is as large as possible while satisfying |d ⋅
q| ≤ |n|. Moreover, q is
positive when |n|
≥ |d| and n and d have the
same sign, but
q is negative when |n|
≥ |d| and n and
d have opposite signs.
There is one special case that does not satisfy this rule: if the
dividend is the negative integer of largest possible magnitude for
the int
type, and the divisor is -1, then overflow occurs, and
the result is equal to the dividend. Despite the overflow, no
exception is thrown in this case.
Both value1 and value2
must be of type reference
. They are both
popped from the operand stack and compared. The results of the
comparison are as follows:
If the comparison succeeds, the unsigned branchbyte1 and
branchbyte2 are used to construct a signed 16-bit offset,
where
the offset is calculated to be (branchbyte1 <<
8) |
branchbyte2. Execution then proceeds at that offset from the
address of the opcode of this if_acmp<cond>
instruction. The
target address must be that of an opcode of an instruction within
the method that contains this if_acmp<cond>
instruction.
Otherwise, if the comparison fails, execution proceeds at the address of the instruction following this if_acmp<cond> instruction.
if_icmpeq = 159 (0x9f)
if_icmpne = 160 (0xa0)
if_icmplt = 161 (0xa1)
if_icmpge = 162 (0xa2)
if_icmpgt = 163 (0xa3)
if_icmple = 164 (0xa4)
Both value1 and value2
must be of type int
. They are both
popped from the operand stack and compared. All comparisons are
signed. The results of the comparison are as follows:
If the comparison succeeds, the unsigned branchbyte1 and
branchbyte2 are used to construct a signed 16-bit offset,
where
the offset is calculated to be (branchbyte1 <<
8) |
branchbyte2. Execution then proceeds at that offset from the
address of the opcode of this if_icmp<cond>
instruction. The
target address must be that of an opcode of an instruction within
the method that contains this if_icmp<cond>
instruction.
Otherwise, execution proceeds at the address of the instruction following this if_icmp<cond> instruction.
ifeq = 153 (0x99)
ifne = 154 (0x9a)
iflt = 155 (0x9b)
ifge = 156 (0x9c)
ifgt = 157 (0x9d)
ifle = 158 (0x9e)
The value must be of type int
.
It is popped from the operand
stack and compared against zero. All comparisons are signed. The
results of the comparisons are as follows:
If the comparison succeeds, the unsigned branchbyte1 and
branchbyte2 are used to construct a signed 16-bit offset,
where
the offset is calculated to be (branchbyte1 <<
8) |
branchbyte2. Execution then proceeds at that offset from the
address of the opcode of this if<cond> instruction. The
target
address must be that of an opcode of an instruction within the
method that contains this if<cond> instruction.
Otherwise, execution proceeds at the address of the instruction following this if<cond> instruction.
The value must be of type reference
. It is popped from the operand
stack. If value is not null
, the
unsigned branchbyte1 and
branchbyte2 are used to construct a signed 16-bit offset,
where
the offset is calculated to be (branchbyte1 <<
8) |
branchbyte2. Execution then proceeds at that offset from the
address of the opcode of this ifnonnull instruction. The
target
address must be that of an opcode of an instruction within the
method that contains this ifnonnull instruction.
Otherwise, execution proceeds at the address of the instruction following this ifnonnull instruction.
The value must of type reference
.
It is popped from the operand
stack. If value is null
, the
unsigned branchbyte1 and
branchbyte2 are used to construct a signed 16-bit offset,
where
the offset is calculated to be (branchbyte1 <<
8) |
branchbyte2. Execution then proceeds at that offset from the
address of the opcode of this ifnull instruction. The target
address must be that of an opcode of an instruction within the
method that contains this ifnull instruction.
Otherwise, execution proceeds at the address of the instruction following this ifnull instruction.
The index is an unsigned byte that must be an index into the
local variable array of the current frame
(§2.6). The const is an
immediate signed byte. The local variable at index must
contain
an int
. The value const is first
sign-extended to an int
, and then the local variable at index
is incremented by that amount.
The iinc opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index and to increment it by a two-byte immediate signed value.
The index is an unsigned byte that must be an index into the
local variable array of the current frame
(§2.6). The local
variable at index must
contain an int
. The value of the
local variable at index is
pushed onto the operand stack.
The iload opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
The <n> must be an index into the local variable array
of the current frame (§2.6). The local
variable at <n> must contain an int
.
The value of
the local variable at <n> is pushed onto the operand
stack.
Both value1 and value2
must be of type int
. The values are
popped from the operand stack. The int
result
is value1 *
value2. The result is
pushed onto the operand stack.
The result is the 32 low-order bits of the true mathematical
result in a sufficiently wide two's-complement format, represented
as a value of type int
. If overflow occurs, then the sign of the
result may not be the same as the sign of the
mathematical multiplication of the two values.
Despite the fact that overflow may occur, execution of an imul instruction never throws a run-time exception.
The value must be of type int
.
It is popped from the operand
stack. The int
result is the
arithmetic negation of value,
-value. The result is
pushed onto the operand stack.
For int
values, negation is the same as subtraction from
zero. Because the Java Virtual Machine uses two's-complement representation for
integers and the range of two's-complement values is not
symmetric, the negation of the maximum negative int
results in
that same maximum negative number. Despite the fact that overflow
has occurred, no exception is thrown.
The objectref, which must be of type reference
,
is popped from the
operand stack. The unsigned indexbyte1 and indexbyte2 are used
to construct an index into the run-time constant pool of the
current class (§2.6),
where the value of the
index is (indexbyte1 <<
8)
| indexbyte2. The run-time
constant pool item at the index must be a symbolic reference to a
class, array, or interface type.
If objectref is null
, the instanceof instruction pushes an
int
result of 0 as an int
on the operand stack.
Otherwise, the named class, array, or interface type is resolved
(§<IP_ADDRESS>). If objectref is an instance of
the resolved class or array or implements the resolved interface,
the instanceof instruction pushes an int
result of 1 as an
int
on the operand stack; otherwise, it pushes an int
result
of 0.
The following rules are used to determine whether an objectref
that is not null
is an instance of the resolved type: If S is
the class of the object referred to by objectref and T is the
resolved class, array, or interface type, instanceof
determines
whether objectref is an instance of T as follows:
During resolution of the symbolic reference to the class, array, or interface type, any of the exceptions documented in §<IP_ADDRESS> can be thrown.
The instanceof instruction is very similar to the checkcast
instruction (§checkcast). It differs in
its treatment of null
, its behavior when its test fails
(checkcast throws an exception, instanceof
pushes a result
code), and its effect on the operand stack.
Each specific lexical occurrence of an invokedynamic instruction is called a dynamic call site.
First, 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 item at that index must be a symbolic reference to a call
site specifier (§5.1). The values of the
third and fourth operand bytes must always be zero.
The call site specifier is resolved (§<IP_ADDRESS>)
for this specific dynamic call site to obtain
a reference
to a java.lang.invoke.MethodHandle
instance that will serve as the
bootstrap method, a reference
to a java.lang.invoke.MethodType
instance, and reference
s
to static arguments.
Next, as part of the continuing resolution of the call site specifier, the bootstrap method is invoked as if by execution of an invokevirtual instruction (§invokevirtual) that contains a run-time constant pool index to a symbolic reference R where:
R is a symbolic reference to a method of a class (§5.1);
for the symbolic reference to the class in which the method is
to be found, R specifies java.lang.invoke.MethodHandle
;
for the descriptor of the method, R specifies a return type
of java.lang.invoke.CallSite
and parameter types derived
from the items
pushed on the operand stack.
The first three parameter types are java.lang.invoke.MethodHandles.Lookup
,
String
, and java.lang.invoke.MethodType
,
in that order. If the call site
specifier has any static arguments, then a parameter type for
each argument is appended to the parameter types of the method
descriptor in the order that the arguments were pushed on to
the operand stack. These parameter types may be Class
,
java.lang.invoke.MethodHandle
, java.lang.invoke.MethodType
,
String
, int
, long
,
float
, or double
.
and where it is as if the following items were pushed, in order, on the operand stack:
the reference
to the java.lang.invoke.MethodHandle
object for the bootstrap
method;
a reference
to a java.lang.invoke.MethodHandles.Lookup
object for the class in
which this dynamic call site occurs;
a reference
to the String
for
the method name in the call site
specifier;
the reference
to the java.lang.invoke.MethodType
object obtained for the method
descriptor in the call site specifier;
reference
s to classes, method types, method handles, and
string
literals denoted as static arguments in the call site
specifier, and numeric values (§2.3.1,
§2.3.2)
denoted as static arguments in
the call site specifier, in the order in which they appear in
the call site specifier. (That is, no boxing occurs for
primitive values.)
The symbolic reference R describes a method which is signature
polymorphic (§2.9). Due to the operation of
invokevirtual on a signature polymorphic method called invoke
,
the type descriptor of the receiving method handle (representing
the bootstrap method) need not be semantically equal to the method
descriptor specified by R. For example, the first parameter type
specified by R could be Object
instead of
java.lang.invoke.MethodHandles.Lookup
, and the return type specified by
R could
be Object
instead of java.lang.invoke.CallSite
. As long as the bootstrap method
can be invoked by the invoke
method without a java.lang.invoke.WrongMethodTypeException
being
thrown, the type descriptor of the method handle which represents
the bootstrap method is arbitrary.
If the bootstrap method is a variable arity method, then some or all of the arguments on the operand stack specified above may be collected into a trailing array parameter.
The invocation of a bootstrap method occurs within a thread that is attempting resolution of the symbolic reference to the call site specifier of this dynamic call site. If there are several such threads, the bootstrap method may be invoked in several threads concurrently. Therefore, bootstrap methods which access global application data must take the usual precautions against race conditions.
The result returned by the bootstrap method must be a reference
to an
object whose class is java.lang.invoke.CallSite
or a subclass of java.lang.invoke.CallSite
. This
object is known as the call site object. The
reference
is popped from the operand stack used as if in the execution
of an invokevirtual instruction.
If several threads simultaneously execute the bootstrap method for the same dynamic call site, the Java Virtual Machine must choose one returned call site object and install it visibly to all threads. Any other bootstrap methods executing for the dynamic call site are allowed to complete, but their results are ignored, and the threads' execution of the dynamic call site proceeds with the chosen call site object.
The call site object has a type descriptor (an instance of
java.lang.invoke.MethodType
) which must be semantically equal to the
java.lang.invoke.MethodType
object obtained for the method descriptor in the call site
specifier.
The result of successful call site specifier resolution is a call site object which is permanently bound to the dynamic call site.
The method handle represented by the target of the bound call site object is invoked. The invocation occurs as if by execution of an invokevirtual instruction (§invokevirtual) that indicates a run-time constant pool index to a symbolic reference to a method (§5.1) with the following properties:
The operand stack will be interpreted as containing a reference
to the
target of the call site object, followed by nargs argument
values, where the number, type, and order of the values must be
consistent with the method descriptor in the call site
specifier.
If resolution of the symbolic reference to the call site specifier
throws an exception E, the invokedynamic instruction throws a
BootstrapMethodError
that wraps E.
Otherwise, during the continuing resolution of the call site
specifier, if invocation of the bootstrap method completes
abruptly (§2.6.5) because of a
throw of
exception E, the invokedynamic
instruction throws a BootstrapMethodError
that
wraps E. (This can occur if the bootstrap method has the wrong
arity, parameter type, or return type, causing java.lang.invoke.MethodHandle
.
invoke
to throw java.lang.invoke.WrongMethodTypeException
.)
Otherwise, during the continuing resolution of the call site
specifier, if the result from the bootstrap method invocation is
not a reference
to an instance of java.lang.invoke.CallSite
,
the invokedynamic
instruction throws a BootstrapMethodError
.
Otherwise, during the continuing resolution of the call site
specifier, if the type descriptor of the target of the call site
object is not semantically equal to the method descriptor in the
call site specifier, the invokedynamic instruction throws a
BootstrapMethodError
.
If this specific dynamic call site completed resolution of its
call site specifier, it implies that a non-null
reference
to an
instance of java.lang.invoke.CallSite
is bound to this dynamic call
site. Therefore, the operand stack item which represents a reference
to the target of the call site object is never null
. Similarly,
it implies that the method descriptor in the call site specifier
is semantically equal to the type descriptor of
the method handle to be invoked as if by
execution of an invokevirtual instruction. Together, these
invariants mean that an invokedynamic instruction which is
bound
to a call site object never throws a NullPointerException
or a java.lang.invoke.WrongMethodTypeException
.
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 item at that 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 (§<IP_ADDRESS>).
The resolved interface method must not be an instance initialization method, or the class or interface initialization method (§2.9).
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. 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 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 there is exactly one maximally-specific method
(§<IP_ADDRESS>) 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.
If the method is synchronized
, the monitor associated with
objectref is entered or reentered as if by execution of a
monitorenter instruction
(§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
type long
or double
, 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 Machine pc
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:
If the native
method is synchronized
, the monitor
associated with objectref is updated and possibly
exited as
if by execution of a monitorexit instruction
(§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 the
native
method and pushed onto the operand stack.
During resolution of the symbolic reference to the interface method, any of the exceptions pertaining to interface method resolution (§<IP_ADDRESS>) can be thrown.
Otherwise, if the resolved method is static
or private
,
the
invokeinterface instruction throws an IncompatibleClassChangeError
.
Otherwise, if objectref is null
,
the invokeinterface
instruction throws a NullPointerException
.
Otherwise, if the class of objectref does not implement the
resolved interface, invokeinterface throws an IncompatibleClassChangeError
.
Otherwise, if step 1 or step 2 of the lookup procedure selects a
method that is not public
, invokeinterface throws an
IllegalAccessError
.
Otherwise, if step 1 or step 2 of the lookup procedure selects an
abstract
method, invokeinterface
throws an AbstractMethodError
.
Otherwise, if step 1 or step 2 of the lookup procedure selects a
native
method and the code that implements the method cannot be
bound, invokeinterface throws an UnsatisfiedLinkError
.
Otherwise, if step 3 of the lookup procedure determines there are
multiple maximally-specific methods in the superinterfaces of C
that match the resolved method's name and descriptor and are not
abstract
, invokeinterface throws
an IncompatibleClassChangeError
Otherwise, if step 3 of the lookup procedure determines there are
zero maximally-specific methods in the superinterfaces of C that
match the resolved method's name and descriptor and are not
abstract
, invokeinterface throws
an AbstractMethodError
.
The count operand of the invokeinterface
instruction records a
measure of the number of argument values, where an argument value
of type long
or type double
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
and double
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 many abstract
methods but only one
non-abstract
method, the non-abstract
method is selected
(unless an abstract
method is more specific).
Invoke instance method; special handling for superclass, private, and instance initialization method invocations
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 item at that 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 as well as a symbolic reference to the class or interface
in which the method is to be found. The named method is resolved
(§<IP_ADDRESS>,
§<IP_ADDRESS>).
If the resolved method is protected
, and it is a member of a
superclass of the current class, and the method is not declared in
the same run-time package (§5.3) as the
current class, then the class of objectref must be either the
current class or a subclass of the current class.
If all of the following are true, let C be the direct superclass of the current class:
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 a public
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
(§<IP_ADDRESS>) 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
(§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
type long
or double
, 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 Machine pc
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 is synchronized
, the monitor
associated with objectref is updated and possibly
exited as
if by execution of a monitorexit instruction
(§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 the
native
method and pushed onto the operand stack.
During resolution of the symbolic reference to the method, any of the exceptions pertaining to method resolution (§<IP_ADDRESS>) 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 an IncompatibleClassChangeError
.
Otherwise, if objectref is null
,
the invokespecial
instruction throws a NullPointerException
.
Otherwise, if the resolved method is a protected
method of a
superclass of the current class, declared in a different run-time
package, and the class of objectref is not the current class
or
a subclass of the current class, then invokespecial throws an
IllegalAccessError
.
Otherwise, if step 1, step 2, or step 3 of the lookup procedure
selects an abstract
method, invokespecial throws an
AbstractMethodError
.
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 an
UnsatisfiedLinkError
.
Otherwise, if step 4 of the lookup procedure determines there are
multiple maximally-specific methods in the superinterfaces of C
that match the resolved method's name and descriptor and are not
abstract
, invokespecial throws
an IncompatibleClassChangeError
Otherwise, if step 4 of the lookup procedure determines there are
zero maximally-specific methods in the superinterfaces of C that
match the resolved method's name and descriptor and are not
abstract
, invokespecial throws
an AbstractMethodError
.
The difference between the invokespecial instruction and the
invokevirtual instruction
(§invokevirtual) is that invokevirtual
invokes a method based on the class of the object. The
invokespecial instruction is used to invoke instance
initialization methods (§2.9) as well as
private
methods and methods of a superclass of the current
class.
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
and double
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 private
interface method, a non-abstract
interface method referenced via
a direct superinterface, and a non-abstract
interface method
referenced 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).
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 item at that 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 as well as a symbolic reference to the class or interface
in which the method is to be found. The named method is resolved
(§<IP_ADDRESS>).
The resolved method must not be an instance initialization method, or the class or interface initialization method (§2.9).
The resolved method must be static
, and therefore cannot be
abstract
.
On successful resolution of the method, the class or interface that declared the resolved method is initialized (§5.5) if that class or interface has not already been initialized.
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
resolved Class
object is entered or reentered as if by execution
of a monitorenter instruction
(§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 type
long
or double
, 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 Machine pc
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 is synchronized
, the monitor
associated with the resolved Class
object is updated and
possibly exited as if by execution of a monitorexit
instruction (§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 the
native
method and pushed onto the operand stack.
During resolution of the symbolic reference to the method, any of the exceptions pertaining to method resolution (§<IP_ADDRESS>) can be thrown.
Otherwise, if the resolved method is an instance method, the
invokestatic instruction throws an IncompatibleClassChangeError
.
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 an
UnsatisfiedLinkError
.
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 item at that 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 (§<IP_ADDRESS>).
The resolved method must not be an instance initialization method, or the class or interface initialization method (§2.9).
If the resolved method is protected
, and it is a member of a
superclass of the current class, and the method is not declared in
the same run-time package (§5.3) as the
current class, then the class of objectref must be either the
current class or a subclass of the current class.
If the resolved method is not signature polymorphic (§2.9), then the invokevirtual instruction proceeds as follows.
Let C be the class of objectref. The actual method to be invoked is selected by the following lookup procedure:
If C contains a declaration for an instance method m
that
overrides (§5.4.5)
the resolved method,
then m
is the method to be invoked.
Otherwise, if C has a superclass, a search for a declaration of an instance method that overrides 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 an overriding method is found or no further superclasses exist. If an overriding method is found, it is the method to be invoked.
Otherwise, if there is exactly one maximally-specific method
(§<IP_ADDRESS>) 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 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
(§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
type long
or double
, 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 Machine pc
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 is synchronized
, the monitor
associated with objectref is updated and possibly
exited as
if by execution of a monitorexit instruction
(§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 the
native
method and pushed onto the operand stack.
If the resolved method is signature polymorphic (§2.9), then the invokevirtual instruction proceeds as follows.
First, a reference
to an instance of java.lang.invoke.MethodType
is obtained as if by
resolution of a symbolic reference to a method type
(§<IP_ADDRESS>) with the same
parameter and
return types as the descriptor of the method referenced by the
invokevirtual instruction.
If the named method is invokeExact
, the instance of
java.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 of
java.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 of
java.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 a call to java.lang.invoke.MethodHandle.asType
, 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 §<IP_ADDRESS>.)
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; 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.
The frame in which the bytecode behavior itself executes is not visible.
Otherwise, if the method handle to be invoked has no bytecode behavior, the Java Virtual Machine invokes it in an implementation-dependent manner.
During resolution of the symbolic reference to the method, any of the exceptions pertaining to method resolution (§<IP_ADDRESS>) can be thrown.
Otherwise, if the resolved method is a class (static
) method,
the invokevirtual instruction throws an IncompatibleClassChangeError
.
Otherwise, if the resolved method is signature polymorphic, 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 (§<IP_ADDRESS>) can be thrown.
Otherwise, if objectref is null
,
the invokevirtual
instruction throws a NullPointerException
.
Otherwise, if the resolved method is a protected
method of a
superclass of the current class, declared in a different run-time
package, and the class of objectref is not the current class
or
a subclass of the current class, then invokevirtual throws an
IllegalAccessError
.
Otherwise, if the resolved method is not signature polymorphic:
If step 1 or step 2 of the lookup procedure selects an abstract
method, invokevirtual throws an AbstractMethodError
.
Otherwise, if step 1 or step 2 of the lookup procedure selects a
native
method and the code that implements the method
cannot
be bound, invokevirtual throws an UnsatisfiedLinkError
.
Otherwise, if step 3 of the lookup procedure determines there
are multiple maximally-specific methods in the superinterfaces
of C that match the resolved method's name and descriptor
and are not abstract
, invokevirtual
throws an IncompatibleClassChangeError
Otherwise, if step 3 of the lookup procedure determines there
are zero maximally-specific methods in the superinterfaces of
C that match the resolved method's name and descriptor and
are not abstract
, invokevirtual throws an AbstractMethodError
.
Otherwise, if the resolved method is signature polymorphic, then:
If the method name is invokeExact
, and the obtained
instance
of java.lang.invoke.MethodType
is not semantically equal to
the type
descriptor of the receiving method handle, the invokevirtual
instruction throws a java.lang.invoke.WrongMethodTypeException
.
If the method name is invoke
, and the obtained instance of
java.lang.invoke.MethodType
is not a valid argument to the
java.lang.invoke.MethodHandle.asType
method invoked on the
receiving method
handle, the invokevirtual instruction throws a
java.lang.invoke.WrongMethodTypeException
.
The nargs argument values and objectref
are not one-to-one
with the first nargs+1 local variables. Argument values of
types
long
and double
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.
Both value1 and value2
must be of type int
. The values are
popped from the operand stack. The int
result
is value1 -
(value1 / value2) *
value2. The result is
pushed onto the
operand stack.
The result of the irem instruction is such that (a/b)*b
+ (a%b)
is equal to a
. This identity
holds even in the special case in which the dividend is the
negative int
of largest possible magnitude for its type and the
divisor is -1 (the remainder is 0). It follows from this rule that
the result of the remainder operation can be negative only if the
dividend is negative and can be positive only if the dividend is
positive. Moreover, the magnitude of the result is always less
than the magnitude of the divisor.
The current method must have return type boolean
, byte
,
short
, char
, or int
. The value must be of type
int
. If
the current method is a synchronized
method, the monitor entered
or reentered on invocation of the method is updated and possibly
exited as if by execution of a monitorexit instruction
(§monitorexit) in the current thread. If
no exception is thrown, value is popped from the operand
stack
of the current frame (§2.6) and 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.
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, ireturn throws an
IllegalMonitorStateException
. This can happen, for example, if a
synchronized
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 ireturn throws an
IllegalMonitorStateException
.
Both value1 and value2
must be of type int
. The values are
popped from the operand stack. An int
result is calculated by
shifting value1 right by s bit positions, with sign
extension, where s is the value of the low 5 bits of
value2. The result is
pushed onto the operand stack.
The resulting value is floor(value1
/
2s), where s is value2
& 0x1f. For non-negative value1, this is equivalent to
truncating int
division by 2 to the power s. The shift
distance actually used is always in the range 0 to 31, inclusive,
as if value2 were subjected to a bitwise logical AND with the
mask value 0x1f.
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 int
. It is popped from the operand
stack, and the value of the local variable at index is set to
value.
The istore opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
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 int
. It is popped
from the operand stack, and the value of the local variable at
<n> is set to value.
Both value1 and value2
must be of type int
. The values are
popped from the operand stack. The int
result
is value1 -
value2. The result is
pushed onto the operand stack.
For int
subtraction, a-b
produces the same
result as a+(-b)
. For int
values,
subtraction
from zero is the same as negation.
The result is the 32 low-order bits of the true mathematical
result in a sufficiently wide two's-complement format, represented
as a value of type int
. If overflow occurs, then the sign of the
result may not be the same as the sign of the mathematical
difference of the two values.
Despite the fact that overflow may occur, execution of an isub instruction never throws a run-time exception.
Both value1 and value2
must be of type int
. The values are
popped from the operand stack. An int
result is calculated by
shifting value1 right by s bit positions, with zero
extension, where s is the value of the low 5 bits of
value2. The result is
pushed onto the operand stack.
If value1 is positive and s is value2 &
0x1f, the
result is the same as that of value1 >>
s; if
value1 is negative, the result is equal to the value of the
expression (value1 >>
s) + (2 <<
~s). The
addition of the (2 <<
~s)
term cancels out the
propagated sign bit. The shift distance actually used is always in
the range 0 to 31, inclusive.
The address of the opcode of the instruction immediately
following this jsr instruction is pushed onto the operand
stack
as a value of type returnAddress
. The unsigned branchbyte1 and
branchbyte2 are used to construct a signed 16-bit offset,
where
the offset is (branchbyte1 <<
8) |
branchbyte2. Execution proceeds at that offset from the
address
of this jsr instruction. The target address must be that of
an
opcode of an instruction within the method that contains this
jsr instruction.
Note that jsr pushes the address onto the operand stack and ret (§ret) gets it out of a local variable. This asymmetry is intentional.
In Oracle's implementation of a compiler for the Java programming language prior
to Java SE 6, the jsr instruction was used with the ret
instruction in the implementation of the finally
clause
(§3.13,
§<IP_ADDRESS>).
The address of the opcode of the instruction immediately
following this jsr_w instruction is pushed onto the operand
stack as a value of type returnAddress
. The unsigned
branchbyte1, branchbyte2, branchbyte3, and branchbyte4 are
used to construct a signed 32-bit offset, where the offset is
(branchbyte1 <<
24) |
(branchbyte2 <<
16) |
(branchbyte3 <<
8) | branchbyte4. Execution proceeds at
that offset from the address of this jsr_w instruction. The
target address must be that of an opcode of an instruction within
the method that contains this jsr_w instruction.
Note that jsr_w pushes the address onto the operand stack and ret (§ret) gets it out of a local variable. This asymmetry is intentional.
In Oracle's implementation of a compiler for the Java programming language prior
to Java SE 6, the jsr_w instruction was used with the ret
instruction in the implementation of the finally
clause
(§3.13,
§<IP_ADDRESS>).
Although the jsr_w instruction takes a 4-byte branch offset, other factors limit the size of a method to 65535 bytes (§4.11). This limit may be raised in a future release of the Java Virtual Machine.
Both value1 and value2
must be of type long
. The values are
popped from the operand stack. The long
result
is value1 +
value2. The result is
pushed onto the operand stack.
The result is the 64 low-order bits of the true mathematical
result in a sufficiently wide two's-complement format, represented
as a value of type long
. If overflow occurs, the sign of the
result may not be the same as the sign of the mathematical sum of
the two values.
Despite the fact that overflow may occur, execution of an ladd instruction never throws a run-time exception.
The arrayref must be of type reference
and must refer to an array
whose components are of type long
. The index must be of type
int
, and value must be of type
long
. The arrayref,
index, and value are
popped from the operand stack. The long
value is stored as the component of the array indexed by
index.
Both value1 and value2
must be of type long
. They are both
popped from the operand stack, and a signed integer comparison is
performed. If value1 is greater than value2, the int
value 1
is pushed onto the operand stack. If value1 is equal to
value2, the int
value 0 is
pushed onto the operand stack. If
value1 is less than value2, the int
value -1 is
pushed onto
the operand stack.
The index is an unsigned byte that must be a valid index into
the run-time constant pool of the current class
(§2.6). The run-time
constant pool entry at
index either must be a run-time constant of type int
or
float
, or a reference
to a string literal,
or a symbolic reference
to a class, method type, or method handle
(§5.1).
If the run-time constant pool entry is a run-time constant of type
int
or float
, the numeric value of that run-time constant is
pushed onto the operand stack as an int
or float
,
respectively.
Otherwise, if the run-time constant pool entry is a reference
to an
instance of class String
representing a string literal
(§5.1), then a reference
to that instance,
value, is pushed onto the operand stack.
Otherwise, if the run-time constant pool entry is a symbolic
reference to a class (§5.1), then the named
class is resolved (§<IP_ADDRESS>) and a
reference
to
the Class
object representing that class, value,
is pushed
onto the operand stack.
Otherwise, the run-time constant pool entry must be a symbolic
reference to a method type or a method handle
(§5.1). The method type or method handle is
resolved (§<IP_ADDRESS>) and a
reference
to the
resulting instance of java.lang.invoke.MethodType
or java.lang.invoke.MethodHandle
, value,
is
pushed onto the operand stack.
During resolution of a symbolic reference to a class, any of the exceptions pertaining to class resolution (§<IP_ADDRESS>) can be thrown.
During resolution of a symbolic reference to a method type or method handle, any of the exception pertaining to method type or method handle resolution (§<IP_ADDRESS>) can be thrown.
The unsigned indexbyte1 and indexbyte2
are assembled into an
unsigned 16-bit index into the run-time constant pool of the
current class (§2.6),
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 either must be a run-time constant of type
int
or float
, or a reference
to a string literal, or a symbolic
reference to a class, method type, or method handle
(§5.1).
If the run-time constant pool entry is a run-time constant of type
int
or float
, the numeric value of that run-time constant is
pushed onto the operand stack as an int
or float
,
respectively.
Otherwise, if the run-time constant pool entry is a reference
to an
instance of class String
representing a string literal
(§5.1), then a reference
to that instance,
value, is pushed onto the operand stack.
Otherwise, if the run-time constant pool entry is a symbolic
reference to a class (§4.4.1). The
named
class is resolved (§<IP_ADDRESS>) and a
reference
to
the Class
object representing that class, value,
is pushed
onto the operand stack.
Otherwise, the run-time constant pool entry must be a symbolic
reference to a method type or a method handle
(§5.1). The method type or method handle is
resolved (§<IP_ADDRESS>) and a
reference
to the
resulting instance of java.lang.invoke.MethodType
or java.lang.invoke.MethodHandle
, value,
is
pushed onto the operand stack.
During resolution of the symbolic reference to a class, any of the exceptions pertaining to class resolution (§<IP_ADDRESS>) can be thrown.
During resolution of a symbolic reference to a method type or method handle, any of the exception pertaining to method type or method handle resolution (§<IP_ADDRESS>) can be thrown.
The ldc_w instruction is identical to the ldc instruction (§ldc) except for its wider run-time constant pool index.
The ldc_w instruction can only be used to push a value of
type
float
taken from the float value set
(§2.3.2) because a
constant of type float
in the constant pool (§4.4.4)
must be taken
from the float value set.
The unsigned indexbyte1 and indexbyte2
are assembled into an
unsigned 16-bit index into the run-time constant pool of the
current class (§2.6),
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 a run-time constant of type long
or
double
(§5.1).
The numeric value of that
run-time constant is pushed onto the operand stack as a long
or
double
, respectively.
Only a wide-index version of the ldc2_w instruction exists;
there is no ldc2 instruction that pushes a
long
or double
with a single-byte index.
The ldc2_w instruction can only be used to push a value of
type
double
taken from the double value set
(§2.3.2) because a
constant of type double
in the constant pool (§4.4.5)
must be taken
from the double value set.
Both value1 and value2
must be of type long
. The values are
popped from the operand stack. The long
result
is the value of
the Java programming language expression value1 / value2. The result
is
pushed onto the operand stack.
A long
division rounds towards 0; that is, the quotient produced
for long
values in n / d is a long
value q
whose magnitude is as large as possible while satisfying |d
⋅ q| ≤
|n|. Moreover, q is
positive when
|n| ≥ |d| and n and d have the same sign,
but q is negative when |n| ≥ |d| and n and
d have opposite signs.
There is one special case that does not satisfy this rule: if the
dividend is the negative integer of largest possible magnitude for
the long
type and the divisor is -1, then overflow occurs and
the result is equal to the dividend; despite the overflow, no
exception is thrown in this case.
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 local
variable at index must
contain a long
. The value of the
local variable at index is
pushed onto the operand stack.
The lload opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
Both <n> and <n>+1 must be indices into the
local variable array of the current frame
(§2.6). The local
variable at <n>
must contain a long
. The value
of the local variable at
<n> is pushed onto the operand stack.
Both value1 and value2
must be of type long
. The values are
popped from the operand stack. The long
result
is value1 *
value2. The result is
pushed onto the operand stack.
The result is the 64 low-order bits of the true mathematical
result in a sufficiently wide two's-complement format, represented
as a value of type long
. If overflow occurs, the sign of the
result may not be the same as the sign of the
mathematical multiplication of the two values.
Despite the fact that overflow may occur, execution of an lmul instruction never throws a run-time exception.
The value must be of type long
.
It is popped from the operand
stack. The long
result is the
arithmetic negation of value,
-value. The result is
pushed onto the operand stack.
For long
values, negation is the same as subtraction from
zero. Because the Java Virtual Machine uses two's-complement representation for
integers and the range of two's-complement values is not
symmetric, the negation of the maximum negative long
results in
that same maximum negative number. Despite the fact that overflow
has occurred, no exception is thrown.
lookupswitch
<0-3 byte pad>
defaultbyte1
defaultbyte2
defaultbyte3
defaultbyte4
npairs1
npairs2
npairs3
npairs4
match-offset pairs...
A lookupswitch is a variable-length instruction. Immediately
after the lookupswitch opcode, between zero and three bytes
must
act as padding, such that defaultbyte1 begins
at an address that is a multiple of four bytes from the start of
the current method (the opcode of its first
instruction). Immediately after the padding follow a series of
signed 32-bit
values: default, npairs,
and then npairs pairs of signed 32-bit
values. The npairs must be greater than or
equal to 0. Each of the npairs pairs consists
of an int
match and a signed
32-bit offset. Each of these signed 32-bit
values is constructed from four unsigned bytes as
(byte1 <<
24) |
(byte2 <<
16) |
(byte3 <<
8)
| byte4.
The table match-offset pairs of the lookupswitch instruction must be sorted in increasing numerical order by match.
The key must be of type int
and
is popped
from the operand stack. The key is compared
against the match values. If it is equal to
one of them, then a target address is calculated by adding the
corresponding offset to the address of the
opcode of this lookupswitch instruction. If
the key does not match any of
the match values, the target address is
calculated by adding default to the address
of the opcode of this lookupswitch instruction. Execution
then
continues at the target address.
The target address that can be calculated from the offset of each match-offset pair, as well as the one calculated from default, must be the address of an opcode of an instruction within the method that contains this lookupswitch instruction.
The alignment required of the 4-byte operands of the lookupswitch instruction guarantees 4-byte alignment of those operands if and only if the method that contains the lookupswitch is positioned on a 4-byte boundary.
The match-offset pairs are sorted to support lookup routines that are quicker than linear search.
Both value1 and value2
must be of type long
. The values are
popped from the operand stack. The long
result
is value1 -
(value1 / value2) *
value2. The result is
pushed onto the
operand stack.
The result of the lrem instruction is such that
(a/b)*b + (a%b)
is equal
to a
. This identity holds even in the special
case in which the dividend is the negative long
of largest
possible magnitude for its type and the divisor is -1 (the
remainder is 0). It follows from this rule that the result of the
remainder operation can be negative only if the dividend is
negative and can be positive only if the dividend is positive;
moreover, the magnitude of the result is always less than the
magnitude of the divisor.
The current method must have return type long
. The value must
be of type long
. If the current method is a synchronized
method, the monitor entered or reentered on invocation of the
method is updated and possibly exited as if by execution of a
monitorexit instruction (§monitorexit)
in the current thread. If no exception is thrown, value is
popped from the operand stack of the current frame
(§2.6) and 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.
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, lreturn throws an
IllegalMonitorStateException
. This can happen, for example, if a
synchronized
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 lreturn throws an
IllegalMonitorStateException
.
The value1 must be of type long
,
and value2 must be of type
int
. The values are popped from the operand stack. A long
result is calculated by shifting value1
right by s bit
positions, with sign extension, where s is the value of the
low 6 bits of value2. The result is pushed onto the operand
stack.
The resulting value is floor(value1
/
2s), where s is value2
& 0x3f. For non-negative value1, this is equivalent to
truncating long
division by 2 to the power s. The shift
distance actually used is therefore always in the range 0 to 63,
inclusive, as if value2 were subjected to a bitwise logical
AND
with the mask value 0x3f.
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 long
. It is popped from the
operand stack, and the local variables at index and index+1
are set to value.
The lstore opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
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 long
. It is popped from the
operand stack, and the local variables at <n> and
<n>+1 are set to value.
Both value1 and value2
must be of type long
. The values are
popped from the operand stack. The long
result
is value1 -
value2. The result is
pushed onto the operand stack.
For long
subtraction, a-b
produces the
same
result as a+(-b)
. For long
values,
subtraction from zero is the same as negation.
The result is the 64 low-order bits of the true mathematical
result in a sufficiently wide two's-complement format, represented
as a value of type long
. If overflow occurs, then the sign of
the result may not be the same as the sign of the
mathematical difference of the two values.
Despite the fact that overflow may occur, execution of an lsub instruction never throws a run-time exception.
The value1 must be of type long
,
and value2 must be of type
int
. The values are popped from the operand stack. A long
result is calculated by shifting value1
right
logically by s bit positions, with zero
extension, where s is the value of the low 6 bits of
value2. The result is
pushed onto the operand stack.
If value1 is positive and s is value2 &
0x3f, the
result is the same as that of value1 >>
s; if
value1 is negative, the result is equal to the value of the
expression (value1 >>
s) + (2L <<
~s). The
addition of the (2L <<
~s)
term cancels out the
propagated sign bit. The shift distance actually used is always in
the range 0 to 63, inclusive.
The objectref must be of type reference
.
Each object is associated with a monitor. A monitor is locked if and only if it has an owner. The thread that executes monitorenter attempts to gain ownership of the monitor associated with objectref, as follows:
If the entry count of the monitor associated with objectref is zero, the thread enters the monitor and sets its entry count to one. The thread is then the owner of the monitor.
If the thread already owns the monitor associated with objectref, it reenters the monitor, incrementing its entry count.
If another thread already owns the monitor associated with objectref, the thread blocks until the monitor's entry count is zero, then tries again to gain ownership.
A monitorenter instruction may be used with one or more
monitorexit instructions
(§monitorexit) to implement a
synchronized
statement in the Java programming language
(§3.14).
The monitorenter and
monitorexit instructions are not used in the implementation
of
synchronized
methods, although they can be used to provide
equivalent locking semantics. Monitor entry on invocation of a
synchronized
method, and monitor exit on its return, are handled
implicitly by the Java Virtual Machine's method invocation and return
instructions, as if monitorenter and monitorexit were
used.
The association of a monitor with an object may be managed in various ways that are beyond the scope of this specification. For instance, the monitor may be allocated and deallocated at the same time as the object. Alternatively, it may be dynamically allocated at the time when a thread attempts to gain exclusive access to the object and freed at some later time when no thread remains in the monitor for the object.
The synchronization constructs of the Java programming language require support
for operations on monitors besides entry and exit. These include
waiting on a monitor (Object.wait
) and
notifying other threads waiting on a monitor
(Object.notifyAll
and Object.notify
). These operations are
supported in the standard package java.lang
supplied with the Java Virtual Machine. No explicit support for these operations
appears in the instruction set of the Java Virtual Machine.
The objectref must be of type reference
.
The thread that executes monitorexit must be the owner of the monitor associated with the instance referenced by objectref.
The thread decrements the entry count of the monitor associated with objectref. If as a result the value of the entry count is zero, the thread exits the monitor and is no longer its owner. Other threads that are blocking to enter the monitor are allowed to attempt to do so.
If objectref is null
, monitorexit throws a NullPointerException
.
Otherwise, if the thread that executes monitorexit is not the
owner of the monitor associated with the instance referenced by
objectref, monitorexit
throws an
IllegalMonitorStateException
.
Otherwise, if the Java Virtual Machine implementation enforces the rules on
structured locking described in §2.11.10 and
if the second of those rules is violated by the execution of this
monitorexit instruction, then monitorexit
throws an
IllegalMonitorStateException
.
One or more monitorexit instructions may be used with a
monitorenter instruction
(§monitorenter) to implement a
synchronized
statement in the Java programming language
(§3.14).
The monitorenter and
monitorexit instructions are not used in the implementation
of
synchronized
methods, although they can be used to provide
equivalent locking semantics.
The Java Virtual Machine supports exceptions thrown within synchronized
methods
and synchronized
statements differently:
Monitor exit on normal synchronized
method completion is
handled by the Java Virtual Machine's return instructions. Monitor exit on
abrupt synchronized
method completion is handled implicitly
by the Java Virtual Machine's athrow instruction.
When an exception is thrown from within a synchronized
statement, exit from the monitor entered prior to the
execution of the synchronized
statement is achieved using
the Java Virtual Machine's exception handling mechanism
(§3.14).
The dimensions operand is an unsigned byte
that must be greater than or equal to 1. It represents the number
of dimensions of the array to be created. The operand stack must
contain dimensions values. Each such value
represents the number of components in a dimension of the array to
be created, must be of type int
, and must be
non-negative. The count1 is the desired
length in the first dimension, count2 in the
second, etc.
All of the count values are popped off the
operand stack. The unsigned indexbyte1 and indexbyte2 are used
to construct an index into the run-time constant pool of the
current class (§2.6),
where the value of the
index is (indexbyte1 <<
8)
| indexbyte2. The run-time
constant pool item at the index must be a symbolic reference to a
class, array, or interface type. The named class, array, or
interface type is resolved (§<IP_ADDRESS>).
The
resulting entry must be an array class type of dimensionality
greater than or equal to dimensions.
A new multidimensional array of the array type is allocated from
the garbage-collected heap. If any count
value is zero, no subsequent dimensions are allocated. The
components of the array in the first dimension are initialized to
subarrays of the type of the second dimension, and so on. The
components of the last allocated dimension of the array are
initialized to the default initial value
(§2.3, §2.4)
for the
element type of the array type. A reference
arrayref
to the new
array is pushed onto the operand stack.
During resolution of the symbolic reference to the class, array, or interface type, any of the exceptions documented in §<IP_ADDRESS> can be thrown.
Otherwise, if the current class does not have permission to access
the element type of the resolved array class, multianewarray
throws an IllegalAccessError
.
Otherwise, if any of the dimensions values on
the operand stack are less than zero, the multianewarray
instruction throws a NegativeArraySizeException
.
It may be more efficient to use newarray or anewarray (§newarray, §anewarray) when creating an array of a single dimension.
The array class referenced via the run-time constant pool may have more dimensions than the dimensions operand of the multianewarray instruction. In that case, only the first dimensions of the dimensions of the array are created.
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 item at the index must be a symbolic reference to a class or
interface type. The named class or interface type is resolved
(§<IP_ADDRESS>) and should result in a
class
type. Memory for a new instance of that class is allocated from
the garbage-collected heap, and the instance variables of the new
object are initialized to their default initial values
(§2.3, §2.4).
The
objectref, a reference
to the
instance, is pushed onto the operand
stack.
On successful resolution of the class, it is initialized (§5.5) if it has not already been initialized.
During resolution of the symbolic reference to the class, array, or interface type, any of the exceptions documented in §<IP_ADDRESS> can be thrown.
Otherwise, if the symbolic reference to the class, array, or
interface type resolves to an interface or is an abstract
class,
new throws an InstantiationError
.
Otherwise, if execution of this new instruction causes
initialization of the referenced class, new may throw an
Error
as detailed in JLS §15.9.4.
The new instruction does not completely create a new instance; instance creation is not completed until an instance initialization method (§2.9) has been invoked on the uninitialized instance.
The count must be of type int
.
It is popped off the operand
stack. The count represents the number of elements in the
array
to be created.