Frames in JVM
Frame is used to store data and partial results, as well as to perform dynamic binding, return values for methods, and throw exceptions. A new frame is created every time the method is called. The Frame is destroyed when the method call completes, whether that completion is normal or abrupt (it throws an uncaught exception). Frames are popped off the stack of the thread creating the frame. Each frame has its own array of local variables, its own operand stack, and a reference to the constant pool during the execution of the current method's class. The sizes of the local variable array and operand stack are determined at compile time and provided with the code for the method associated with the frame. Thus, the size of the data structure, frame, depends only on the implementation of the Java virtual machine, and the memory for these structures can be allocated simultaneously when the method is called.
Only one frame is active at any point in a given control flow, the execution method, and this frame is called the current, and its method is known as the current method. The class in which the current method is defined is the current class. Operations on local variables and the operand stack are usually performed with reference to the current frame.
A Frame is no longer current if its method calls another method or if its method terminates. When the method is called, a new frame is created and becomes current when control passes to the new method. When the method returns, the current frame passes the result of the method call, if any, to the previous frame. The current frame is then discarded as the previous frame becomes the current one. Note that a frame created by a thread is local to that thread and cannot be referenced by any other thread.
Local variables
Each frame contains an array of variables known as its local variables. The length of the local variable array frame is determined at compile time and is provided in the binary representation of the class or interface, along with the code for the method associated with frame. A single local variable can store a value of type: boolean, byte, char, short, int, float, reference, or returnAddress. A pair of local variables can store a value of types: long or double.
Local variables are addressed by indexing. The index of the first local variable is zero.
A long or double value occupies two consecutive local variables.
The JVM uses local variables to pass parameters when calling a method. When calling a class method, all parameters are passed in sequential local variables, starting with local variable 0. When calling an instance method, local variable 0 is always used to pass a reference to the object on which the instance method is called (this in Java). Any parameters are subsequently passed in sequential local variables, starting with local variable 1.
Operand Stacks
Each frame contains a last-in-first-out (LIFO) stack, known as the operand stack. The maximum operand stack depth of frame is determined at compile time and provided with the code for the method associated with frame.
The operand stack is empty when the frame that contains it is created. The JVM provides instructions for loading constants or values from local variables or fields onto the operand stack. Other JVM instructions take operands from the operand stack, operate on them, and push the result back onto the operand stack. The operand stack is also used to prepare parameters for passing to methods and for receiving method results.
For example, the iadd statement adds two int values. The operand stack is required to have two int values at the top of the stack. Values are removed from the stack, pop operation. They are added and their sum is pushed onto the operand stack.
Dynamic Linking
Each frame contains a reference to a run-time constant pool for the type of the current method to support dynamic binding of method code. Callable methods and variables are accessed through symbolic links from the class file. Dynamic linking converts these symbolic method references to concrete method references, loading classes as needed to resolve as yet undefined characters, and converts variable references to appropriate offsets in storage structures associated with the location of these variables at runtime.
Late binding of methods and variables introduces changes to other classes that the method uses less likely to break this code.
Normal completion of a method call
A method call completes normally unless the call throws an exception, either directly from the JVM or as a result of an explicit throw statement. If the call to the current method completes normally, then the value can be returned to the calling method. This occurs when the called method executes one of the return statements, the selection of which must match the return type (if any).
The current frame is used in this case to restore the state of the initiator, including its local variables and operand stack, with the initiator's program counter incremented appropriately to skip the method call instruction. Execution then usually continues in the calling method's frame, with the return value (if any) pushed onto that frame's operand stack.
Method call abrupt termination
A method call completes abruptly if the JVM in the method throws an exception when the statement is executed, and the exception is not handled in the method. Executing athrow will also explicitly throw an exception, and if the exception is not caught by the current method, the method call will terminate unexpectedly. A method call that terminates abruptly never returns a value to its caller.
Read also:
Comments
Post a Comment