This week's book giveaway is in the Kotlin forum.
We're giving away four copies of Kotlin in Action and have Dmitry Jemerov & Svetlana Isakova on-line!
See this thread for details.
Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

HotSpot VM: Questions about how it compiles and inlines code.  RSS feed

 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello:

I've several questions with regard to how the compilers in the HotSpot VM work. I hope that you can help me, because I suspect that I may have misunderstood some concepts. These are my doubts:

1. I've run HotSpot with the option -XX:+PrintCompilation and I've seen that the same method is listed several times. Excluding the "not entrant" lines, Does it mean that it's re-compiled with more aggressive optimizations each time? If so, Are these optimizations applied to the bytecode version or are they applied directly to the assembly code that was already compiled the previous time?

2. Later I've used the options -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining. I've methodA() that calls methodB(), that in turn calls methodC(). Suppose that methodC() is compiled. Later, methodB() is compiled too, being methodC() inlined into it. Finally, methodA() is compiled, and methodB() is inlined there. How does the last inlining occur? Does the compiler compile methodA() and then "injects" the compiled version of methodB() that already existed? Or does it work with the bytecode versions, inlining methodB() in methodA(), also the descendant calls that can be inlined, and the compiling the whole result? Or can both scenarios happen: inlining bytecode and compiled code (separately)? If so, How to differentiate they both in the output?

3. How to interpret that branches outputted by -XX:+PrintInlining that haven't got any concrete suffix such as "hot" or "callee is too large"? Do they correspond just to an analysis?

4. Does a tree outputted by -XX:+PrintInlining correspond to the preceding line outputted -XX:+PrintCompilation? Or they don't keep any relation? If thought that they did, but I've seen certain incoherences in their order :S .

Thank you!
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When I mentioned incoherences in the order of the output of -XX:+PrintInlining, I meant that some inlinings seemed to occur in wrong places. For example, I saw the inlining of HashMap::put() in one of my methods, despite I didn't use it at all nor it was used in descending method calls.

I've been digging in the output again, and I believe that the inconsistencies are because I'm running Oracle JDK 8 64-bit, which uses tiered compilation by default. So the C1 and C2 compilers work in parallel and sometimes their output messages get mixed. I've came to this conclusion after learning the meaning of the numbers outputted by -XX:+PrintCompilation. To do so, I've read this article by Kris Mok. In HotSpot (as of Java 1.8.0-25), the third figure means the tier or type of compiler that compiles the method. In the output of my program I've seen the figures 0 (interpreter), 1, 2 and 3 (C1 compiler) and also 4 (C2 compiler). Just in the parts of the output where there have been messages of the C2 compiler, the output of -XX:+PrintInlining has gotten messed. So I guess that's the explanation of these apparent incoherences.

On the other hand, I've tried to find information about how the inlining occurs, either at the bytecode level or the machine code level. I believe that it's at the bytecode level because there is an option called -XX:MaxInlineSize, which sets the maximum amount of bytecode of a method so that it can be inlined. But there's also the option -XX:InlineSmallCode, which sets a limit by the size of the generated native code. So it's a little confusing...

I've been reading about how modern compilers work (in its broadest sense), and I've found out that many of the optimizations are applied to an intermediate form of code, which is between the source code and the native code. This is done that way because it's easier to apply certain optimizations and they can cover a bigger context. In the case of HotSport I guess that, because the bytecode is itself an intermediate type of code, it can be used (and it's used) by the JIT compiler to apply almost all optimizations. Am I right?

If that's the way it works, now my doubt is how the compiler inlines a tree of methods in which all them can be inlined. Resuming the example of my question #2, and supposing that the methodC() has already been inlined in the methodB() and compiled, What does it occur when the methodB() is inlined in the methodA():

a. Does the JIT compiler keep a copy of the bytecode of the methodB() with the methodC() inlined into it and re-uses it?

b. Does it start from the scratch, inling the whole tree of methods from the methodA() to the deepest method that can be inlined, one by one?

c. Does it compile methodA() as is, takes the compiled version of the methodB() and "injects" it in the compiled version of methodA()? This would contradict my supposition that the most of the optimizations occur at the bytecode level, but it's a reason for the existence of the option -XX:InlineSmallCode.

Thank you.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Avor Nadal wrote:I've several questions with regard to how the compilers in the HotSpot VM work...

I've looked over your posts, and all I can say is "ooof".

I've been a programmer for over 35 years (13 with Java), and I've never found a need to know even a fraction of the level of detail you appear to want - in any language (Java's my 6th). And I suspect that the reason you haven't received any replies is that very few other people here have either ... or maybe they're just working off their holiday hangovers before they tackle a subject as involved as this.

My question is: Why do need (or think you need) to know this? Intellectual curiosity (and there's nothing wrong with that)? Or do you want you write your own compiler? Either way, I think some Googling might help you out. A simple "how does the Java compiler work?" netted me this StackOverflow link right at the top, which contains a few others you might find useful. And the Wiki page contains this one which might also help.

And adding "hotspot", gets you this link, which may even be a bit more targeted.

However, as to your specific questions: I'm afraid I can't help you out with a single one, because I've simply never needed the information.

HIH

Winston
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:I've been a programmer for over 35 years (13 with Java), and I've never found a need to know even a fraction of the level of detail you appear to want - in any language (Java's my 6th). And I suspect that the reason you haven't received any replies is that very few other people here have either ... or maybe they're just working off their holiday hangovers before they tackle a subject as involved as this.

Ha ha ha. I would prefer it were the latter :P .

Winston Gutkowski wrote:My question is: Why do need (or think you need) to know this? Intellectual curiosity (and there's nothing wrong with that)? Or do you want you write your own compiler?

It's simply a matter of curiosity. I've a very limited knowledge about compilers, specially JIT compilers. So these days I've been reading a few articles about HotSpot and about compilers in general, as well as the type of optimizations that they can do. While I was "playing" with the output of HotSpot, this doubt about the method inlining came up.

I wish it sufficed for me to know that HotSpot can do it... But my way of being pushes me to want to know how it does it, he he he. I'll try searching in the links that you've provided me. Although I believe that I already checked in Java.net. As always, thank you for your help ;) .
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Avor Nadal wrote:I wish it sufficed for me to know that HotSpot can do it... But my way of being pushes me to want to know how it does it...

Which suggests to me - and don't take this the wrong way - that Java may be the wrong language for you; and you might be better off with something like C or C++.

The whole ethos of Object-Orientation is that users shouldn't know HOW everything works; and Java takes it a stage further by being platform-independent, and so even hiding details about the machine and the compiler and memory management from you.

The fact is that you're not supposed to know this stuff - and you certainly mustn't rely on any information you find out about it - because, as likely as not, it might change in the next release of the compiler or JVM.

Just as an example, you may be interested to know that:
"The Java Virtual Machine does not mandate any particular internal structure for objects." − JVM spec, Chapter 2 (emphasis mine).

And while it might be frustrating for you, it frees up the developers of Java to completely rewrite major sections of the compiler and JVM without telling you; which is just one of the reasons it's improved so much over the years. Back in the early days, Java had a reputation for being slow; but now it rivals (and sometimes even exceeds) machine-compiled languages like C.

Sometimes, "not knowing how" can be a help...

HIH

Winston
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!