ruby-changes:35427
From: normal <ko1@a...>
Date: Wed, 10 Sep 2014 15:32:59 +0900 (JST)
Subject: [ruby-changes:35427] normal:r47509 (trunk): rb_call_info_t: shrink to 96 bytes from 104 bytes on 64-bit
normal 2014-09-10 15:32:44 +0900 (Wed, 10 Sep 2014) New Revision: 47509 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47509 Log: rb_call_info_t: shrink to 96 bytes from 104 bytes on 64-bit This keeps ci->flag and ci->aux.index consistent across 32-bit and 64-bit platforms. ci->flag: VM_CALL_* flags only use 9 bits, currently ci->aux.index: 2 billion ivars per class should be enough for anybody This saves around 50K allocations on "valgrind ruby -e exit" on x86-64 before: total heap usage: 48,122 allocs, 19,253 frees, 8,099,197 bytes allocated after: total heap usage: 48,069 allocs, 19,214 frees, 8,047,266 bytes allocated * vm_core.h (rb_call_info_t): ci->flag becomes 32-bit unsigned int ci->index becomes a 32-bit signed int (from signed long). Reorder for better packing on 64-bit, giving an 8 byte reduction from 104 to 96 bytes for each ci. * compile.c (new_callinfo, setup_args, iseq_compile_each, iseq_build_from_ary_body): adjust for type changes * vm_insnhelper.c (vm_getivar): ditto Modified files: trunk/ChangeLog trunk/compile.c trunk/include/ruby/ruby.h trunk/variable.c trunk/vm_core.h trunk/vm_insnhelper.c Index: include/ruby/ruby.h =================================================================== --- include/ruby/ruby.h (revision 47508) +++ include/ruby/ruby.h (revision 47509) @@ -775,7 +775,7 @@ struct RObject { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L775 struct RBasic basic; union { struct { - long numiv; + long numiv; /* only uses 32-bits */ VALUE *ivptr; struct st_table *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */ } heap; Index: ChangeLog =================================================================== --- ChangeLog (revision 47508) +++ ChangeLog (revision 47509) @@ -1,3 +1,16 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Sep 10 15:29:46 2014 Eric Wong <e@8...> + + * vm_core.h (rb_call_info_t): ci->flag becomes 32-bit unsigned int + ci->index becomes a 32-bit signed int (from signed long). + Reorder for better packing on 64-bit, giving an 8 byte reduction + from 104 to 96 bytes for each ci. + [Feature #10187] + + * compile.c (new_callinfo, setup_args, iseq_compile_each, + iseq_build_from_ary_body): adjust for type changes + + * vm_insnhelper.c (vm_getivar): ditto + Wed Sep 10 15:07:35 2014 Eric Wong <e@8...> * compile.c (rb_iseq_translate_threaded_code): Index: variable.c =================================================================== --- variable.c (revision 47508) +++ variable.c (revision 47509) @@ -1173,6 +1173,10 @@ rb_ivar_set(VALUE obj, ID id, VALUE val) https://github.com/ruby/ruby/blob/trunk/variable.c#L1173 iv_index_tbl->num_entries < (st_index_t)newsize) { newsize = iv_index_tbl->num_entries; } + + /* never happens in practice: */ + if (newsize > INT_MAX) rb_memerror(); + if (RBASIC(obj)->flags & ROBJECT_EMBED) { newptr = ALLOC_N(VALUE, newsize); MEMCPY(newptr, ptr, VALUE, len); Index: vm_core.h =================================================================== --- vm_core.h (revision 47508) +++ vm_core.h (revision 47509) @@ -140,11 +140,9 @@ struct rb_control_frame_struct; https://github.com/ruby/ruby/blob/trunk/vm_core.h#L140 typedef struct rb_call_info_struct { /* fixed at compile time */ ID mid; - VALUE flag; - rb_iseq_t *blockiseq; + unsigned int flag; int orig_argc; - - int argc; /* temporary for method calling */ + rb_iseq_t *blockiseq; /* inline cache: keys */ rb_serial_t method_state; @@ -158,9 +156,10 @@ typedef struct rb_call_info_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L156 /* temporary values for method calling */ struct rb_block_struct *blockptr; VALUE recv; + int argc; union { int opt_pc; /* used by iseq */ - long index; /* used by ivar */ + int index; /* used by ivar */ int missing_reason; /* used by method_missing */ int inc_sp; /* used by cfunc */ } aux; Index: compile.c =================================================================== --- compile.c (revision 47508) +++ compile.c (revision 47509) @@ -981,7 +981,7 @@ new_insn_body(rb_iseq_t *iseq, int line_ https://github.com/ruby/ruby/blob/trunk/compile.c#L981 } static rb_call_info_t * -new_callinfo(rb_iseq_t *iseq, ID mid, int argc, VALUE block, unsigned long flag) +new_callinfo(rb_iseq_t *iseq, ID mid, int argc, VALUE block, unsigned int flag) { rb_call_info_t *ci = (rb_call_info_t *)compile_data_alloc(iseq, sizeof(rb_call_info_t)); ci->mid = mid; @@ -3119,7 +3119,7 @@ add_ensure_iseq(LINK_ANCHOR *ret, rb_ise https://github.com/ruby/ruby/blob/trunk/compile.c#L3119 } static VALUE -setup_args(rb_iseq_t *iseq, LINK_ANCHOR *args, NODE *argn, VALUE *flag) +setup_args(rb_iseq_t *iseq, LINK_ANCHOR *args, NODE *argn, unsigned int *flag) { VALUE argc = INT2FIX(0); int nsplat = 0; @@ -4015,7 +4015,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4015 case NODE_OP_ASGN1: { DECL_ANCHOR(args); VALUE argc; - VALUE flag = 0; + unsigned int flag = 0; VALUE asgnflag = 0; ID id = node->nd_mid; int boff = 0; @@ -4060,7 +4060,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4060 } ADD_INSN1(ret, line, dupn, FIXNUM_INC(argc, 1 + boff)); flag |= asgnflag; - ADD_SEND_R(ret, line, idAREF, argc, Qfalse, LONG2FIX(flag)); + ADD_SEND_R(ret, line, idAREF, argc, Qfalse, INT2FIX(flag)); if (id == 0 || id == 1) { /* 0: or, 1: and @@ -4104,13 +4104,13 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4104 ADD_INSN(ret, line, pop); } ADD_SEND_R(ret, line, idASET, - argc, Qfalse, LONG2FIX(flag)); + argc, Qfalse, INT2FIX(flag)); } else { if (boff > 0) ADD_INSN(ret, line, swap); ADD_SEND_R(ret, line, idASET, - FIXNUM_INC(argc, 1), Qfalse, LONG2FIX(flag)); + FIXNUM_INC(argc, 1), Qfalse, INT2FIX(flag)); } ADD_INSN(ret, line, pop); ADD_INSNL(ret, line, jump, lfin); @@ -4141,13 +4141,13 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4141 ADD_INSN(ret, line, pop); } ADD_SEND_R(ret, line, idASET, - argc, Qfalse, LONG2FIX(flag)); + argc, Qfalse, INT2FIX(flag)); } else { if (boff > 0) ADD_INSN(ret, line, swap); ADD_SEND_R(ret, line, idASET, - FIXNUM_INC(argc, 1), Qfalse, LONG2FIX(flag)); + FIXNUM_INC(argc, 1), Qfalse, INT2FIX(flag)); } ADD_INSN(ret, line, pop); } @@ -4398,7 +4398,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4398 DECL_ANCHOR(args); ID mid = node->nd_mid; VALUE argc; - VALUE flag = 0; + unsigned int flag = 0; VALUE parent_block = iseq->compile_data->current_block; iseq->compile_data->current_block = Qfalse; @@ -4499,7 +4499,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4499 } ADD_SEND_R(ret, line, mid, - argc, parent_block, LONG2FIX(flag)); + argc, parent_block, INT2FIX(flag)); if (poped) { ADD_INSN(ret, line, pop); @@ -4510,7 +4510,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4510 case NODE_ZSUPER:{ DECL_ANCHOR(args); int argc; - VALUE flag = 0; + unsigned int flag = 0; VALUE parent_block = iseq->compile_data->current_block; INIT_ANCHOR(args); @@ -4699,7 +4699,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4699 case NODE_YIELD:{ DECL_ANCHOR(args); VALUE argc; - VALUE flag = 0; + unsigned int flag = 0; INIT_ANCHOR(args); if (iseq->type == ISEQ_TYPE_TOP) { @@ -5354,7 +5354,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L5354 case NODE_ATTRASGN:{ DECL_ANCHOR(recv); DECL_ANCHOR(args); - VALUE flag = 0; + unsigned int flag = 0; VALUE argc; int asgnflag; @@ -5418,7 +5418,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L5418 ADD_SEQ(ret, recv); ADD_SEQ(ret, args); } - ADD_SEND_R(ret, line, node->nd_mid, argc, 0, LONG2FIX(flag)); + ADD_SEND_R(ret, line, node->nd_mid, argc, 0, INT2FIX(flag)); ADD_INSN(ret, line, pop); break; @@ -5834,7 +5834,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/compile.c#L5834 ID mid = 0; int orig_argc = 0; VALUE block = 0; - unsigned long flag = 0; + unsigned int flag = 0; if (!NIL_P(op)) { VALUE vmid = rb_hash_aref(op, ID2SYM(rb_intern("mid"))); @@ -5843,7 +5843,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/compile.c#L5843 VALUE vblock = rb_hash_aref(op, ID2SYM(rb_intern("blockptr"))); if (!NIL_P(vmid)) mid = SYM2ID(vmid); - if (!NIL_P(vflag)) flag = NUM2ULONG(vflag); + if (!NIL_P(vflag)) flag = NUM2UINT(vflag); if (!NIL_P(vorig_argc)) orig_argc = FIX2INT(vorig_argc); if (!NIL_P(vblock)) block = iseq_build_load_iseq(iseq, vblock); } Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 47508) +++ vm_insnhelper.c (revision 47509) @@ -498,7 +498,7 @@ vm_getivar(VALUE obj, ID id, IC ic, rb_c https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L498 if (LIKELY((!is_attr && ic->ic_serial == RCLASS_SERIAL(klass)) || (is_attr && ci->aux.index > 0))) { - long index = !is_attr ? (long)ic->ic_value.index : ci->aux.index - 1; + int index = !is_attr ? (int)ic->ic_value.index : ci->aux.index - 1; long len = ROBJECT_NUMIV(obj); VALUE *ptr = ROBJECT_IVPTR(obj); @@ -522,7 +522,7 @@ vm_getivar(VALUE obj, ID id, IC ic, rb_c https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L522 ic->ic_serial = RCLASS_SERIAL(klass); } else { /* call_info */ - ci->aux.index = index + 1; + ci->aux.index = (int)index + 1; } } } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/