[lworld] RFR: 8244227: [lworld] Explore an implementation where the reference projection and value projection types are backed by a single class symbol

Maurizio Cimadamore mcimadamore at openjdk.java.net
Thu Apr 1 15:55:38 UTC 2021

On Wed, 31 Mar 2021 12:32:04 GMT, Srikanth Adayapalam <sadayapalam at openjdk.org> wrote:

> This PR overhauls the existing implementation/representation of reference projection types  and the inline types so that both share the same underlying symbol, much like how an infinite family of parameterized types that originate from the same generic type are modelled using the same underlying symbol.

This seems like a good cleanup overall. IMHO the issues can be bucketized as follows:

* some more experiment is required to see if we can avoid changing asSuper too much
* there is a bigger issue (which we'll have to confront with, sooner or later, because of specialization) regarding type erasure kicking in too early, and subsequent pipeline steps only dealing with symbol (not type) info

Since the approach moves things in the way generic types are modeled, I'm not surprised to see some of the issues I had to face when writing a backend for the specializer compiler pop back here. I'd say, for now, let's try to deal with the first bullet (which is localized with these changes), and let's come back (in a separate PR) with some workaround for the second bullet (perhaps borrowing some old valhalla code?).

src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java line 2202:

> 2200:      * @param s a type
> 2201:      */
> 2202:     public Type asSuper(Type t, Type s) {

A possible approach here (discussed offline) would be to leave asSuper as it is today - e.g. assume that asSuper speaks about "extends/implements" clause, and deal with .ref vs. .val mismatches at the callsite (if possible) - e.g. in Types::isSubtypes.

src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java line 2572:

> 2570:             public Type visitClassType(ClassType t, Boolean recurse) {
> 2571:                 // erasure(projection(primitive)) = projection(erasure(primitive))
> 2572:                 Type erased = eraseClassType(t, recurse);

Random non-code comment: this seems a case of erasure applied to early. The first time that happens in lworld, but in the old branch which featured generic specializations, at some point we decided to postpone type erasure, as we needed sharp generic types during code gen. This smells like more of the same - e.g. having to fight with erasure so that the info that we care about is preserved in some form.

src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java line 552:

> 550: 
> 551:             case ';': {         // end
> 552:                 name = names.fromUtf(signatureBuffer,

This is another bit which might get simpler if we end up generating only a single .class.

src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java line 1540:

> 1538: 
> 1539:         // where
> 1540:         private static ClassSymbol getReferenceProjection(ClassSymbol c) {

Maybe one day we will be able to remove this...


PR: https://git.openjdk.java.net/valhalla/pull/375

More information about the valhalla-dev mailing list