3 ms·
The article's wording is a bit misleading here. The first-tier and second-tier compilers are always available throughout the entire lifetime of the program. The
by jdmichal 10y ago
The article's wording is a bit misleading here. The first-tier and second-tier compilers are always available throughout the entire lifetime of the program. The first-tier compiler performs very few optimizations, but compiles very quickly. It is a simple and literal compiler -- most direct translation of byte code to machine code. It's meant to be a quick win to get out of interpreted mode, which is vastly slower. The second-tier compiler is slower, but also takes advantage of the data collected during runtime profiling to make optimizations. Basically, there's a trade-off between the time it takes to run the second-tier compiler and the time it will save. By comparison, the first-tier compiler is almost always a win over interpreted code, even if the code is only run a small number of times.
Now, sometimes optimizations can be "wrong", in the sense that something new has happened that invalidates an assumption used during second-tier compilation. Here's a real-world example: I have an interface and only one loaded class that implements that interface. The second-tier compiler will use this information to basically do this:
function doStuff(MyInterface a) {
if (a.getClass() != MyClass.class)
deoptimize();
// Do everything from here on assuming
// that a is an instance of MyClass.
// This includes inlining simple getter
// methods to pure field accesses, etc.
}
Now, when a second class that implements `MyInterface` is loaded and makes it to that function, it will hit the `deoptimize` branch and go back to first-tier or even interpreted mode. Eventually the function will be recompiled by both tiers with the new assumption -- two implementing classes.
So, in the case of deoptimization, it can be a win to keep the first-tier code to fall-back to.
- __-X-__ 10y agoyes that's the idea ! but your example is wrong because c1 never compile a branch that was not executed before.