Why JVM can not type infer type params but javac can do?
Paul Sandoz
paul.sandoz at oracle.com
Thu Jan 8 11:46:51 UTC 2015
On Jan 8, 2015, at 9:54 AM, Ali Ebrahimi <ali.ebrahimi1781 at gmail.com> wrote:
> Hi, maybe this is stupid question, but want to ask and what is requirements
> for this?
>
> Array instantiation sample:
> public <any T> T[] newArray(int){
> return new T[0];
> }
>
> even for non-any T:
> public <T> T[] newArray(int){
> return new T[0];
> }
>
> With thousands number of optimization and inlining mechanics equipped in
> jvm, What is the reasoning behind not allowing to jvm to be aware of
> generics info emitted in classfilles?
>
> Why jvm should not able do following inlining?
>
> String[] strs = newArray(int) => String[] strs = new String[0];
> I mean even in jitted code.
>
> I think some time ago I read some papers in similar area.
Try compiling the following:
public class A {
static <any T> T[] array(int s) {
return new T[s];
}
static int[] intArray(int s) {
return array(s);
}
public static void main(String[] args) throws Throwable {
int sum = 0;
for (int i = 0; i < 1000000; i++) {
int[] ia = intArray(0);
sum += ia.length;
}
System.out.println(sum);
}
}
Then run with:
java -XX:-TieredCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining -Dvalhalla.dumpProxyClasses=. A
You should see an inline trace such as:
@ 11 A::intArray (7 bytes) inline (hot)
@ 1 java.lang.invoke.LambdaForm$MH/1389133897::linkToTargetMethod (9 bytes) force inline by annotation
@ 5 java.lang.invoke.LambdaForm$DMH/321001045::invokeStatic_I_L (14 bytes) force inline by annotation
@ 1 java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes) force inline by annotation
@ 10 A$array${0=I}/1922154895::array (4 bytes) inline (hot)
Look at the specialized class holding the specialized the method:
javap -p -v A\$array\$\{0\=I\}.1922154895.class
and you will see:
static int[] array(int);
descriptor: (I)[I
flags: ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: iload_0
1: newarray int
3: areturn
It all inlines rather nicely.
At the moment you will get a ClassCastException if you use a ref, such as String, since javac currently compiles the array method to:
static <T extends java.lang.Object> T[] array(int);
descriptor: (I)[Ljava/lang/Object;
flags: ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: iload_0
1: anewarray #2 // class java/lang/Object
4: areturn
LineNumberTable:
line 4: 0
BytecodeMapping:
Code_idx Signature
1: [TT;
Signature: #18 // <T:Ljava/lang/Object;>(I)[TT;
TypeVariablesMap:
LA;::array(I)[Ljava/lang/Object;:
Tvar Flags Erased bound
T [ANY] Ljava/lang/Object;
That method is not specalized for refs (nor is T reified in such cases). There are some nasty edge cases w.r.t. arrays that need to be solved at some point.
Paul.
More information about the valhalla-dev
mailing list