008 Virtual Machine byte-code execution engine

Source: Internet
Author: User
Tags compact

The execution engine is one of the core components of the Java virtual machine. The execution engine of a physical machine is built on the processor, hardware, instruction set, and operating system, and the execution engine of the virtual machine needs to be implemented by itself, so that the architecture of the instruction set and execution engine can be set up and supported by the instruction set format that is not directly supported by the hardware.
1, the runtime stack frame stack frame is used to support the virtual machine to make method calls and method execution of the data structure, is the virtual machine Runtime data region of the stack elements of the virtual stack. The stack frame stores the local variable table of the method, the operand stack, the dynamic connection, and the method return address. For the execution engine, in the active thread, only the stack frame at the top of the stack is valid and becomes the current stack frame, and the method associated with the stack frame is called the current method. ① local variable table local variable table (local Variable table) is a set of variable value storage spaces used to store method parameters and local variables defined inside methods.
The maximum capacity of the local variable table that the method needs to allocate is determined in the Max_locals data item of the method's Code property.
The capacity of the local variable table is the smallest unit in the variable slot (Variable slot, slot), and the virtual machine specification does not explicitly indicate the amount of memory that a slot should occupy, but it is very prescriptive to say that each slot should be able to hold a Boolean, Byte, Char , short, int, float, reference, or returnaddress types of data.
ForReference,from this reference, you directly or indirectly find the starting address index of the object's data in the Java heap, and second, this reference directly or indirectly finds the type information stored in the method area of the data type to which the object belongs. For a 64-bit data type, the virtual opportunity assigns two contiguous slot spaces to it in a high-alignment manner. The data types in the Java language that are explicit (reference types may be 32-bit or 64-bit) 64-bit are only long and double two.
When the method executes, the virtual machine uses the local variable table to complete the pass of the parameter value to the parameter list, and if it executes an instance method (a non-static method), the slot of the No. 0-bit index in the local variable table defaults to the reference used to pass the object instance to which the method belongs, and in the method the keyword " This "accesses this implied parameter.
In order to save stack frame space as much as possible, the slot in the local variable table is reusable, the variable defined in the method body does not necessarily overwrite the entire method body, and if the value of the current bytecode PC counter exceeds the scope of a variable, the slot corresponding to that variable can be used by other variables. But it may affect garbage collection, for example:
  
 
  1. public static void main(String[]args)(){
  2.     byte[] placeholder = new byte[64*1024*1024];
  3.     System.gc();
  4. }
The placeholder is not recycled and the slots are not reused.
The fundamental reason placeholder can be recycled is whether the slots in the local variable table also have references to placeholder array objects. The code has left the scope of the placeholder, but after that, there is no read-write operation on the local variable table, placeholder originally occupied by the slot has not been reused by other variables, so the local variable table as part of the GC roots remains associated with it.
Local variables are defined, but they cannot be used without assigning an initial value.
The ② operand stack (Operand stack) is also commonly referred to as the stack of operations, which is a post-in, first-out (last-in Out,lifo) stack. As with local variable tables, the maximum depth of the operand stack is also written to the Max_stacks data item of the Code property at compile time. The 32-bit data type occupies a stack capacity of 1, and the 64-bit data type occupies a stack capacity of 2. At any point in the execution of the method, the depth of the operand stack does not exceed the maximum value set in the Max_stacks data item.

③ dynamic connections Each stack frame contains a reference to the method that the stack frame belongs to in the run-time pool, which is held to support dynamic connections in the method invocation process (linking).

④ method return address When a method starts executing, there are only two ways to exit this method.
    • The first is that the execution engine encounters a bytecode instruction returned by either method, at which point the return value may be passed to the method caller of the upper layer (the method calling the current method is called the caller), and whether the type of the return value and the return value will be determined based on the method return instruction encountered. The way to exit this method is known as the normal completion exit (normal method invocation completion).
    • Another way to exit is to encounter an exception during the execution of the method, and the exception is not handled in the method body, whether it is an exception generated inside the Java virtual machine, or an exception that is generated in code using the Athrow bytecode directive, as long as no matching exception handler is found in the exception table of this method. Causes the method to exit, the way the exit method is called the exception completion exit (abrupt invocation completion). A method exits with an exception completion exit, and does not produce any return value for its upper-level callers.

