ruby-changes:60155
From: Koichi <ko1@a...>
Date: Sat, 22 Feb 2020 09:59:22 +0900 (JST)
Subject: [ruby-changes:60155] f2286925f0 (master): VALUE size packed callinfo (ci).
https://git.ruby-lang.org/ruby.git/commit/?id=f2286925f0 From f2286925f08406bc857f7b03ad6779a5d61443ae Mon Sep 17 00:00:00 2001 From: Koichi Sasada <ko1@a...> Date: Wed, 8 Jan 2020 08:20:36 +0900 Subject: VALUE size packed callinfo (ci). Now, rb_call_info contains how to call the method with tuple of (mid, orig_argc, flags, kwarg). Most of cases, kwarg == NULL and mid+argc+flags only requires 64bits. So this patch packed rb_call_info to VALUE (1 word) on such cases. If we can not represent it in VALUE, then use imemo_callinfo which contains conventional callinfo (rb_callinfo, renamed from rb_call_info). iseq->body->ci_kw_size is removed because all of callinfo is VALUE size (packed ci or a pointer to imemo_callinfo). To access ci information, we need to use these functions: vm_ci_mid(ci), _flag(ci), _argc(ci), _kwarg(ci). struct rb_call_info_kw_arg is renamed to rb_callinfo_kwarg. rb_funcallv_with_cc() and rb_method_basic_definition_p_with_cc() is temporary removed because cd->ci should be marked. diff --git a/common.mk b/common.mk index f1bd19c..50f2c15 100644 --- a/common.mk +++ b/common.mk @@ -1837,6 +1837,7 @@ compile.$(OBJEXT): {$(VPATH)}builtin.h https://github.com/ruby/ruby/blob/trunk/common.mk#L1837 compile.$(OBJEXT): {$(VPATH)}compile.c compile.$(OBJEXT): {$(VPATH)}config.h compile.$(OBJEXT): {$(VPATH)}constant.h +compile.$(OBJEXT): {$(VPATH)}debug_counter.h compile.$(OBJEXT): {$(VPATH)}defines.h compile.$(OBJEXT): {$(VPATH)}encindex.h compile.$(OBJEXT): {$(VPATH)}encoding.h @@ -1866,6 +1867,7 @@ compile.$(OBJEXT): {$(VPATH)}subst.h https://github.com/ruby/ruby/blob/trunk/common.mk#L1867 compile.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h compile.$(OBJEXT): {$(VPATH)}thread_native.h compile.$(OBJEXT): {$(VPATH)}util.h +compile.$(OBJEXT): {$(VPATH)}vm_callinfo.h compile.$(OBJEXT): {$(VPATH)}vm_core.h compile.$(OBJEXT): {$(VPATH)}vm_debug.h compile.$(OBJEXT): {$(VPATH)}vm_opts.h @@ -1966,6 +1968,7 @@ debug.$(OBJEXT): $(top_srcdir)/internal/warnings.h https://github.com/ruby/ruby/blob/trunk/common.mk#L1968 debug.$(OBJEXT): {$(VPATH)}assert.h debug.$(OBJEXT): {$(VPATH)}config.h debug.$(OBJEXT): {$(VPATH)}debug.c +debug.$(OBJEXT): {$(VPATH)}debug_counter.h debug.$(OBJEXT): {$(VPATH)}defines.h debug.$(OBJEXT): {$(VPATH)}encoding.h debug.$(OBJEXT): {$(VPATH)}eval_intern.h @@ -1987,6 +1990,7 @@ debug.$(OBJEXT): {$(VPATH)}symbol.h https://github.com/ruby/ruby/blob/trunk/common.mk#L1990 debug.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h debug.$(OBJEXT): {$(VPATH)}thread_native.h debug.$(OBJEXT): {$(VPATH)}util.h +debug.$(OBJEXT): {$(VPATH)}vm_callinfo.h debug.$(OBJEXT): {$(VPATH)}vm_core.h debug.$(OBJEXT): {$(VPATH)}vm_debug.h debug.$(OBJEXT): {$(VPATH)}vm_opts.h @@ -2437,6 +2441,7 @@ gc.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h https://github.com/ruby/ruby/blob/trunk/common.mk#L2441 gc.$(OBJEXT): {$(VPATH)}thread_native.h gc.$(OBJEXT): {$(VPATH)}transient_heap.h gc.$(OBJEXT): {$(VPATH)}util.h +gc.$(OBJEXT): {$(VPATH)}vm_callinfo.h gc.$(OBJEXT): {$(VPATH)}vm_core.h gc.$(OBJEXT): {$(VPATH)}vm_opts.h golf_prelude.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h @@ -2663,6 +2668,7 @@ iseq.$(OBJEXT): {$(VPATH)}subst.h https://github.com/ruby/ruby/blob/trunk/common.mk#L2668 iseq.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h iseq.$(OBJEXT): {$(VPATH)}thread_native.h iseq.$(OBJEXT): {$(VPATH)}util.h +iseq.$(OBJEXT): {$(VPATH)}vm_callinfo.h iseq.$(OBJEXT): {$(VPATH)}vm_core.h iseq.$(OBJEXT): {$(VPATH)}vm_opts.h load.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h @@ -2986,6 +2992,7 @@ mjit_compile.$(OBJEXT): {$(VPATH)}st.h https://github.com/ruby/ruby/blob/trunk/common.mk#L2992 mjit_compile.$(OBJEXT): {$(VPATH)}subst.h mjit_compile.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h mjit_compile.$(OBJEXT): {$(VPATH)}thread_native.h +mjit_compile.$(OBJEXT): {$(VPATH)}vm_callinfo.h mjit_compile.$(OBJEXT): {$(VPATH)}vm_core.h mjit_compile.$(OBJEXT): {$(VPATH)}vm_exec.h mjit_compile.$(OBJEXT): {$(VPATH)}vm_insnhelper.h @@ -4165,6 +4172,7 @@ vm.$(OBJEXT): {$(VPATH)}vm.h https://github.com/ruby/ruby/blob/trunk/common.mk#L4172 vm.$(OBJEXT): {$(VPATH)}vm.inc vm.$(OBJEXT): {$(VPATH)}vm_args.c vm.$(OBJEXT): {$(VPATH)}vm_call_iseq_optimized.inc +vm.$(OBJEXT): {$(VPATH)}vm_callinfo.h vm.$(OBJEXT): {$(VPATH)}vm_core.h vm.$(OBJEXT): {$(VPATH)}vm_debug.h vm.$(OBJEXT): {$(VPATH)}vm_eval.c diff --git a/compile.c b/compile.c index fa3505a..e1efbcd 100644 --- a/compile.c +++ b/compile.c @@ -36,6 +36,7 @@ https://github.com/ruby/ruby/blob/trunk/compile.c#L36 #include "ruby/re.h" #include "ruby/util.h" #include "vm_core.h" +#include "vm_callinfo.h" #include "vm_debug.h" #include "builtin.h" @@ -919,6 +920,15 @@ compile_data_alloc2(rb_iseq_t *iseq, size_t x, size_t y) https://github.com/ruby/ruby/blob/trunk/compile.c#L920 return compile_data_alloc(iseq, size); } +static inline void * +compile_data_calloc2(rb_iseq_t *iseq, size_t x, size_t y) +{ + size_t size = rb_size_mul_or_raise(x, y, rb_eRuntimeError); + void *p = compile_data_alloc(iseq, size); + memset(p, 0, size); + return p; +} + static INSN * compile_data_alloc_insn(rb_iseq_t *iseq) { @@ -1187,38 +1197,31 @@ new_insn_body(rb_iseq_t *iseq, int line_no, enum ruby_vminsn_type insn_id, int a https://github.com/ruby/ruby/blob/trunk/compile.c#L1197 return new_insn_core(iseq, line_no, insn_id, argc, operands); } -static struct rb_call_info * -new_callinfo(rb_iseq_t *iseq, ID mid, int argc, unsigned int flag, struct rb_call_info_kw_arg *kw_arg, int has_blockiseq) +static const struct rb_callinfo * +new_callinfo(rb_iseq_t *iseq, ID mid, int argc, unsigned int flag, struct rb_callinfo_kwarg *kw_arg, int has_blockiseq) { - size_t size = kw_arg != NULL ? sizeof(struct rb_call_info_with_kwarg) : sizeof(struct rb_call_info); - struct rb_call_info *ci = (struct rb_call_info *)compile_data_alloc(iseq, size); - struct rb_call_info_with_kwarg *ci_kw = (struct rb_call_info_with_kwarg *)ci; + VM_ASSERT(argc >= 0); - ci->mid = mid; - ci->flag = flag; - ci->orig_argc = argc; + if (!(flag & (VM_CALL_ARGS_SPLAT | VM_CALL_ARGS_BLOCKARG | VM_CALL_KW_SPLAT)) && + kw_arg == NULL && !has_blockiseq) { + flag |= VM_CALL_ARGS_SIMPLE; + } if (kw_arg) { - ci->flag |= VM_CALL_KWARG; - ci_kw->kw_arg = kw_arg; - ci->orig_argc += kw_arg->keyword_len; - iseq->body->ci_kw_size++; - } - else { - iseq->body->ci_size++; + flag |= VM_CALL_KWARG; + argc += kw_arg->keyword_len; } - if (!(ci->flag & (VM_CALL_ARGS_SPLAT | VM_CALL_ARGS_BLOCKARG | VM_CALL_KW_SPLAT)) && - kw_arg == NULL && !has_blockiseq) { - ci->flag |= VM_CALL_ARGS_SIMPLE; - } + iseq->body->ci_size++; + const struct rb_callinfo *ci = vm_ci_new(mid, flag, argc, kw_arg); + RB_OBJ_WRITTEN(iseq, Qundef, ci); return ci; } static INSN * -new_insn_send(rb_iseq_t *iseq, int line_no, ID id, VALUE argc, const rb_iseq_t *blockiseq, VALUE flag, struct rb_call_info_kw_arg *keywords) +new_insn_send(rb_iseq_t *iseq, int line_no, ID id, VALUE argc, const rb_iseq_t *blockiseq, VALUE flag, struct rb_callinfo_kwarg *keywords) { - VALUE *operands = compile_data_alloc2(iseq, sizeof(VALUE), 2); + VALUE *operands = compile_data_calloc2(iseq, sizeof(VALUE), 2); operands[0] = (VALUE)new_callinfo(iseq, id, FIX2INT(argc), FIX2INT(flag), keywords, blockiseq != NULL); operands[1] = (VALUE)blockiseq; return new_insn_core(iseq, line_no, BIN(send), 2, operands); @@ -2129,11 +2132,8 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) https://github.com/ruby/ruby/blob/trunk/compile.c#L2132 insns_info = ALLOC_N(struct iseq_insn_info_entry, insn_num); positions = ALLOC_N(unsigned int, insn_num); body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, body->is_size); - body->call_data = - rb_xcalloc_mul_add_mul( - sizeof(struct rb_call_data), body->ci_size, - sizeof(struct rb_kwarg_call_data), body->ci_kw_size); - ISEQ_COMPILE_DATA(iseq)->ci_index = ISEQ_COMPILE_DATA(iseq)->ci_kw_index = 0; + body->call_data = ZALLOC_N(struct rb_call_data, body->ci_size); + ISEQ_COMPILE_DATA(iseq)->ci_index = 0; list = FIRST_ELEMENT(anchor); insns_info_index = code_index = sp = 0; @@ -2201,7 +2201,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) https://github.com/ruby/ruby/blob/trunk/compile.c#L2201 } case TS_ISE: /* inline storage entry */ /* Treated as an IC, but may contain a markable VALUE */ - FL_SET(iseq, ISEQ_MARKABLE_ISEQ); + FL_SET(iseq, ISEQ_MARKABLE_ISEQ); /* fall through */ case TS_IC: /* inline cache */ case TS_IVC: /* inline ivar cache */ @@ -2219,22 +2219,10 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) https://github.com/ruby/ruby/blob/trunk/compile.c#L2219 } case TS_CALLDATA: { - struct rb_call_info *source_ci = (struct rb_call_info *)operands[j]; - struct rb_call_data *cd; - - if (source_ci->flag & VM_CALL_KWARG) { - struct rb_kwarg_call_data *kw_calls = (struct rb_kwarg_call_data *)&body->call_data[body->ci_size]; - struct rb_kwarg_call_data *cd_kw = &kw_calls[ISEQ_COMPILE_DATA(iseq)->ci_kw_index++]; - cd_kw->ci_kw = *((struct rb_call_info_with_kwarg *)source_ci); - cd = (struct rb_call_data *)cd_kw; - assert(ISEQ_COMPILE_DATA(iseq)->ci_kw_index <= body->ci_kw_size); - } - else { - cd = &body->call_data[ISEQ_COMPILE_DATA(iseq)->ci_index++]; - cd->ci = *source_ci; - assert(ISEQ_COMPILE_DATA(iseq)->ci_index (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/