Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C1/C2资料汇编 #337

Open
shining1984 opened this issue Feb 18, 2022 · 12 comments
Open

C1/C2资料汇编 #337

shining1984 opened this issue Feb 18, 2022 · 12 comments

Comments

@shining1984
Copy link

C1 compiler
Fast, lightly optimizing bytecode compiler. Performs some value numbering, inlining, and class analysis. Uses a simple CFG-oriented SSA "high" IR, a machine-oriented "low" IR, a linear scan register allocation, and a template-style code generator.

C2 compiler
Highly optimizing bytecode compiler, also known as 'opto'. Uses a "sea of nodes" SSA "ideal" IR, which lowers to a machine-specific IR of the same kind. Has a graph-coloring register allocator; colors all machine state, including local, global, and argument registers and stack. Optimizations include global value numbering, conditional constant type propagation, constant folding, global code motion, algebraic identities, method inlining (aggressive, optimistic, and/or multi-morphic), intrinsic replacement, loop transformations (unswitching, unrolling), array range check elimination.

From: https://openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html

@shining1984
Copy link
Author

C1 原始论文:A Compiler for the Java HotSpot Virtual Machine ( Robert Griesemer) 源于书籍:The School of Niklaus Wirth

@shining1984
Copy link
Author

shining1984 commented Feb 18, 2022

Despite being called server JVMs, the distinction between client and server compilers
persists; both compilers are available to and used by the JVM. So knowing this differ‐
ence is important in understanding how the compiler works.

Historically, JVM developers (and even some tools) sometimes referred to the com‐
pilers by the names C1 (compiler 1, client compiler) and C2 (compiler 2, server
compiler). Those names are more apt now, since any distinction between a client and
server computer is long gone, so we’ll adopt those names throughout.

The primary difference between the two compilers is their aggressiveness in compil‐
ing code. The C1 compiler begins compiling sooner than the C2 compiler does. This
means that during the beginning of code execution, the C1 compiler will be faster,
because it will have compiled correspondingly more code than the C2 compiler.

The engineering trade-off here is the knowledge the C2 compiler gains while it waits:
that knowledge allows the C2 compiler to make better optimizations in the compiled
code. Ultimately, code produced by the C2 compiler will be faster than that produced
by the C1 compiler. From a user’s perspective, the benefit to that trade-off is based on
how long the program will run and how important the startup time of the program is.
When these compilers were separate, the obvious question was why there needed to
be a choice at all: couldn’t the JVM start with the C1 compiler and then use the C2
compiler as code gets hotter? That technique is known as tiered compilation, and it is
the technique all JVMs now use. It can be explicitly disabled with the
-XX:-TieredCompilation flag (the default value of which is true); in “Advanced
Compiler Flags” on page 105, we’ll discuss the ramifications of doing that.

——P93-94 《Java Performance——In-Depth Advice for Tuning and Programming Java 8, 11, and Beyond (SECOND EDITION)》

@shining1984
Copy link
Author

In addition, if you still have an old Windows machine with a 32-bit JVM, the total
process size cannot exceed 4 GB. That includes the Java heap, space for all the code of
the JVM itself (including its native libraries and thread stacks), any native memory
the application allocates (either directly or via the New I/O [NIO] libraries), and of
course the code cache.

——P95 《Java Performance——In-Depth Advice for Tuning and Programming Java 8, 11, and Beyond (SECOND EDITION)》

@shining1984
Copy link
Author

shining1984 commented Feb 18, 2022

Tiered Compilation Levels

The compilation log for a program using tiered compilation prints the tier level at
which each method is compiled. In the sample output, code was compiled either at
level 3 or 4, even though we’ve discussed only two compilers (plus the interpreter) so
far. It turns out that there are five levels of compilation, because the C1 compiler has
three levels. So the levels of compilation are as follows:

0
Interpreted code
1
Simple C1 compiled code
2
Limited C1 compiled code
3
Full C1 compiled code
4
C2 compiled code

A typical compilation log shows that most methods are first compiled at level 3: full
C1 compilation. (All methods start at level 0, of course, but that doesn’t appear in the
log.) If a method runs often enough, it will get compiled at level 4 (and the level 3
code will be made not entrant). This is the most frequent path: the C1 compiler waits
to compile something until it has information about how the code is used that it can
leverage to perform optimizations.

If the C2 compiler queue is full, methods will be pulled from the C2 queue and com‐
piled at level 2, which is the level at which the C1 compiler uses the invocation and
back-edge counters (but doesn’t require profile feedback). That gets the method com‐
piled more quickly; the method will later be compiled at level 3 after the C1 compiler
has gathered profile information, and finally compiled at level 4 when the C2 com‐
piler queue is less busy.

On the other hand, if the C1 compiler queue is full, a method that is scheduled for
compilation at level 3 may become eligible for level 4 compilation while still waiting
to be compiled at level 3. In that case, it is quickly compiled to level 2 and then transi‐
tioned to level 4.

Trivial methods may start in either level 2 or 3 but then go to level 1 because of their
trivial nature. If the C2 compiler for some reason cannot compile the code, it will also
go to level 1. And, of course, when code is deoptimized, it goes to level 0.

Flags control some of this behavior, but expecting results when tuning at this level is
optimistic. The best case for performance happens when methods are compiled as
expected: tier 0 → tier 3 → tier 4. If methods frequently get compiled into tier 2 and
extra CPU cycles are available, consider increasing the number of compiler threads;
that will reduce the size of the C2 compiler queue. If no extra CPU cycles are avail‐
able, all you can do is attempt to reduce the size of the application.

——P107-108 《Java Performance——In-Depth Advice for Tuning and Programming Java 8, 11, and Beyond (SECOND EDITION)》

分层编译选项:-XX:+TieredCompilation

@shining1984
Copy link
Author

image
image

From: Zoltan Majo,Hotspot Compiler Team Oracle Corporation, December 2015

@shining1984
Copy link
Author

入门C2最好的材料就是Thomas Würthinger写的关于IdealGraphVisualizer的硕士论文:
Visualization of Program Dependence Graphs, Thomas Würthinger, 2007

C2的整体介绍最好的资料还是原始论文:
The Java HotSpot™ Server Compiler, Michael Paleczny, Christopher Vick, Cliff Click, JVM'01

Overview of Ideal, C2's high level intermediate representation, HotSpot Internals, OpenJDK Wiki
介绍了C2 Ideal Graph的设计思路

From: https://blog.csdn.net/fishmai/article/details/77824224

@shining1984
Copy link
Author

@shining1984
Copy link
Author

调试C1、C2中可能会用到的选项:

printassembly https://wiki.openjdk.java.net/display/HotSpot/PrintAssembly
printoptoassembly
printcompilation

@axiangyushanhaijing
Copy link

axiangyushanhaijing commented Apr 11, 2022

查询资料遇到的一篇C2的交流讨论帖子
c2
IdealGraphVisualizer下载链接

@DingliZhang
Copy link

@zifeihan
Copy link

@shining1984
Copy link
Author

-XX:+LogCompilation
-XX:+PrintOptoAssembly
-XX:
+PrintAssembly print assembly code for bytecoded and native methods
+PrintNMethods print nmethods as they are generated
+PrintNativeNMethods print native method wrappers as they are generated
+PrintSignatureHandlers print native method signature handlers
+PrintAdapterHandlers print adapters (i2c, c2i) as they are generated
+PrintStubCode print stubs: deopt, uncommon trap, exception, safepoint, runtime support
+PrintInterpreter print interpreter code
https://wiki.openjdk.org/display/HotSpot/PrintAssembly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants