From 82ea2870188d66aa75a99f03b4e7fdd1750aa196 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Thu, 18 Nov 2021 11:01:31 +0900 Subject: optimize `Struct` getter/setter Introduce new optimized method type `OPTIMIZED_METHOD_TYPE_STRUCT_AREF/ASET` with index information. --- vm_eval.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'vm_eval.c') diff --git a/vm_eval.c b/vm_eval.c index 183f4e78c9..140912f218 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -163,6 +163,19 @@ vm_call0_cfunc(rb_execution_context_t *ec, struct rb_calling_info *calling, cons return vm_call0_cfunc_with_frame(ec, calling, argv); } +static void +vm_call_check_arity(struct rb_calling_info *calling, int argc, const VALUE *argv) +{ + if (calling->kw_splat && + calling->argc > 0 && + RB_TYPE_P(argv[calling->argc-1], T_HASH) && + RHASH_EMPTY_P(argv[calling->argc-1])) { + calling->argc--; + } + + rb_check_arity(calling->argc, argc, argc); +} + /* `ci' should point temporal value (on stack value) */ static VALUE vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const VALUE *argv) @@ -196,27 +209,13 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const ret = vm_call0_cfunc(ec, calling, argv); goto success; case VM_METHOD_TYPE_ATTRSET: - if (calling->kw_splat && - calling->argc > 0 && - RB_TYPE_P(argv[calling->argc-1], T_HASH) && - RHASH_EMPTY_P(argv[calling->argc-1])) { - calling->argc--; - } - - rb_check_arity(calling->argc, 1, 1); + vm_call_check_arity(calling, 1, argv); VM_CALL_METHOD_ATTR(ret, rb_ivar_set(calling->recv, vm_cc_cme(cc)->def->body.attr.id, argv[0]), (void)0); goto success; case VM_METHOD_TYPE_IVAR: - if (calling->kw_splat && - calling->argc > 0 && - RB_TYPE_P(argv[calling->argc-1], T_HASH) && - RHASH_EMPTY_P(argv[calling->argc-1])) { - calling->argc--; - } - - rb_check_arity(calling->argc, 0, 0); + vm_call_check_arity(calling, 0, argv); VM_CALL_METHOD_ATTR(ret, rb_attr_get(calling->recv, vm_cc_cme(cc)->def->body.attr.id), (void)0); @@ -274,6 +273,14 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const ret = rb_vm_invoke_proc(ec, proc, calling->argc, argv, calling->kw_splat, calling->block_handler); goto success; } + case OPTIMIZED_METHOD_TYPE_STRUCT_AREF: + vm_call_check_arity(calling, 0, argv); + ret = vm_call_opt_struct_aref0(ec, ec->cfp, calling); + goto success; + case OPTIMIZED_METHOD_TYPE_STRUCT_ASET: + vm_call_check_arity(calling, 1, argv); + ret = vm_call_opt_struct_aset0(ec, ec->cfp, calling); + goto success; default: rb_bug("vm_call0: unsupported optimized method type (%d)", vm_cc_cme(cc)->def->body.optimized.type); } -- cgit v1.2.3