Re: Boxed types and constat propagation

2012-04-21 Thread RĂ©mi Forax
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

2012-04-21 Thread Mark Roos
>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

2012-04-21 Thread Kohsuke Kawaguchi
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

2012-04-21 Thread Julien Ponge
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

2012-04-21 Thread Martijn Verburg
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