⑤Additional InformationThe virtual machine specification allows specific virtual machine implementations to add information that is not described in the specification to the stack frame, such as debugging-related information, which is entirely dependent on the specific virtual machine implementation, which is no longer detailed here. In the actual development, the dynamic connection, the method return address and other additional information are generally classified as a class, called the stack frame information.
2, method call parsing is a static process, the allocation may be dynamic or static ① parsing all method calls in the target method in the class file is a constant pool of symbolic references, in the class load parsing phase, some of the symbolic references will be converted to direct references, The premise of this resolution is that the method has a deterministic version of the call before the program actually runs, and that the invocation version of the method is immutable at run time. In other words, the invocation target must be determined when the program code is written and the compiler compiles. The invocation of such a method is called parsing (Resolution). < mainly includes static and private methods, both of which cannot be inherited or otherwise rewritten, and are suitable for parsing during the loading phase >
In the Java virtual machine there are 5 methods called bytecode instructions, respectively, as follows.
    • Invokestatic: Calls a static method.
    • Invokespecial: Invokes the instance constructor method, private method, and parent class method.
    • Invokevirtual: All virtual methods are called.
    • Invokeinterface: Invokes an interface method that, at run time, determines an object that implements this interface.
    • Invokedynamic: The method referenced by the call point qualifier is parsed dynamically at run time before the method is executed, where the dispatch logic is cured inside the Java virtual machine, before the 4 calling instruction. The dispatch logic of the invokedynamic instruction is determined by the user-defined guidance method.
As long as the method that can be called by the invokestatic and invokespecial instructions can determine the unique invocation version in the parsing phase, there are static methods, private methods, instance constructors, and parent class method 4 classes that conform to this condition. They parse the symbolic reference into a direct reference to the method when the class is loaded. These methods can be called non-virtual methods, and conversely, other methods are called virtual methods (except final, the final method usesinvokevirtual directive invocation, but is not a virtual method). A non-virtual method in Java, in addition to the method called by Invokestatic, Invokespecial, is the final modified method. Although the final method is invoked with the Invokevirtual directive, it cannot be overwritten, there are no other versions, so there is no need to make a polymorphic selection of the method receiver, or the result of a polymorphic selection must be unique. The final method is explicitly stated in the Java language Specification as a non-virtual method. ② Dispatch 1) Static dispatch
 
   
  
  1. Human man = new Man(); //Man是Human的子类
Human is called the static type of the variable, man is called the actual type,A virtual machine (exactly, the compiler) is judged by the static type of the parameter instead of the actual type when overloaded. For the above variable passed as a parameter to the overloaded function,
 
   
  
  1. sayHello(Human human);
  2. sayHello(Man man);
The virtual opportunity invokes the above function, judging by the static type of the argument, the static type of the man variable is human.
All dispatch actions that rely on static types to locate a method's execution version are called static allocations. Typical applications for static dispatch are method overloads. Static dispatch occurs during the compilation phase, so determining the static dispatch action is not actually performed by the virtual machine.
2) The runtime parsing process of the dynamic dispatch invokevirtual instruction is broadly divided into the following steps:
    • Find the actual type of the object pointed to by the first element at the top of the operand stack, as C.
    • If a method is found in type C that matches the descriptor and simple name in the constant, the access check is performed, and if passed returns a direct reference to the method, the lookup process ends, and if it does not, the Java.lang.IllegalAccessError exception is returned.
    • Otherwise, follow the inheritance relationship from the bottom up to the 2nd step of the search and validation process for each parent class C.
    • Throws a Java.lang.AbstractMethodError exception if the appropriate method is never found.
