jdart - oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · use a linear*...
TRANSCRIPT
![Page 1: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/1.jpg)
JDart
https://github.com/Geozz/DartRuntime
Rémi ForaxJVM Summit'12
![Page 2: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/2.jpg)
Dart in one slide
Dynamic Language2 runtimes : DartVM / Dart2js
Less dynamic than Java ?
Better JavaScriptScope done right,
classes, no_such_method, mirrors
Optionally typestypes are mostly for documentation
checked modeIntegers are nullable and infinite
![Page 3: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/3.jpg)
DartVM
Derived from V8
Not a production VM (yet!)
Client VM / 32 bits only
Two tiers compiler
Use tagged pointer (small integer/reference)
Far better than Java boxing !
![Page 4: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/4.jpg)
Example on Fibonacci
int fibo(n) { if (n < 2) return 1; return fibo(n-1) + fibo(n-2);}
main() { fibo(7);}
![Page 5: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/5.jpg)
In assembler – simple code
0xf3108f0a push [ebp+0x8]0xf3108f0d push 0x20xf3108f12 mov ecx,0xf31b8f11 'ICData target:-'0xf3108f17 mov edx,0xf331d279 Array[2, 2, null]0xf3108f1c call 0xf3100230 [stub: TwoArgsCheckInlineCache]0xf3108f21 add esp,0x80xf3108f24 push eax0xf3108f25 mov ecx,0xf31b8ca1 'Function 'fibo': static.'0xf3108f2a mov edx,0xf31a1ba9 Array[1, 1, null]0xf3108f2f call 0xf5600420 [stub: CallStaticFunction]0xf3108f34 add esp,0x40xf3108f37 push eax
0xf3108f38 push [ebp+0x8]0xf3108f3b push 0x4... ; same code again !0xf3108f66 mov ecx,0xf31b8fd1 'ICData target:+'0xf3108f6b mov edx,0xf331d279 Array[2, 2, null]0xf3108f70 call 0xf3100230 [stub: TwoArgsCheckInlineCache]0xf3108f75 add esp,0x80xf3108f78 push eax0xf3108f79 pop eax0xf3108f7a mov ebx,0xf31b8ca1 'Function 'fibo': static.'0xf3108f7f inc [ebx+0x43]0xf3108f82 cmp [ebx+0x43],0x7d00xf3108f89 jng 0xf3108f9e
![Page 6: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/6.jpg)
In assembler - optimized
0xf3109005 mov eax,[ebp+0x8]0xf3109008 mov edx,0x20xf310900d mov ecx,eax0xf310900f test al,0x10xf3109011 jnz 0xf31090830xf3109017 sub eax,edx0xf3109019 jo 0xf31090830xf310901f push eax0xf3109020 mov ecx,0xf31b8ca1 'Function 'fibo': static.'0xf3109025 mov edx,0xf31a1ba9 Array[1, 1, null]0xf310902a call 0xf5600420 [stub: CallStaticFunction]0xf310902f add esp,0x40xf3109032 push eax
0xf3109033 mov eax,[ebp+0x8]0xf3109036 mov edx,0x4... ; same code again0xf310905b mov ecx,eax0xf310905d or eax,edx0xf310905f test al,0x10xf3109061 jnz 0xf310909b0xf3109067 mov eax,ecx0xf3109069 add eax,edx0xf310906b jo 0xf310909b0xf3109071 mov esp,ebp0xf3109073 pop ebp0xf3109074 ret
![Page 7: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/7.jpg)
Dart on the JVM
Dart on server
uses invokedynamic !
but avoid useless boxing● precise static type analysis
(done offline currently)● split-path trick
![Page 8: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/8.jpg)
![Page 9: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/9.jpg)
JDart static analysis
Use a linear* interprocedural type flow analysis before generating bytecode
Don't use declared type by default
Can be used in rare cases in checked mode
Works with an horizon, try to share/reuse analysis
Analysis not done more than K times by method (actually K=4)
* almost :)
![Page 10: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/10.jpg)
Example on Fibonacci
int fibo(n [7]) { if (n < 2) return 1; return fibo(n -1 [6]) + fibo(n-2);}
main() { fibo(7);}
![Page 11: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/11.jpg)
Example on Fibonacci
int fibo(n [7]) { if (n < 2) return 1; return fibo(n -1 [6]) + fibo(n-2);}
int fibo(n [0, +inf]) { if (n < 2) return 1; // return type [1] return fibo(n [2, +inf] -1) + fibo(n-2);}
main() { fibo(7);}
![Page 12: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/12.jpg)
Example on Fibonacci
int fibo(n [7]) { if (n < 2) return 1; return fibo(n -1 [6]) + fibo(n-2);}
int fibo(n [0, +inf]) { if (n < 2) return 1; // return type = [1] return [-inf, +inf]? + fibo(n-2 [0, +inf]); // return type = [-inf, +inf]}
main() { fibo(7);}
![Page 13: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/13.jpg)
Example on Fibonacci
int fibo(n [7]) { if (n < 2) return 1; return fibo(n -1 [6]) [-inf, +inf] + fibo(n-2 [5]) [-inf, +inf];}
[-inf, +inf] int fibo(n [0, +inf]) { if (n < 2) return 1; // return type = [1] return [-inf, +inf]? + fibo(n-2 [0, +inf]); // return type = [-inf, +inf]}
main() { fibo(7);}
![Page 14: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/14.jpg)
Example on Fibonacci
[-inf, +inf] int fibo(n [7]) { if (n < 2) return 1; return fibo(n -1 [6]) [-inf, +inf] + fibo(n-2) [-inf, +inf];}
[-inf, +inf] int fibo(n [0, +inf]) { if (n < 2) return 1; // return type = [1] return [-inf, +inf]? + fibo(n-2 [0, +inf]); // return type = [-inf, +inf]}
main() { fibo(7);} We can remove the first fibo because
fibo([7]) doesn't offer a more precise return type
![Page 15: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/15.jpg)
Split-path generation
Methods that takes an int > int32 are compiled in two methods
If return type is int, int32 will be used and overflow values will use a thread local exception
In the method, ints are compiled using two variables (int32 and BigInt) if BigInt is null, value is int32
Overflow detection is added where neededusing the profile
![Page 16: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/16.jpg)
Fibo in pseudo Java
private static int fibo(int n) { if (n < 2) return 1; int r1; BigInt _r1; try { r1 = invokedynamic fibo(n -1); _r1 = null; } catch(ControlFlowException e) { r1 = 0; _r1 = e.value; } int r2; BigInt _r2; try { r2 = invokedynamic fibo(n -2); _r2 = null; } catch(ControlFlowException e) { r2 = 0; _r2 = e.value; } int r3; BigInt _r3; if (_r1 == null && _r2 == null) try { r3 = RT.addExact(r1, r2); _r3 = null; } catch(ArithmeticException e) { _r3 = invokedynamic addOverflowed(r1, r2); r3 = 0; } else _r3 = invokedynamic addBig(r1, _r1, r2, _r2); r3 = 0; if (_r3 == null) return r3; throw ControlFlowException.valueOf(_r3); }
![Page 17: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/17.jpg)
In assembler
...fd4c: mov %esi,(%rsp)
...fd4f: cmp $0x2,%esi
...fd52: jl ...fda1 ;*if_icmpge
...fd54: dec %esi ;*isub
...fd57: callq 0x00007f6459038060 ;*invokestatic fibo
...fd5c: mov %eax,0x4(%rsp)
...fd60: mov (%rsp),%esi
...fd63: add $0xfffffffffffffffe,%esi ;*isub
...fd67: callq 0x00007f6459038060 ;*invokestatic fibo
...fd6c: mov %eax,%r9d
...fd6f: mov 0x4(%rsp),%eax
...fd73: add %r9d,%eax
...fd76: mov 0x4(%rsp),%r11d
...fd7b: xor %eax,%r11d
...fd7e: mov %r9d,%r8d
...fd81: xor %eax,%r8d
...fd84: and %r8d,%r11d
...fd87: test %r11d,%r11d
...fd8a: jge ...fda6 ;inline RT.addExact
...fd8c: mov $0xa5,%esi
...fd91: mov %r9d,(%rsp)
...fd95: xchg %ax,%ax
...fd97: callq 0x00007f6459039020 ; deoptimization
...fda1: mov $0x1,%eax
fast path ??
![Page 18: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/18.jpg)
Execution time !Fibo(40) in second
DartVM Java boxing JDart (no inline) JDart Java (int only)0
2
4
6
8
10
12
14
16
18
1.65
15.26
0.93 0.69 0.73
Smaller is better
![Page 19: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/19.jpg)
Questions ?
![Page 20: JDart - Oraclecr.openjdk.java.net/~forax/jvmsummit2012/jvmsummit12.pdf · Use a linear* interprocedural type flow analysis before generating bytecode Don't use declared type by default](https://reader034.vdocuments.site/reader034/viewer/2022050210/5f5cee062281505ece252c1b/html5/thumbnails/20.jpg)
Image Credits
Phone booth by Louis du Monshttp://www.flickr.com/photos/2create/4433423854/
Overflow by James Whitesmithhttp://www.flickr.com/photos/jwhitesmith/7430605966/