Re: Boxed types and constat propagation
See inlined comments :) On 04/22/2012 12:02 AM, Kohsuke Kawaguchi wrote: > Hi, > > I was inspired by the talk by Charles in JAX 2012 and was playing with > invokedynamic a bit. I'm observing what seems like a constant > propagation failure, which I'd imagine would affect some important use > cases, so I wanted to check if I'm not doing something stupid. > > I've used Apache JEXL [1] as my toy "dynamic language". My basic > strategy was to convert an expression into a graph of MethodHandles. > This is a fairly straight-forward process, where each node in the JEXL > AST is converted into function of the type (JexlContext)->Object. > JexlContext represents the context object for an evaluation. > > I then compiled the expression "30+12" to see how well it'd optimize, > which essentially does the following: > > > import static java.lang.invoke.MethodHandles.*; > > public void test1() throws Throwable { > // builds 30+12 as tree > MethodHandle a = constant(Object.class, 30); > MethodHandle b = constant(Object.class, 12); > > MethodHandle h = > lookup().unreflect(getClass().getMethod("add",int.class,int.class)); > MethodHandle r = > foldArguments(foldArguments(h,asReturnType(int.class,a)),asReturnType(int.class,b)); > r = Sandbox.wrap(r); > > assertEquals(42, r.invokeWithArguments()); > } > > public static int add(int a, int b) { > return a+b; > } > > public static MethodHandle asReturnType(Class type, MethodHandle h) { > return h.asType(MethodType.methodType(type,h.type())); > } > > > I was hoping that this would optimize to "return 42", but on my JDK7u3 > on linux-amd64, it only gets optimized to the followig: > > ># {method} 'invokedynamic' '()I' in 'Gen0' ># [sp+0x20] (sp of caller) >0x7f785ca29700: push %rbp >0x7f785ca29701: sub$0x10,%rsp >0x7f785ca29705: nop ;*synchronization entry > ; - Gen0::invokedynamic@-1 >0x7f785ca29706: mov$0x7d66619d8,%r10 ; {oop(a > 'java/ang/nteger' = 30)} >0x7f785ca29710: mov0xc(%r10),%eax >0x7f785ca29714: mov$0x7d66618b8,%r10 ; {oop(a > 'java/ang/nteger' = 12)} >0x7f785ca2971e: add0xc(%r10),%eax ;*iadd > ; - > GuardedIntAddTest::add@2 (line 27) > ; - > java.lang.invoke.MethodHandle::invokeExact@14 > ; - Gen0::invokedynamic@0 >0x7f785ca29722: add$0x10,%rsp >0x7f785ca29726: pop%rbp >0x7f785ca29727: test %eax,0x5b2c8d3(%rip)# 0x7f7862556000 > ; {poll_return} >0x7f785ca2972d: retq > > > So as you can see, 30 and 12 are not recognized as constants. You're right, 30 and 12 are not recognized as int constant but they are recognized as java/lang/Integer constant. 0x7f785ca29706: mov$0x7d66619d8,%r10 ; {oop(a 'java/ang/nteger' = 30)} so escape analysis works but Hotspot doesn't trust final field thus doesn't consider the value in the Integer as a constant. > > I think this would affect dynamic languages that treat primitives and > reference types interchangeably, which is the majority. If I > understand correctly, those languages need to compose method handlers > of the type "(...)->Object", like I did, and rely on the inlining to > discover unnecessary boxing/unboxing. p.18 in JSR 292 cookbook [2] is > affected by this, too, since it uses a similar MethodHandle types. > > > After a few more experiments, I realize the root cause of this isn't > so much as JSR-292 but more in HotSpot. For example, the following > method produces the following assembly code, and as you can see it's > failing to optimize body() into just "return false". In fact, Hotspot doesn't fail. But Hotspot also obfuscates the code :( > So my question is: > > - Am I missing something? yes :) in that case, the body of 'body' is (there is a ret at 0x7fadf244130c) 0x7fadf24412e6: mov$0x7d6602fe0,%r10 ; {oop(a 'java/lang/Class' = 'java/lang/Boolean')} 0x7fadf24412f0: mov0x74(%r10),%r8d;*getstatic FALSE ; - java.lang.Boolean::valueOf@10 (line 149) ; - BoxedBooleanInlineTest::bool1@1 (line 29) ; - BoxedBooleanInlineTest::body@1 (line 21) 0x7fadf24412f4: movzbl 0xc(%r12,%r8,8),%r11d 0x7fadf24412fa: test %r11d,%r11d 0x7fadf24412fd: jne0x7fadf244130d ;*iconst_0 ; - BoxedBooleanInlineTest::body@24 (line 21) 0x7fadf24412ff: xor%
Re: Boxed types and constat propagation
>From Kohsuke Kawaguchi email - How do other language implementers cope with this? We are doing a Smalltalk implementation and have seen that the handling of 'boxed' integers is a possible performance issue. I say possible because while it is an obvious issue for integer intensive operations ( like Hanoi ) our large scale benchmarks run at a similar speed to the native versions. The larger issue in our use of boxed integers ( boxed in our own wrapper) is the object creation and collection overhead. For instance indexing over a million element array involves creating and discarding a million integers. Currently we use a cache plus a mutable integer approach to minimize this but I have yet to really benchmark its performance. The solution to this may lie in FixNums ( ints encoded in pointers ) but that is some time off and may not be of a form useful to us. regards mark ___ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
Boxed types and constat propagation
Hi, I was inspired by the talk by Charles in JAX 2012 and was playing with invokedynamic a bit. I'm observing what seems like a constant propagation failure, which I'd imagine would affect some important use cases, so I wanted to check if I'm not doing something stupid. I've used Apache JEXL [1] as my toy "dynamic language". My basic strategy was to convert an expression into a graph of MethodHandles. This is a fairly straight-forward process, where each node in the JEXL AST is converted into function of the type (JexlContext)->Object. JexlContext represents the context object for an evaluation. I then compiled the expression "30+12" to see how well it'd optimize, which essentially does the following: import static java.lang.invoke.MethodHandles.*; public void test1() throws Throwable { // builds 30+12 as tree MethodHandle a = constant(Object.class, 30); MethodHandle b = constant(Object.class, 12); MethodHandle h = lookup().unreflect(getClass().getMethod("add",int.class,int.class)); MethodHandle r = foldArguments(foldArguments(h,asReturnType(int.class,a)),asReturnType(int.class,b)); r = Sandbox.wrap(r); assertEquals(42, r.invokeWithArguments()); } public static int add(int a, int b) { return a+b; } public static MethodHandle asReturnType(Class type, MethodHandle h) { return h.asType(MethodType.methodType(type,h.type())); } I was hoping that this would optimize to "return 42", but on my JDK7u3 on linux-amd64, it only gets optimized to the followig: # {method} 'invokedynamic' '()I' in 'Gen0' # [sp+0x20] (sp of caller) 0x7f785ca29700: push %rbp 0x7f785ca29701: sub$0x10,%rsp 0x7f785ca29705: nop ;*synchronization entry ; - Gen0::invokedynamic@-1 0x7f785ca29706: mov$0x7d66619d8,%r10 ; {oop(a 'java/ang/nteger' = 30)} 0x7f785ca29710: mov0xc(%r10),%eax 0x7f785ca29714: mov$0x7d66618b8,%r10 ; {oop(a 'java/ang/nteger' = 12)} 0x7f785ca2971e: add0xc(%r10),%eax ;*iadd ; - GuardedIntAddTest::add@2 (line 27) ; - java.lang.invoke.MethodHandle::invokeExact@14 ; - Gen0::invokedynamic@0 0x7f785ca29722: add$0x10,%rsp 0x7f785ca29726: pop%rbp 0x7f785ca29727: test %eax,0x5b2c8d3(%rip)# 0x7f7862556000 ; {poll_return} 0x7f785ca2972d: retq So as you can see, 30 and 12 are not recognized as constants. I think this would affect dynamic languages that treat primitives and reference types interchangeably, which is the majority. If I understand correctly, those languages need to compose method handlers of the type "(...)->Object", like I did, and rely on the inlining to discover unnecessary boxing/unboxing. p.18 in JSR 292 cookbook [2] is affected by this, too, since it uses a similar MethodHandle types. After a few more experiments, I realize the root cause of this isn't so much as JSR-292 but more in HotSpot. For example, the following method produces the following assembly code, and as you can see it's failing to optimize body() into just "return false". So my question is: - Am I missing something? - Is there any reason behind why HotSpot fails to treat boxed constants like real constants? Is that because HotSpot doesn't trust 'final'? - How do other language implementers cope with this? public boolean body() { return bool1() && bool2(); } private Boolean bool2() { return true; } private Boolean bool1() { return false; } # {method} 'body' '()Z' in 'BoxedBooleanInlineTest' # [sp+0x20] (sp of caller) 0x7fadf24412c0: mov0x8(%rsi),%r10d 0x7fadf24412c4: shl$0x3,%r10 0x7fadf24412c8: cmp%r10,%rax 0x7fadf24412cb: jne0x7fadf24138a0 ; {runtime_call} 0x7fadf24412d1: xchg %ax,%ax 0x7fadf24412d4: nopl 0x0(%rax,%rax,1) 0x7fadf24412dc: xchg %ax,%ax [Verified Entry Point] 0x7fadf24412e0: push %rbp 0x7fadf24412e1: sub$0x10,%rsp 0x7fadf24412e5: nop ;*synchronization entry ; - BoxedBooleanInlineTest::body@-1 (line 21) 0x7fadf24412e6: mov$0x7d6602fe0,%r10 ; {oop(a 'java/ang/lass' = 'java/ang/oolean')} 0x7fadf24412f0: mov0x74(%r10),%r8d;*getstatic FALSE ; - java.lang.Boolean::valueOf@10 (line 149) ; - BoxedBooleanInlineTest::bool1@1 (line 29)
Re: [jvm-l] Clever uses of InvokeDynamic
Maybe I'm a bit late into the game, but we demoed with Frederic Le Mouel at Devoxx France an early prototype of a dynamic AOP JVM agent called JooFlux that takes advantage of invokedynamic. It's still a research project at this stage, but we will eventually publish this and release the code as an opensource project. Cheers On Tue, Apr 17, 2012 at 7:30 PM, Charles Oliver Nutter wrote: > I'm filling out the remaining slides in my JAX keynote on > InvokeDynamic, and I'm interested in additional "clever" uses of > invokedynamic folks have discovered. > > I have included the following, which we make use of in JRuby: > > * Dynamic invocation (obviously) > * Lazy constants > * Multiple dispatch > > I'll also make a brief mention of MethodHandle as a replacement for > java.lang.reflect stuff. > > Other good ones for a room full of people learning invokedynamic for > the first time? > > - Charlie > > -- > You received this message because you are subscribed to the Google Groups > "JVM Languages" group. > To post to this group, send email to jvm-langua...@googlegroups.com. > To unsubscribe from this group, send email to > jvm-languages+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/jvm-languages?hl=en. > -- Julien Ponge http://julien.ponge.info/ ___ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
Re: OSX port
This would be extremely helpful in being able to organise hack nights with the Java User Groups globally to beat up on an experimental feature and provide feedback on it here (such as coroutines). Cheers, Martijn On 20 April 2012 00:27, Henri Gomez wrote: > Hi to all, > > I'm wondering when OSX support will be merged in mlvm trunk. > > I'm releasing OSX packages for stock Java 8, jigsaw and lambda easily now > but mlvm build is still too tricky and a pain. > > Any chance to get OSX code merged so OSX Java 8 early adopters could play > with Continuous packages as they do with others Java 8 projects ? > > Cheers > ___ > mlvm-dev mailing list > mlvm-dev@openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > ___ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev