RFR: javac support for Parametric VM, first stab [v3]

Maurizio Cimadamore mcimadamore at openjdk.java.net
Fri Mar 12 22:26:20 UTC 2021


On Fri, 12 Mar 2021 17:33:57 GMT, Vicente Romero <vromero at openjdk.org> wrote:

>> This patch is the initial support for Parametric VM in javac. This is the first iteration of the prototype, so still a work in progress. In order to test the new code users need to pass the hidden option: `-XDsupportParametricVM` to javac. See the examples below for an illustration of the bytecode the compiler can generate now. Lets assume we have the following class annotated with the `@Parametric` annotation:
>> 
>> import java.lang.annotation.*;
>> 
>> @Parametric(id="PAIR")
>> class Pair<X, Y> {
>>     @Parametric(id="PAIR")
>>     X fst;
>>     @Parametric(id="PAIR")
>>     Y snd;
>> 
>>     Pair(X fst, Y snd) {
>>         this.fst = fst;
>>         this.snd = snd;
>>     }
>> 
>>     Pair<Y, X> swap() {
>>         return new Pair<>(snd, fst);
>>     }
>> 
>>     @Parametric(id="make", kind=ParamKind.METHOD_ONLY)
>>     static <U, W> Pair<U, W> make(U fst, W snd) {
>>         return new Pair<>(fst, snd);
>>     }
>> 
>>     @Parametric(id="setFst", kind=ParamKind.METHOD_AND_CLASS)
>>     <Z> Pair<Z, Y> setFst(Z newFst) {
>>         return null;
>>     }
>> }
>> 
>> After compilation this class will contain the following new entries in the constant pool:
>> 
>> #22 = Parameter          CLASS:0        // CLASS:0
>> #37 = Parameter          METHOD_ONLY:0  // METHOD_ONLY:0
>> #44 = Parameter          METHOD_AND_CLASS:0 // METHOD_AND_CLASS:0
>> also there will be several elements with the new attribute `Parametric` which will appear in both fields, the `Pair` class per-se and methods: `make` and `setFst`.
>> 
>> Let's now assume we define a Client willing to use class `Pair`, it will need to define values to bound to the "holes" defined in class `Pair` using the `Parametric` annotation. For this class Client should use annotations `@LinkageClass` and or `@LinkageMethod` depending on the kind of hole in class `Pair` it is intending to bound to. Let's define class `Client` as:
>> 
>> import java.lang.annotation.*;
>> 
>> class Client {
>>     @LinkageClass("linkageClass")
>>     void linkClassParams() {
>>         Pair<String, Integer> psi = new Pair<>("first", 2);
>>     }
>> 
>>     @LinkageClass("linkageClass")
>>     void linkClassParamsFieldAccess(Pair<String, Integer> psi) {
>>         psi.fst = "field";
>>     }
>> 
>> 
>>     @LinkageMethod("linkageMethod1")
>>     void linkMethodParams(Pair<String, Integer> psi) {
>>         Pair<String, Integer> pair = Pair.make("hello", 1);
>>     }
>> 
>>     @LinkageClass("linkageClass")
>>     @LinkageMethod("linkageMethod2")
>>     void linkClassAndMethodParams(Pair<String, Integer> psi) {
>>         Pair<String, Integer> pss = psi.setFst("b");
>>     }
>> }
>> 
>> again compiling this class with the hidden option `-XDsupportParametricVM` we can find these new entries in the CP:
>> 
>>    #7 = Linkage            #8:#9          // linkageClass:Pair
>>    #8 = String             #10            // linkageClass
>>    #9 = Class              #11            // Pair
>> 
>> this Linkage CP entry is referred from method: `linkClassParams` as:
>> 
>>   void linkClassParams();
>>     descriptor: ()V
>>     flags: (0x0000)
>>     Code:
>>       stack=4, locals=2, args_size=1
>>          0: new           #7                  // Linkage linkageClass:Pair
>> 
>> also:
>> 
>>   #25 = Linkage            #8:#26         // linkageClass:Pair.fst:Ljava/lang/Object;
>>   #26 = Fieldref           #7.#27         // Pair.fst:Ljava/lang/Object;
>>   #27 = NameAndType        #28:#29        // fst:Ljava/lang/Object;
>> 
>> referred from method: `linkClassParamsFieldAccess` the bytecode looks like:
>> 
>>   void linkClassParamsFieldAccess(Pair<java.lang.String, java.lang.Integer>);
>>     descriptor: (LPair;)V
>>     flags: (0x0000)
>>     Code:
>>       stack=2, locals=2, args_size=2
>>          0: aload_1
>>          1: ldc           #23                 // String field
>>          3: putfield      #25                 // Linkage linkageClass:Pair.fst:Ljava/lang/Object;
>>          6: return
>> 
>> also:
>> 
>>   #32 = Linkage            #33:#34        // linkageMethod1:Pair.make:(Ljava/lang/Object;Ljava/lang/Object;)LPair;
>>   #33 = String             #35            // linkageMethod1
>>   #34 = Methodref          #9.#36         // Pair.make:(Ljava/lang/Object;Ljava/lang/Object;)LPair;
>> 
>> this time referred by method: `linkMethodParams` with bytecode:
>> 
>>   void linkMethodParams(Pair<java.lang.String, java.lang.Integer>);
>>     descriptor: (LPair;)V
>>     flags: (0x0000)
>>     Code:
>>       stack=2, locals=3, args_size=2
>>          0: ldc           #30                 // String hello
>>          2: iconst_1
>>          3: invokestatic  #14                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
>>          6: invokestatic  #32                 // Linkage linkageMethod1:Pair.make:(Ljava/lang/Object;Ljava/lang/Object;)LPair;
>>          9: astore_2
>>         10: return
>> 
>> and finally:
>> 
>>   #41 = Linkage            #42:#43        // linkageMethod2:Pair.setFst:(Ljava/lang/Object;)LPair;
>>   #42 = String             #44            // linkageMethod2
>>   #43 = Methodref          #7.#45         // Pair.setFst:(Ljava/lang/Object;)LPair;
>> 
>> in this last example it can be seen that Methodref at #43 is also pointing to #7 which, as commented above, is another Linkage_info entry in the CP.
>> 
>> TIA, for the feedback and comments,
>> Vicente
>
> Vicente Romero has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains one additional commit since the last revision:
> 
>   associate an id to the Parameter CP

Looks good to me!

-------------

Marked as reviewed by mcimadamore (Committer).

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


More information about the valhalla-dev mailing list