More performance explorations

Charles Oliver Nutter headius at headius.com
Fri May 27 08:04:17 PDT 2011


Two threads going now, so I'm going to move exploration and discussion
to this one.

So, I'm reading through MLVM versus 5/13 macosx build amd64 ASM output...

First difference, the < operator logic:

On macosx build:

  4619030327: jl     4619034359                 ;*ifge
                                                ; -
org.jruby.RubyFixnum::op_lt at 10 (line 883)
                                                ; -
org.jruby.runtime.callsite.LtCallSite::call at 24 (line 16)
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 14 (line 4)
  4619030333: mov    0x88(%r12,%r11,8),%r10d    ;*areturn
                                                ; -
org.jruby.RubyBoolean::newBoolean at 15 (line 104)
                                                ; -
org.jruby.RubyFixnum::op_lt at 18 (line 883)
                                                ; -
org.jruby.runtime.callsite.LtCallSite::call at 24 (line 16)
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 14 (line 4)
  4619030341: shl    $0x3,%r10                  ;*invokevirtual call
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 14 (line 4)
...
  4619034359: mov    0x84(%r12,%r11,8),%r10d    ;*getfield trueObject
                                                ; -
org.jruby.Ruby::getTrue at 1 (line 1750)
                                                ; -
org.jruby.RubyBoolean::newBoolean at 5 (line 104)
                                                ; -
org.jruby.RubyFixnum::op_lt at 18 (line 883)
                                                ; -
org.jruby.runtime.callsite.LtCallSite::call at 24 (line 16)
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 14 (line 4)
  4619034367: jmpq   4619030341

And on MLVM:

  0x00000001028ac459: jl     0x00000001028ac465  ;*ifge
                                                ; -
org.jruby.RubyFixnum::op_lt at 10 (line 883)
                                                ; -
org.jruby.runtime.callsite.LtCallSite::call at 24 (line 16)
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 14 (line 4)
  0x00000001028ac45b: mov    0x88(%r12,%r11,8),%r10d  ;*getfield falseObject
                                                ; -
org.jruby.Ruby::getFalse at 1 (line 1757)
                                                ; -
org.jruby.RubyBoolean::newBoolean at 12 (line 104)
                                                ; -
org.jruby.RubyFixnum::op_lt at 18 (line 883)
                                                ; -
org.jruby.runtime.callsite.LtCallSite::call at 24 (line 16)
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 14 (line 4)
  0x00000001028ac463: jmp    0x00000001028ac46d
  0x00000001028ac465: mov    0x84(%r12,%r11,8),%r10d  ;*areturn
                                                ; -
org.jruby.RubyBoolean::newBoolean at 15 (line 104)
                                                ; -
org.jruby.RubyFixnum::op_lt at 18 (line 883)
                                                ; -
org.jruby.runtime.callsite.LtCallSite::call at 24 (line 16)
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 14 (line 4)

So for whatever reason, macosx and mlvm differ in whether they decide
to load the falseObject or the trueObject for the result of the test.
FWIW, I do intend to use invokedynamic to patch through
boolean-returning calls wherever I'm looking for a boolean value, so
hopefully the use of RubyBoolean and the interface call to isTrue will
go away soon.

Difference number two, how much logic is there before we reach the
first GWT test for recursive fib_ruby call...

On macosx, starting from the end of the RubyFixnum::op_minus call:

  4619030611: shl    $0x3,%r9                   ;*invokevirtual op_minus
                                                ; -
org.jruby.runtime.callsite.MinusCallSite::call at 24 (line 16)
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 48 (line 7)
  4619030615: mov    %r9,0x98(%rsp)             ;*invokevirtual call
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 48 (line 7)
  4619030623: movsd  -0x1df(%rip),%xmm1        # 4619030152
                                                ;   {section_word}
  4619030631: movabs $0x7dc80ac78,%r10          ;   {oop(cache [57]
for constant pool [260]/invokedynamic/operands[4] for
'bench/bench_fib_recursive' cache=0x00000007dc80ac78)}
  4619030641: mov    0x628(%r10),%r10
  4619030648: mov    0x14(%r10),%r8d
  4619030652: cmp    $0xfebb3c3a,%r8d           ;   {oop(a
'java/lang/invoke/AdapterMethodHandle')}
  4619030659: jne    4619040931                 ;*invokedynamic
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 51 (line 7)
  4619030665: mov    0x88(%rsp),%r10
  4619030673: mov    0x8(%r10),%r11d            ; implicit exception:
dispatches to 4619042117
  4619030677: mov    0x40(%r12,%r11,8),%r10
  4619030682: mov    %r10,0x18(%rsp)
  4619030687: movabs $0x7dbcfe460,%r11          ;
{oop('org/jruby/RubyBasicObject')}
  4619030697: cmp    %r11,%r10
  4619030700: jne    4619036937
  4619030706: mov    0x88(%rsp),%r10            ;*checkcast
                                                ; -
org.jruby.runtime.invokedynamic.InvokeDynamicSupport::test at 2 (line
854)
                                                ; -
java.lang.invoke.MethodHandle::invokeExact at 15
                                                ; -
java.lang.invoke.MethodHandleImpl$GuardWithTest::invoke_L5 at 11 (line
865)
                                                ; -
java.lang.invoke.MethodHandle::invokeExact at 8
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 51 (line 7)

And now on MLVM:

  0x00000001028ac57e: shl    $0x3,%rax          ;*invokevirtual op_minus
                                                ; -
