20
JDart https://github.com/Geozz/DartRuntime Rémi Forax JVM Summit'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

  • Upload
    others

  • View
    12

  • Download
    0

Embed Size (px)

Citation preview

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

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

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

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

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

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

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

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
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

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

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

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

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

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

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

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

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

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

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

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

Image Credits

Phone booth by Louis du Monshttp://www.flickr.com/photos/2create/4433423854/

Overflow by James Whitesmithhttp://www.flickr.com/photos/jwhitesmith/7430605966/