ruby-changes:52481
From: shyouhei <ko1@a...>
Date: Wed, 12 Sep 2018 12:39:41 +0900 (JST)
Subject: [ruby-changes:52481] shyouhei:r64690 (trunk): make opt_str_freeze leaf
shyouhei 2018-09-12 12:39:36 +0900 (Wed, 12 Sep 2018) New Revision: 64690 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64690 Log: make opt_str_freeze leaf Simply use DISPATCH_ORIGINAL_INSN instead of rb_funcall. This is, when possible, overall performant because method dispatch results are cached inside of CALL_CACHE. Should also be good for JIT. ---- trunk: ruby 2.6.0dev (2018-09-12 trunk 64689) [x86_64-darwin15] ours: ruby 2.6.0dev (2018-09-12 leaf-insn 64688) [x86_64-darwin15] last_commit=make opt_str_freeze leaf Calculating ------------------------------------- trunk ours vm2_freezestring 5.440M 31.411M i/s - 6.000M times in 1.102968s 0.191017s Comparison: vm2_freezestring ours: 31410864.5 i/s trunk: 5439865.4 i/s - 5.77x slower Added files: trunk/benchmark/vm2_freezestring.yml Modified files: trunk/compile.c trunk/insns.def trunk/vm_insnhelper.c Index: insns.def =================================================================== --- insns.def (revision 64689) +++ insns.def (revision 64690) @@ -753,22 +753,36 @@ send https://github.com/ruby/ruby/blob/trunk/insns.def#L753 DEFINE_INSN opt_str_freeze -(VALUE str) +(VALUE str, CALL_INFO ci, CALL_CACHE cc) () (VALUE val) -// attr bool leaf = BASIC_OP_UNREDEFINED_P(BOP_FREEZE, STRING_REDEFINED_OP_FLAG); { val = vm_opt_str_freeze(str, BOP_FREEZE, idFreeze); + + if (val == Qundef) { + PUSH(str); +#ifndef MJIT_HEADER + ADD_PC(-WIDTH_OF_opt_send_without_block); +#endif + DISPATCH_ORIGINAL_INSN(opt_send_without_block); + } } DEFINE_INSN opt_str_uminus -(VALUE str) +(VALUE str, CALL_INFO ci, CALL_CACHE cc) () (VALUE val) -// attr bool leaf = BASIC_OP_UNREDEFINED_P(BOP_UMINUS, STRING_REDEFINED_OP_FLAG); { val = vm_opt_str_freeze(str, BOP_UMINUS, idUMinus); + + if (val == Qundef) { + PUSH(str); +#ifndef MJIT_HEADER + ADD_PC(-WIDTH_OF_opt_send_without_block); +#endif + DISPATCH_ORIGINAL_INSN(opt_send_without_block); + } } DEFINE_INSN Index: compile.c =================================================================== --- compile.c (revision 64689) +++ compile.c (revision 64690) @@ -6384,10 +6384,14 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK https://github.com/ruby/ruby/blob/trunk/compile.c#L6384 ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) { VALUE str = freeze_literal(iseq, node->nd_recv->nd_lit); if (node->nd_mid == idUMinus) { - ADD_INSN1(ret, line, opt_str_uminus, str); + ADD_INSN3(ret, line, opt_str_uminus, str, + new_callinfo(iseq, idUMinus, 0, 0, NULL, FALSE), + Qundef /* CALL_CACHE */); } else { - ADD_INSN1(ret, line, opt_str_freeze, str); + ADD_INSN3(ret, line, opt_str_freeze, str, + new_callinfo(iseq, idFreeze, 0, 0, NULL, FALSE), + Qundef /* CALL_CACHE */); } if (popped) { ADD_INSN(ret, line, pop); Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 64689) +++ vm_insnhelper.c (revision 64690) @@ -3219,7 +3219,7 @@ vm_opt_str_freeze(VALUE str, int bop, ID https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L3219 return str; } else { - return rb_funcall(rb_str_resurrect(str), id, 0); + return Qundef; } } Index: benchmark/vm2_freezestring.yml =================================================================== --- benchmark/vm2_freezestring.yml (nonexistent) +++ benchmark/vm2_freezestring.yml (revision 64690) @@ -0,0 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/benchmark/vm2_freezestring.yml#L1 +prelude: | + class String + def freeze + -self + end + end +benchmark: + vm2_freezestring: | + "tXnL1BP5T1WPXMjuFNLQtallEtRcay1t2lHtJSrlVsDgvunlbtfpr/DGdH0NGYE9".freeze +loop_count: 6000000 Property changes on: benchmark/vm2_freezestring.yml ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +LF \ No newline at end of property -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/