diff options
author | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-12-26 00:59:37 +0000 |
---|---|---|
committer | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-12-26 00:59:37 +0000 |
commit | d46ab953765e2114b6f2f58792be9a7a974e5f27 (patch) | |
tree | 893d6b7748b296a17450bc8d4354dd689c4caeb4 /insns.def | |
parent | 686881d383cfe44c67875aada64207c5e0abaa8d (diff) | |
download | ruby-d46ab953765e2114b6f2f58792be9a7a974e5f27.tar.gz |
insns.def: refactor to avoid CALL_METHOD macro
These send and its variant instructions are the most frequently called
paths in the entire process. Reducing macro expansions to make them
dedicated function called vm_sendish() is the main goal of this
changeset. It reduces the size of vm_exec_coref from 25,552 bytes to
23,728 bytes on my machine.
I see no significant slowdown.
Fix: [GH-2056]
vanilla: ruby 2.6.0dev (2018-12-19 trunk 66449) [x86_64-darwin15]
ours: ruby 2.6.0dev (2018-12-19 refactor-send 66449) [x86_64-darwin15]
last_commit=insns.def: refactor to avoid CALL_METHOD macro
Calculating -------------------------------------
vanilla ours
vm2_defined_method 2.645M 2.823M i/s - 6.000M times in 5.109888s 4.783254s
vm2_method 8.553M 8.873M i/s - 6.000M times in 1.579892s 1.524026s
vm2_method_missing 3.772M 3.858M i/s - 6.000M times in 3.579482s 3.499220s
vm2_method_with_block 8.494M 8.944M i/s - 6.000M times in 1.589774s 1.509463s
vm2_poly_method 0.571 0.607 i/s - 1.000 times in 3.947570s 3.733528s
vm2_poly_method_ov 5.514 5.168 i/s - 1.000 times in 0.408156s 0.436169s
vm3_clearmethodcache 2.875 2.837 i/s - 1.000 times in 0.783018s 0.793493s
Comparison:
vm2_defined_method
ours: 2822555.4 i/s
vanilla: 2644878.1 i/s - 1.07x slower
vm2_method
ours: 8872947.8 i/s
vanilla: 8553433.1 i/s - 1.04x slower
vm2_method_missing
ours: 3858192.3 i/s
vanilla: 3772296.3 i/s - 1.02x slower
vm2_method_with_block
ours: 8943825.1 i/s
vanilla: 8493955.0 i/s - 1.05x slower
vm2_poly_method
ours: 0.6 i/s
vanilla: 0.6 i/s - 1.06x slower
vm2_poly_method_ov
vanilla: 5.5 i/s
ours: 5.2 i/s - 1.07x slower
vm3_clearmethodcache
vanilla: 2.9 i/s
ours: 2.8 i/s - 1.01x slower
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66565 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'insns.def')
-rw-r--r-- | insns.def | 52 |
1 files changed, 26 insertions, 26 deletions
@@ -740,12 +740,13 @@ send (VALUE val) // attr rb_snum_t sp_inc = sp_inc_of_sendish(ci); { - struct rb_calling_info calling; + VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), ci, blockiseq, false); + val = vm_sendish(ec, GET_CFP(), ci, cc, bh, vm_search_method_wrap); - calling.block_handler = vm_caller_setup_arg_block(ec, reg_cfp, ci, blockiseq, FALSE); - calling.recv = TOPN(calling.argc = ci->orig_argc); - vm_search_method(ci, cc, calling.recv); - CALL_METHOD(&calling, ci, cc); + if (val == Qundef) { + RESTORE_REGS(); + NEXT_INSN(); + } } /* Invoke method without block */ @@ -757,10 +758,13 @@ opt_send_without_block // attr bool handles_sp = true; // attr rb_snum_t sp_inc = sp_inc_of_sendish(ci); { - struct rb_calling_info calling; - calling.block_handler = VM_BLOCK_HANDLER_NONE; - vm_search_method(ci, cc, calling.recv = TOPN(calling.argc = ci->orig_argc)); - CALL_METHOD(&calling, ci, cc); + VALUE bh = VM_BLOCK_HANDLER_NONE; + val = vm_sendish(ec, GET_CFP(), ci, cc, bh, vm_search_method_wrap); + + if (val == Qundef) { + RESTORE_REGS(); + NEXT_INSN(); + } } DEFINE_INSN @@ -826,12 +830,13 @@ invokesuper (VALUE val) // attr rb_snum_t sp_inc = sp_inc_of_sendish(ci); { - struct rb_calling_info calling; + VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), ci, blockiseq, true); + val = vm_sendish(ec, GET_CFP(), ci, cc, bh, vm_search_super_method); - calling.block_handler = vm_caller_setup_arg_block(ec, reg_cfp, ci, blockiseq, TRUE); - calling.recv = TOPN(calling.argc = ci->orig_argc); - vm_search_super_method(ec, GET_CFP(), &calling, ci, cc); - CALL_METHOD(&calling, ci, cc); + if (val == Qundef) { + RESTORE_REGS(); + NEXT_INSN(); + } } /* yield(args) */ @@ -843,21 +848,16 @@ invokeblock // attr bool handles_sp = true; // attr rb_snum_t sp_inc = sp_inc_of_invokeblock(ci); { - struct rb_calling_info calling; - VALUE block_handler; + static struct rb_call_cache cc = { + 0, 0, NULL, vm_invokeblock_i, + }; - calling.argc = ci->orig_argc; - calling.block_handler = VM_BLOCK_HANDLER_NONE; - calling.recv = Qundef; /* should not be used */ - - block_handler = VM_CF_BLOCK_HANDLER(GET_CFP()); - if (block_handler == VM_BLOCK_HANDLER_NONE) { - rb_vm_localjump_error("no block given (yield)", Qnil, 0); - } + VALUE bh = VM_BLOCK_HANDLER_NONE; + val = vm_sendish(ec, GET_CFP(), ci, &cc, bh, vm_search_invokeblock); - val = vm_invoke_block(ec, GET_CFP(), &calling, ci, block_handler); if (val == Qundef) { - EXEC_EC_CFP(val); + RESTORE_REGS(); + NEXT_INSN(); } } |