Your SlideShare is downloading. ×
0
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Message in a bottle
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Message in a bottle

3,449

Published on

Published in: Technology, Business
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,449
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
12
Comments
0
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Message In A Bottle Konstantin Haase
  • 2. Ruby 1.8 is slow because its interpreted. Surprise! Ruby 1.9 is interpreted, too.
  • 3. Thanks!github.com / rkh / presentations
  • 4. Ruby
  • 5. What Well Look Into MRI: method dispatch and execution Rubinius: inline caches and JIT JRuby: invokedynamic
  • 6. class DeepThought def ultimate_answer?(value) value.to_s == 42 endendDeepThought.new.ultimate_answer? 42
  • 7. They Just Love BytecodeRuby value.to_sMRI getlocal value send :to_s, 0, nil, 0, <ic:0>Rubinius push_local 0 send_stack :to_s, 0JRuby ALOAD 0 LDC "to_suffffNuffffu0000u0000u0001u0000u0000u0000u0000u0000u0000... INVOKEVIRTUAL org/jruby/ast/executable/AbstractScript.initFromDescriptor (Lj... ... ALOAD 0 INVOKEVIRTUAL ruby/__dash_e__.getCallSite0 ()Lorg/jruby/runtime/CallSite; ALOAD 1 ALOAD 2 ALOAD 9 INVOKEVIRTUAL org/jruby/runtime/CallSite.call (Lorg/jruby/runtime/ThreadCont...
  • 8. The Plansearch for methodexecute method
  • 9. How To Speed That Up? search faster execute faster
  • 10. Speed Up SearchInline Cache (aka Call/Send Site Cache) Lookup Cache Inlining
  • 11. Speed Up Execution Reduce operations Just-in-time compilation Inlining Speed up search
  • 12. MRI
  • 13. a method gets called rb_call0
  • 14. static inline VALUErb_call0(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope, VALUE self){ rb_method_entry_t *me = rb_search_method_entry(recv, mid); rb_thread_t *th = GET_THREAD(); int call_status = rb_method_call_status(th, me, scope, self); // <- SEARCH if (call_status != NOEX_OK) { return method_missing(recv, mid, argc, argv, call_status); } stack_check(); return vm_call0(th, recv, mid, argc, argv, me); // <- EXECUTE}
  • 15. /* * rb_call0 searching for a method * -> rb_method_entry * -> rb_method_entry_get_without_cache * -> search_method */static rb_method_entry_t*search_method(VALUE klass, ID id){ st_data_t body; if (!klass) { return 0; } while (!st_lookup(RCLASS_M_TBL(klass), id, &body)) { klass = RCLASS_SUPER(klass); if (!klass) { return 0; } } return (rb_method_entry_t *)body;}
  • 16. /* * rb_call0 executing a method * -> vm_call0 */static inline VALUEvm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv, const rb_method_entry_t *me){ const rb_method_definition_t *def = me->def; VALUE val; const rb_block_t *blockptr = 0; // ... again: switch (def->type) { case VM_METHOD_TYPE_ISEQ: { rb_control_frame_t *reg_cfp; // ... vm_setup_method(th, reg_cfp, recv, argc, blockptr, 0 /* flag */, me); val = vm_exec(th); // <- EXECUTE !!! break; } // ... } // ...}
  • 17. static VALUEvm_exec(rb_thread_t *th){ // ... go see for yourself ...}
  • 18. DEFINE_INSNsend(ID op_id, rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag, IC ic)(...)(VALUE val)// inc += - (int)(op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));{ const rb_method_entry_t *me; VALUE recv, klass; rb_block_t *blockptr = 0; VALUE flag = op_flag; int num = caller_setup_args(th, GET_CFP(), flag, (int)op_argc, (rb_iseq_t *)blockiseq, &blockptr); ID id = op_id; /* get receiver */ recv = (flag & VM_CALL_FCALL_BIT) ? GET_SELF() : TOPN(num); klass = CLASS_OF(recv); me = vm_method_search(id, klass, ic); CALL_METHOD(num, blockptr, flag, id, me, recv);}
  • 19. Rubinius
  • 20. klass = object.singleton_classmethod = nilwhile klass and not method method = klass.method_table.lookup(:some_method) klass = klass.direct_superclassend
  • 21. >> cm = DeepThought.method_table ?> .lookup(:ultimate_answer?).method=> #<Rubinius::CompiledMethod ultimate_answer?>>> puts cm.decode0000: push_local 0 # value0002: send_stack :to_s, 00005: push_literal "42"0007: string_dup0008: meta_send_op_equal :==0010: ret=> nil>> cm.iseq.opcodes=> #<Rubinius::Tuple: 20, 0, 49, 0, 0, 7, 1, 64, 83, 2, 11>>> cm.literals=> #<Rubinius::Tuple: :to_s, "42", :==>
  • 22. literals: :to_s, "42", :== locals: value (42)bytes: 20 0 49 0 0 7 1 64 83 2 11bytes decoded stack20 0 push_local 0 [ 42 ]49 0 0 send_stack :to_s, 0 [ "42" ]7 1 push_literal "42" [ "42", "42" ]64 string_dup [ "42", "42" ]83 2 meta_send_op_equal [ true ]11 ret [ ]
  • 23. instruction send_stack(literal count) [ receiver +count -- value ] => send Object* recv = stack_back(count); InlineCache* cache = reinterpret_cast<InlineCache*>(literal); Arguments args(cache->name, recv, Qnil, count, stack_back_position(count)); Object* ret = cache->execute(state, call_frame, args); CHECK_AND_PUSH(ret);end
  • 24. Specialized Methods cached bytecode code with breakpoints specialized for arguments JITed code
  • 25. JRuby
  • 26. INVOKEVIRTUALINVOKEVIRTUAL example.getCallSite1 ...ALOAD 1ALOAD 2ALOAD 9INVOKEVIRTUAL org/jruby/runtime/CallSite.call ... INVOKEDYNAMICALOAD 1ALOAD 2ALOAD 9INVOKEDYNAMIC call ...
  • 27. INVOKEVIRTUALINVOKEVIRTUAL org/jruby/runtime/CallSite.call( Lorg/jruby/runtime/ThreadContext; Lorg/jruby/runtime/builtin/IRubyObject; Lorg/jruby/runtime/builtin/IRubyObject; )Lorg/jruby/runtime/builtin/IRubyObject; INVOKEDYNAMICINVOKEDYNAMIC call( Lorg/jruby/runtime/ThreadContext; Lorg/jruby/runtime/builtin/IRubyObject; Lorg/jruby/runtime/builtin/IRubyObject; Ljava/lang/String; )Lorg/jruby/runtime/builtin/IRubyObject; [...]
  • 28. The Linker[org/jruby/runtime/invokedynamic/InvocationLinker .invocationBootstrap( Ljava/lang/invoke/MethodHandles$Lookup; Ljava/lang/String; Ljava/lang/invoke/MethodType; )Ljava/lang/invoke/CallSite;]
  • 29. The Bootstrappublic static CallSiteinvocationBootstrap(Lookup lookup, String name, MethodType type)throws NoSuchMethodException, IllegalAccessException { CallSite site; // ... if (name.equals("call")) { site = new JRubyCallSite(lookup, type, CallType.NORMAL, false, false, true); } // ... MethodHandle myFallback = ... site.setTarget(myFallback); return site;}
  • 30. The Fallbackpublic static IRubyObject invocationFallback(JRubyCallSite site, ThreadContext context, IRubyObject caller, IRubyObject self, String name) throws Throwable { RubyClass selfClass = pollAndGetClass(context, self); CacheEntry entry = selfClass.searchWithCache(name); if (methodMissing(entry, site.callType(), name, caller)) { return callMethodMissing(entry, site.callType(), context, self, name); } MethodHandle target = getTarget(site, selfClass, name, entry, 0); target = updateInvocationTarget(target, site, selfClass, name, entry, false, 0); return (IRubyObject)target.invokeWithArguments(context, caller, self, name);}
  • 31. images http://kosmur.deviantart.com/art/assembler-79007314 https://www.facebook.com/headius https://www.facebook.com/koichi.sasada https://www.facebook.com/profile.php?id=523826914 http://farm4.static.flickr.com/3207/2522976901_6ff55314cd.jpg http://www.flickr.com/photos/binkley27/3451700024 http://www.flickr.com/photos/funtik/1175522045 http://en.wikipedia.org/wiki/File:Answer_to_Life.png http://www.flickr.com/photos/makelessnoise/195088755/ http://www.flickr.com/photos/jeffhenshaw/4833007463/http://churchmusictoday.wordpress.com/2011/05/13/ten-warning-signs-for-churches-from-thom-ranier/ http://www.freefoto.com/preview/28-06-3/Police-Underwater-Search-Unit http://blog-blond.blogspot.com/2009/07/how-to-do-blogs-right.html http://fuckyouverymuch.dk/post/9661487809/we-are-ready-to-leave http://crunchtools.com/bootstrapping-and-rooting-documentation-part-2/ http://www.softmyhard.com/tag/device-instruction-manual http://www.flickr.com/photos/quinnanya/4874581964
  • 32. Thanks!github.com / rkh / presentations

×