Java JVM: Bytecode Execution Engine (6)

The execution engine is one of the core components of the Java virtual machine, and the execution engine is implemented by the software itself

1. Runtime stack frame structure

  • The Java virtual machine uses methods as the most basic execution unit, and the "stack frame" is used to support the virtual machine for method invocation and method execution.
  • Stack frame includes local variable table, operand stack, dynamic link, method return address and some additional additional information
  • When compiling the Java source code, the required local variable table and the depth of the operand stack have been calculated and written into the Code attribute
  • In the active thread, only the method at the top of the stack is running (current stack frame)
  • local variable table
    • A storage space for a set of variable values, storing method parameters and local variables defined inside the method, with variable slots as the smallest unit of capacity
    • Each variable slot should occupy a memory space of 32 bits in length
      • Can vary by processor, operating system, or virtual machine implementation
      • Need to use alignment and padding to make the variable slot look the same as in the 32-bit virtual machine
      • The Java virtual machine allocates two consecutive variable slot spaces (long, double) in a high-order aligned manner
  • operand stack
    • Operation stack, last in first out, the maximum depth is written into the max_stacks data item of the Code attribute during compilation
    • The data flow analysis work of the Javac compiler ensures that at any time during the execution of the method, the depth of the operand stack will not exceed the maximum value set in the max_stacks data item
    • At the beginning of execution, various bytecode instructions write and extract content into the operand stack, that is, pop and push
    • Two different stack frames are independent of each other as virtual machine stack elements of different methods
    • The interpretation and execution engine of the Java virtual machine is called a "stack-based execution engine", and the stack is the operand stack
  • dynamic link
    • Each stack frame contains a reference to the method to which the stack frame belongs in the runtime constant pool. This reference is to support the dynamic connection during the method call.
    • Part of the symbol reference will be converted into a direct reference during the class loading phase or when it is used for the first time, which is static analysis
    • It is converted into a direct reference during each run, and this part is called dynamic linking
  • method return address
    • method exit method
      • The execution engine encounters a bytecode instruction returned by any method (normal call completion)
        • When exiting normally, the value of the PC counter of the calling method can be used as the return address, and this counter value is likely to be saved in the stack frame
      • An exception was encountered during method execution (abnormal call completed)
        • When exiting abnormally, it is determined by the exception handler table
    • Actions possible on exit
      • Restore the local variable table and operand stack of the upper-level method, push the return value into the operand stack of the caller's stack frame, adjust the value of the PC counter to point to an instruction after the method call instruction, etc.

2. Method call

  • analyze
    • The target method of all method calls is a symbolic reference in a constant pool in the Class file
    • During the parsing phase of class loading, some of the symbolic references will be converted into direct references
      • The method has a determinable call version before the program actually runs, and the call version of this method cannot be changed during runtime
  • assign
    • static dispatch
      • overload
    • dynamic dispatch
      • rewrite
    • single dispatch and multiple dispatch
  • dynamically typed language
    • The key feature is that the main process of its type checking is performed at runtime rather than at compile time

3. Stack-based bytecode interpretation and execution engine

  • explain execution
    • code execution process
      • The javac compiler completes the process of lexical analysis, syntax analysis, abstract syntax tree, and then traversal of the syntax tree to generate a linear bytecode instruction stream.
      • This part of the action is performed outside the Java virtual machine, and the interpreter is inside the virtual machine, so the compilation of the Java program is a semi-independent implementation

insert image description here

  • Stack-based instruction set vs. register-based instruction set
    • The bytecode instruction stream output by the javac compiler is basically a stack-based instruction set architecture. Most of the instructions in the bytecode instruction stream are zero-address instructions, and they rely on the operand stack to work.
  • Stack-based interpreter execution process

insert image description here

4. OSGI: Flexible Class Loader Architecture

  • A Dynamic Modularization Specification Based on the Java Language
  • In OSGI, the dependency relationship between Bundles has changed from the traditional upper-level module dependence on the lower-level module to the dependence between flat-level modules, and the visibility of the class library is very precisely controlled
    • Only the exported Package of a module can be accessed by the outside world, and other Packages and Classes will be hidden
  • There are only rules between OSGI's Bundle class loaders, and there is no fixed delegation relationship
  • When the Bundle class loader provides services for other Bundles, it will strictly control the access scope according to the Export-Package list
    • If there is no Export, it will not be provided to other Bundles, nor will the class loading requests of other Bundles be assigned to this Bundle for processing

Guess you like

Origin blog.csdn.net/baidu_40468340/article/details/128814515