Tiered Attribution for javac – Java 9

In Java 8, the implementation of type-checking at compiler level was based on Speculative Attribution. In Speculative Attribution, the same tree can be type-checked against multiple targets at runtime. This is particularly used in target typing for lambda expressions, resolving diamond expressions for generics, etc.

To understand more about target typing in lambda expressions, we need to learn a bit about lambda expressions. In languages that support functional programming, the type of a lambda expression would be a function. But in case of Java, a lambda expression can be an instance of a Functional Interface. From a lambda expression alone, we cannot deduce which functional interface it is implementing. Instead, we get that information from the context.

The following is a valid lambda expression:

The above lambda expression  can be an instance of the following functional interface:

Thus, we can write:

In the above statement, the RHS is of type StringConcat. This is known as target type for the lambda expression. But the same expression can be compatible with another interface like the following:

So, the following expression is also valid:

Need for Tiered Attribution

As we saw in the previous example, there may be instances in which the compiler will have to perform type checking for multiple target types. This is a very important capability but can result in performance issues because of redundant steps done in the process.

The exponential number of calls to the speculative attribution machinery has resulted in performance issues that have been observed and reported as bugs, e.g., JDK-8077247JDK-8078093 and JDK-8055984

A JDK Enhancement Proposal (JEP 215) was proposed for type checking of poly expressions. The newly proposed way is known as Tiered Attribution. It focuses on improving performance by implementing a different way of type-checking that reduces redundant steps but gives the same results as current type-checking implementation.

Tiered Attribution aims at producing ahead of overload resolution, bottom up structural types with all information needed for resolving overloaded types and perform compatibility check during compilation. For each poly argument expression, a corresponding structural type will be created. New structural types will be created for lambda expressions, conditional poly expressions, generic method calls, parenthesized expressions, diamond instance creation expressions in case of generics, etc.

It is possible for a structural type to mention another structural type within itself if the expression that corresponds to structural type supports some type of nesting or looping.

Changes were incorporated as a part of a feature implementation as mentioned here. The changes are incorporated at compiler level to javac tool and delivered in Java 9.

Leave a Reply