[lworld] RFR: Javac support for Parametric VM
Vicente Romero
vromero at openjdk.java.net
Sun Mar 7 00:35:31 UTC 2021
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
-------------
Commit messages:
- javac support for Experimental Parametric VM, first stab
- Merge lworld
Changes: https://git.openjdk.java.net/valhalla/pull/364/files
Webrev: https://webrevs.openjdk.java.net/?repo=valhalla&pr=364&range=00
Stats: 778 lines in 24 files changed: 772 ins; 2 del; 4 mod
Patch: https://git.openjdk.java.net/valhalla/pull/364.diff
Fetch: git fetch https://git.openjdk.java.net/valhalla pull/364/head:pull/364
PR: https://git.openjdk.java.net/valhalla/pull/364
More information about the valhalla-dev
mailing list