More performance explorations
Charles Oliver Nutter
headius at headius.com
Fri May 27 08:05:02 PDT 2011
Bleah, these formatted badly, but you should be able to search for the
offsets in the files I posted to see for yourself :)
On Fri, May 27, 2011 at 10:04 AM, Charles Oliver Nutter
<headius at headius.com> wrote:
> 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