org.jruby.runtime.callsite.MinusCallSite::call at 24 (line 16)
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 48 (line 7)
  0x00000001028ac582: mov    %rax,0x98(%rsp)    ;*invokevirtual call
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 48 (line 7)
  0x00000001028ac58a: movabs $0x7dc7991b8,%r10  ;   {oop(cache [57]
for constant pool [260]/invokedynamic/operands[4] for
'bench/bench_fib_recursive' cache=0x00000007dc7991b8)}
  0x00000001028ac594: mov    0x628(%r10),%r10
  0x00000001028ac59b: mov    0x14(%r10),%r8d
  0x00000001028ac59f: cmp    $0xfeba9520,%r8d   ;   {oop(a
'java/lang/invoke/AdapterMethodHandle')}
  0x00000001028ac5a6: jne    0x00000001028b00d9  ;*invokedynamic
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 51 (line 7)
  0x00000001028ac5ac: mov    0x98(%rsp),%r10
  0x00000001028ac5b4: mov    0x8(%r10),%r10d    ; implicit exception:
dispatches to 4337632029
  0x00000001028ac5b8: mov    0x28(%r12,%r10,8),%r9
  0x00000001028ac5bd: lea    (%r12,%r10,8),%r11
  0x00000001028ac5c1: movabs $0x7dbccf760,%r8   ;
{oop('org/jruby/runtime/builtin/IRubyObject')}
  0x00000001028ac5cb: cmp    %r8,%r9
  0x00000001028ac5ce: jne    0x00000001028adae3  ;*checkcast
                                                ; -
java.lang.invoke.MethodHandle::invokeExact at 2
                                                ; -
java.lang.invoke.MethodHandleImpl$GuardWithTest::invoke_L5 at 11 (line
987)
                                                ; -
java.lang.invoke.MethodHandle::invokeExact at 9
                                                ; -
java.lang.invoke.MethodHandle::invokeExact at 8
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 51 (line 7)
  0x00000001028ac5d4: mov    0x70(%rsp),%r8
  0x00000001028ac5d9: mov    0x8(%r8),%r8d      ; implicit exception:
dispatches to 4337632069
  0x00000001028ac5dd: mov    %r8d,0x18(%rsp)
  0x00000001028ac5e2: mov    0x28(%r12,%r8,8),%r8
  0x00000001028ac5e7: mov    0x18(%rsp),%ebx
  0x00000001028ac5eb: lea    (%r12,%rbx,8),%rcx
  0x00000001028ac5ef: mov    %rcx,0x20(%rsp)
  0x00000001028ac5f4: movabs $0x7dbccf760,%rcx  ;
{oop('org/jruby/runtime/builtin/IRubyObject')}
  0x00000001028ac5fe: cmp    %rcx,%r8
  0x00000001028ac601: jne    0x00000001028adb29  ;*checkcast
                                                ; -
java.lang.invoke.MethodHandle::invokeExact at 15
                                                ; -
java.lang.invoke.MethodHandleImpl$GuardWithTest::invoke_L5 at 11 (line
987)
                                                ; -
java.lang.invoke.MethodHandle::invokeExact at 9
                                                ; -
java.lang.invoke.MethodHandle::invokeExact at 8
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 51 (line 7)
  0x00000001028ac607: movabs $0x7dbccf760,%rcx  ;
{oop('org/jruby/runtime/builtin/IRubyObject')}
  0x00000001028ac611: cmp    %rcx,%r8
  0x00000001028ac614: jne    0x00000001028adb75  ;*checkcast
                                                ; -
java.lang.invoke.MethodHandle::invokeExact at 20
                                                ; -
java.lang.invoke.MethodHandleImpl$GuardWithTest::invoke_L5 at 11 (line
987)
                                                ; -
java.lang.invoke.MethodHandle::invokeExact at 9
                                                ; -
java.lang.invoke.MethodHandle::invokeExact at 8
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 51 (line 7)
  0x00000001028ac61a: mov    0x40(%r12,%rbx,8),%rcx
  0x00000001028ac61f: mov    %rcx,0x28(%rsp)
  0x00000001028ac624: movabs $0x7dbd12300,%rbx  ;
{oop('org/jruby/RubyBasicObject')}
  0x00000001028ac62e: cmp    %rbx,%rcx
  0x00000001028ac631: jne    0x00000001028af5a5
  0x00000001028ac637: mov    0x70(%rsp),%rcx    ;*checkcast
                                                ; -
org.jruby.runtime.invokedynamic.InvokeDynamicSupport::test at 2 (line
854)
                                                ; -
java.lang.invoke.MethodHandle::invokeExact at 32
                                                ; -
java.lang.invoke.MethodHandleImpl$GuardWithTest::invoke_L5 at 11 (line
987)
                                                ; -
java.lang.invoke.MethodHandle::invokeExact at 9
                                                ; -
java.lang.invoke.MethodHandle::invokeExact at 8
                                                ; -
bench.bench_fib_recursive::method__0$RUBY$fib_ruby at 51 (line 7)

There's substantially more code here. I don't see any jumps that would
short-circuit this logic. Am I reading right?

Now the good news is that after the test is completed I don't see much
additional logic on MLVM before it's back into the inlined recursive
call. Both versions inline a single level of fib_ruby recursion and
then callq the next level of recursion.

So what's up with that logic leading up to test? I assume that's the
new GWT logic, but am I getting that it's a lot more heavyweight than
the old version? Or is some intermediate handle doing extra work?

- Charlie


More information about the mlvm-dev mailing list