[In-depth understanding of the just-in-time compiler of the Java virtual machine] 1123 compilation process

One, the compilation process

1. Default conditions

A: Before the compiler finishes compiling, it will continue to execute the code according to the interpretation method. (Standard compilation request for method call, compilation request for replacement on the stack)

B: The compilation action is performed in the background compilation thread.

C: You can use the parameter -XX: -BackgroundCompilation to prohibit background compilation. After background compilation is prohibited, when the conditions for triggering just-in-time compilation are reached, the execution thread will block and wait after submitting a compilation request to the virtual machine until the compilation process is completed. Start to execute the native code output by the compiler.

2. Client-side compiler (three-stage compiler)

1. A platform-independent front end constructs bytecode into a high-level intermediate representation (High-Level Intermediate Representation, HIR, that is, an intermediate representation independent of the target machine instruction set).

A: HIR uses the form of Static Single Assignment (SSA) to represent code values, which can make it easier to implement some optimization actions during and after the construction of HIR. Prior to this, the compiler has already completed some basic optimizations on the bytecode, such as method inlining, constant propagation and other optimizations will be completed before the bytecode is constructed into HIR.

2. A platform-related backend generates a low-level intermediate code representation from HIR (Low-Level Intermediate Representation, LIR, that is, an intermediate representation related to the target machine instruction set)

A:, and before that, other optimizations will be done on HIR, such as null value check elimination, range check elimination, etc., so that HIR can achieve a more efficient code representation.

3. Use the Linear Scan RegisterAllocation to allocate registers on the LIR on the platform-related backend, and do Peephole optimization on the LIR, and then generate machine code.

Insert picture description here

Three, server-side compilation

1. The server-side compiler is specifically oriented to typical server-side application scenarios, and is configured specifically for server-side performance. It is an advanced compiler that can tolerate high optimization complexity and can almost reach GNU C++ compilation. Optimized intensity when using the -O2 parameter.

A: It will perform most of the classic optimization actions, such as: Dead Code Elimination, Loop Unrolling, Loop Expression Hoisting, CommonSubexpression Elimination , Constant Propagation, Basic Block Reordering, etc.,

B: Implement some optimization techniques closely related to Java language features, such as Range Check Elimination and NullCheck Elimination. However, not all Null Check Elimination is optimized by the compiler, and some It is automatically optimized during code execution) and so on.

C: According to the performance monitoring information provided by the interpreter or client compiler, some unstable predictive radical optimizations, such as Guarded Inlining, Branch Frequency Prediction, etc.

2. The register allocator used in server-side compilation is a global graph shading allocator, which can make full use of the large register set on certain processor architectures (such as RISC). In terms of just-in-time compilation standards, the server-side compiler is undoubtedly slower, but its compilation speed is still far faster than the traditional static optimization compiler, and it has a great quality compared to the client-side compiler. The improvement can greatly reduce the execution time of the native code, thereby offsetting the additional compilation time overhead. Therefore, many non-server applications choose to use the HotSpot virtual machine in the server mode to run.

Guess you like

Origin blog.csdn.net/qq_40996741/article/details/109109526