Since the first step in the execution of the invokevirtual instruction is to determine the actual type of receiver at run time, the invokevirtual instruction in two calls resolves the class method symbol reference in the constant pool to a different direct reference, which is the essence of the method rewrite in the Java language. The dispatch process of performing a version at run time based on the actual type determination method is called dynamic dispatch. 3) The parameters of the receivers and methods of the single dispatch and multi-dispatch methods are collectively referred to as the method's volume, which can be divided into single and multi-Dispatch depending on how many kinds of parcels are based on the allocation. A single dispatch is a selection of the target method based on one volume, and the multiple allocation selects the target method based on more than one volume.
The Java language is a static, multi-Dispatch, dynamic single-Dispatch language.
4) Implementation of dynamic dispatch of virtual machine because dynamic dispatch is a very frequent action, and the method version selection process of dynamic dispatch requires the runtime to search for the appropriate target method in the method metadata of the class, most implementations do not really carry out such frequent searches based on performance considerations in the actual implementation of the virtual machine. In the face of this situation, the most commonly used "stability optimization" method is to create a virtual method table for the class in the method area (Vritual methods table, also known as vtable, corresponding to this, in the Invokeinterface execution will also use the interface method tables--inteface Method table, referred to as itable), uses virtual method table indexes instead of metadata lookups to improve performance.

If a method is not overridden in a subclass, the address entry in the virtual method table of the subclass and the address entry for the same method as the parent class are consistent, pointing to the implementation entry of the parent class.

The method table is typically initialized at the connection stage of the class load, and after the class's variable initial value is prepared, the virtual opportunity initializes the method table for that class.

③ The key feature of dynamic type language support for dynamic type language is that the main process of its type checking is at run time rather than compile time, there are many languages that satisfy this feature, commonly used include: APL, Clojure, Erlang, Groovy, JavaScript, Jython, Lisp, Lua, PHP, Prolog, Python, Ruby, Smalltalk, and Tcl.
"Variable without type and variable value is type" is an important feature of dynamic type language.

In the Java language perspective, the use of methodhandle and the effects of reflection have many similarities, but they still have the following differences:
    • Essentially, the reflection and methodhandle mechanisms are in the mock method invocation, but the reflection is a method call that emulates the Java code hierarchy, and Methodhandle is a method call that emulates the byte-code hierarchy. The 3 methods in Methodhandles.lookup--findstatic (), findvirtual (), findspecial () are to correspond to invokestatic, The Invokevirtual&invokeinterface and invokespecial execute permission check behavior for these bytecode directives, and these underlying details do not need to be concerned when using the reflection API.
    • The Java.lang.reflect.Method object in reflection is much more information than the Java.lang.invoke.MethodHandle object in the Methodhandle mechanism. The former is a comprehensive image of the method at the Java end, including the method's signature, descriptor, and the Java side representation of various properties in the method attribute table, as well as run-time information such as execution permissions. The latter only contains information related to the execution of the method. In layman's terms, reflection is heavyweight, while Methodhandle is lightweight.
    • since Methodhandle is a simulation of the method instruction invocation of bytecode, in theory the various optimizations made by virtual machines in this regard (such as inline methods) should be supported on the Methodhandle (but are not yet complete). It is not possible to invoke the method by reflection.  
The Reflection API is designed to serve only the Java language, while Methodhandle is designed to serve all Java virtual machines, including the Java language.
Each location that contains the invokedynamic directive is called a dynamic call site, and the first parameter of this instruction is no longer the Constant_methodref_info constant that represents the method symbol, but instead becomes the JDK 1.7 Newly added Constant_invokedynamic_info constants, from this new constant can be obtained 3 information: The Boot method (Bootstrap method, which is stored in the new Bootstrapmethods attribute), The method type (methodtype) and name.

4. Stack-based bytecode interpretation execution engine stack-based instruction sets the main advantages are portability, relatively compact code, and simpler compiler implementations. The main drawback is that the execution speed is relatively slow. Although the code of the stack schema instruction set is very compact, the number of instructions required to complete the same function is generally more than the register schema, because the stack and stack operations themselves produce a considerable number of instructions.

From for notes (Wiz)

008 Virtual Machine byte-code execution engine

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.