Sponsored Link •
Because Java programs are dynamically linked, references to methods initially are symbolic. All invoke instructions, such as
invokestatic, refer to a
constant pool entry that initially contains a symbolic reference. (See
my earlier column, "The Java class file
lifestyle," for a description of constant pool.) The symbolic
reference is a bundle of information that uniquely identifies a method,
including the class name, method name, and method descriptor. (A
method descriptor is the method's return type and the number and types
of its arguments.) The first time the Java virtual machine encounters a
particular invoke instruction, the symbolic reference must be
To resolve a symbolic reference, the JVM locates the method being referred to symbolically and replaces the symbolic reference with a direct reference. A direct reference, such as a pointer or offset, allows the virtual machine to invoke the method more quickly if the reference is ever used again in the future.
For example, upon encountering an
instruction, the Java virtual machine forms an index into the constant
pool of the current class from the
indexbyte2 operands that follow the
invokevirtual opcode. The constant pool entry contains a
symbolic reference to the method to invoke. The process of resolving
symbolic references in the constant pool is how the JVM performs
During resolution, the JVM also performs several verification checks. These checks ensure that Java language rules are followed and that the invoke instruction is safe to execute. For example, the virtual machine first makes sure the symbolically referenced method exists. If it exists, the virtual machine checks to make sure the current class can legally access the method. For example, if the method is private, it must be a member of the current class. If any of these checks fail, the Java virtual machine throws an exception.
Objectref and args
Once the method has been resolved, the Java virtual machine is ready to invoke it. If the method is an instance method, it must be invoked on an object. For every instance method invocation, the virtual machine expects a reference to the object (objectref) to be on the stack. In addition to objectref, the virtual machine expects the arguments (args) required by the method, if any, to be on the stack. If the method is a class method, only the args are on the stack. Class methods don't require an objectref because they aren't invoked on an object.
The objectref and args (or just args, in the case of a class method) must be pushed onto the calling method's operand stack by the bytecode instructions that precede the invoke instruction.
Pushing and popping the stack frame
To invoke a method, the Java virtual machine creates a new stack frame for the method. The stack frame contains space for the method's local variables, its operand stack, and any other information required by a particular virtual machine implementation. The size of the local variables and operand stack are calculated at compile-time and placed into the class file, so the virtual machine knows just how much memory will be needed by the method's stack frame. When the JVM invokes a method, it creates a stack frame of the proper size for that method.
Adding a new frame onto the Java stack when a method is invoked is called "pushing" a stack frame; removing a frame when a method returns is called "popping" a stack frame. The Java stack is made up solely of these frames.