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



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64690 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
shyouhei 2018-09-12 03:39:36 +00:00
Родитель 33c8171c65
Коммит 02b52b2733
4 изменённых файлов: 35 добавлений и 7 удалений

Просмотреть файл

@ -0,0 +1,10 @@
prelude: |
class String
def freeze
-self
end
end
benchmark:
vm2_freezestring: |
"tXnL1BP5T1WPXMjuFNLQtallEtRcay1t2lHtJSrlVsDgvunlbtfpr/DGdH0NGYE9".freeze
loop_count: 6000000

Просмотреть файл

@ -6384,10 +6384,14 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
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);

Просмотреть файл

@ -753,22 +753,36 @@ send
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

Просмотреть файл

@ -3219,7 +3219,7 @@ vm_opt_str_freeze(VALUE str, int bop, ID id)
return str;
}
else {
return rb_funcall(rb_str_resurrect(str), id, 0);
return Qundef;
}
}