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 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47509 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ea4c97904e
commit
b3a4367ce4
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
|||||||
|
Wed Sep 10 15:29:46 2014 Eric Wong <e@80x24.org>
|
||||||
|
|
||||||
|
* 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@80x24.org>
|
Wed Sep 10 15:07:35 2014 Eric Wong <e@80x24.org>
|
||||||
|
|
||||||
* compile.c (rb_iseq_translate_threaded_code):
|
* compile.c (rb_iseq_translate_threaded_code):
|
||||||
|
32
compile.c
32
compile.c
@ -981,7 +981,7 @@ new_insn_body(rb_iseq_t *iseq, int line_no, enum ruby_vminsn_type insn_id, int a
|
|||||||
}
|
}
|
||||||
|
|
||||||
static rb_call_info_t *
|
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));
|
rb_call_info_t *ci = (rb_call_info_t *)compile_data_alloc(iseq, sizeof(rb_call_info_t));
|
||||||
ci->mid = mid;
|
ci->mid = mid;
|
||||||
@ -3119,7 +3119,7 @@ add_ensure_iseq(LINK_ANCHOR *ret, rb_iseq_t *iseq, int is_return)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
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);
|
VALUE argc = INT2FIX(0);
|
||||||
int nsplat = 0;
|
int nsplat = 0;
|
||||||
@ -4015,7 +4015,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
case NODE_OP_ASGN1: {
|
case NODE_OP_ASGN1: {
|
||||||
DECL_ANCHOR(args);
|
DECL_ANCHOR(args);
|
||||||
VALUE argc;
|
VALUE argc;
|
||||||
VALUE flag = 0;
|
unsigned int flag = 0;
|
||||||
VALUE asgnflag = 0;
|
VALUE asgnflag = 0;
|
||||||
ID id = node->nd_mid;
|
ID id = node->nd_mid;
|
||||||
int boff = 0;
|
int boff = 0;
|
||||||
@ -4060,7 +4060,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
}
|
}
|
||||||
ADD_INSN1(ret, line, dupn, FIXNUM_INC(argc, 1 + boff));
|
ADD_INSN1(ret, line, dupn, FIXNUM_INC(argc, 1 + boff));
|
||||||
flag |= asgnflag;
|
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) {
|
if (id == 0 || id == 1) {
|
||||||
/* 0: or, 1: and
|
/* 0: or, 1: and
|
||||||
@ -4104,13 +4104,13 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
ADD_INSN(ret, line, pop);
|
ADD_INSN(ret, line, pop);
|
||||||
}
|
}
|
||||||
ADD_SEND_R(ret, line, idASET,
|
ADD_SEND_R(ret, line, idASET,
|
||||||
argc, Qfalse, LONG2FIX(flag));
|
argc, Qfalse, INT2FIX(flag));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (boff > 0)
|
if (boff > 0)
|
||||||
ADD_INSN(ret, line, swap);
|
ADD_INSN(ret, line, swap);
|
||||||
ADD_SEND_R(ret, line, idASET,
|
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_INSN(ret, line, pop);
|
||||||
ADD_INSNL(ret, line, jump, lfin);
|
ADD_INSNL(ret, line, jump, lfin);
|
||||||
@ -4141,13 +4141,13 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
ADD_INSN(ret, line, pop);
|
ADD_INSN(ret, line, pop);
|
||||||
}
|
}
|
||||||
ADD_SEND_R(ret, line, idASET,
|
ADD_SEND_R(ret, line, idASET,
|
||||||
argc, Qfalse, LONG2FIX(flag));
|
argc, Qfalse, INT2FIX(flag));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (boff > 0)
|
if (boff > 0)
|
||||||
ADD_INSN(ret, line, swap);
|
ADD_INSN(ret, line, swap);
|
||||||
ADD_SEND_R(ret, line, idASET,
|
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_INSN(ret, line, pop);
|
||||||
}
|
}
|
||||||
@ -4398,7 +4398,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
DECL_ANCHOR(args);
|
DECL_ANCHOR(args);
|
||||||
ID mid = node->nd_mid;
|
ID mid = node->nd_mid;
|
||||||
VALUE argc;
|
VALUE argc;
|
||||||
VALUE flag = 0;
|
unsigned int flag = 0;
|
||||||
VALUE parent_block = iseq->compile_data->current_block;
|
VALUE parent_block = iseq->compile_data->current_block;
|
||||||
iseq->compile_data->current_block = Qfalse;
|
iseq->compile_data->current_block = Qfalse;
|
||||||
|
|
||||||
@ -4499,7 +4499,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ADD_SEND_R(ret, line, mid,
|
ADD_SEND_R(ret, line, mid,
|
||||||
argc, parent_block, LONG2FIX(flag));
|
argc, parent_block, INT2FIX(flag));
|
||||||
|
|
||||||
if (poped) {
|
if (poped) {
|
||||||
ADD_INSN(ret, line, pop);
|
ADD_INSN(ret, line, pop);
|
||||||
@ -4510,7 +4510,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
case NODE_ZSUPER:{
|
case NODE_ZSUPER:{
|
||||||
DECL_ANCHOR(args);
|
DECL_ANCHOR(args);
|
||||||
int argc;
|
int argc;
|
||||||
VALUE flag = 0;
|
unsigned int flag = 0;
|
||||||
VALUE parent_block = iseq->compile_data->current_block;
|
VALUE parent_block = iseq->compile_data->current_block;
|
||||||
|
|
||||||
INIT_ANCHOR(args);
|
INIT_ANCHOR(args);
|
||||||
@ -4699,7 +4699,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
case NODE_YIELD:{
|
case NODE_YIELD:{
|
||||||
DECL_ANCHOR(args);
|
DECL_ANCHOR(args);
|
||||||
VALUE argc;
|
VALUE argc;
|
||||||
VALUE flag = 0;
|
unsigned int flag = 0;
|
||||||
|
|
||||||
INIT_ANCHOR(args);
|
INIT_ANCHOR(args);
|
||||||
if (iseq->type == ISEQ_TYPE_TOP) {
|
if (iseq->type == ISEQ_TYPE_TOP) {
|
||||||
@ -5354,7 +5354,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
case NODE_ATTRASGN:{
|
case NODE_ATTRASGN:{
|
||||||
DECL_ANCHOR(recv);
|
DECL_ANCHOR(recv);
|
||||||
DECL_ANCHOR(args);
|
DECL_ANCHOR(args);
|
||||||
VALUE flag = 0;
|
unsigned int flag = 0;
|
||||||
VALUE argc;
|
VALUE argc;
|
||||||
int asgnflag;
|
int asgnflag;
|
||||||
|
|
||||||
@ -5418,7 +5418,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
ADD_SEQ(ret, recv);
|
ADD_SEQ(ret, recv);
|
||||||
ADD_SEQ(ret, args);
|
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);
|
ADD_INSN(ret, line, pop);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -5834,7 +5834,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
|
|||||||
ID mid = 0;
|
ID mid = 0;
|
||||||
int orig_argc = 0;
|
int orig_argc = 0;
|
||||||
VALUE block = 0;
|
VALUE block = 0;
|
||||||
unsigned long flag = 0;
|
unsigned int flag = 0;
|
||||||
|
|
||||||
if (!NIL_P(op)) {
|
if (!NIL_P(op)) {
|
||||||
VALUE vmid = rb_hash_aref(op, ID2SYM(rb_intern("mid")));
|
VALUE vmid = rb_hash_aref(op, ID2SYM(rb_intern("mid")));
|
||||||
@ -5843,7 +5843,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
|
|||||||
VALUE vblock = rb_hash_aref(op, ID2SYM(rb_intern("blockptr")));
|
VALUE vblock = rb_hash_aref(op, ID2SYM(rb_intern("blockptr")));
|
||||||
|
|
||||||
if (!NIL_P(vmid)) mid = SYM2ID(vmid);
|
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(vorig_argc)) orig_argc = FIX2INT(vorig_argc);
|
||||||
if (!NIL_P(vblock)) block = iseq_build_load_iseq(iseq, vblock);
|
if (!NIL_P(vblock)) block = iseq_build_load_iseq(iseq, vblock);
|
||||||
}
|
}
|
||||||
|
@ -775,7 +775,7 @@ struct RObject {
|
|||||||
struct RBasic basic;
|
struct RBasic basic;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
long numiv;
|
long numiv; /* only uses 32-bits */
|
||||||
VALUE *ivptr;
|
VALUE *ivptr;
|
||||||
struct st_table *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */
|
struct st_table *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */
|
||||||
} heap;
|
} heap;
|
||||||
|
@ -1173,6 +1173,10 @@ rb_ivar_set(VALUE obj, ID id, VALUE val)
|
|||||||
iv_index_tbl->num_entries < (st_index_t)newsize) {
|
iv_index_tbl->num_entries < (st_index_t)newsize) {
|
||||||
newsize = iv_index_tbl->num_entries;
|
newsize = iv_index_tbl->num_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* never happens in practice: */
|
||||||
|
if (newsize > INT_MAX) rb_memerror();
|
||||||
|
|
||||||
if (RBASIC(obj)->flags & ROBJECT_EMBED) {
|
if (RBASIC(obj)->flags & ROBJECT_EMBED) {
|
||||||
newptr = ALLOC_N(VALUE, newsize);
|
newptr = ALLOC_N(VALUE, newsize);
|
||||||
MEMCPY(newptr, ptr, VALUE, len);
|
MEMCPY(newptr, ptr, VALUE, len);
|
||||||
|
@ -140,11 +140,9 @@ struct rb_control_frame_struct;
|
|||||||
typedef struct rb_call_info_struct {
|
typedef struct rb_call_info_struct {
|
||||||
/* fixed at compile time */
|
/* fixed at compile time */
|
||||||
ID mid;
|
ID mid;
|
||||||
VALUE flag;
|
unsigned int flag;
|
||||||
rb_iseq_t *blockiseq;
|
|
||||||
int orig_argc;
|
int orig_argc;
|
||||||
|
rb_iseq_t *blockiseq;
|
||||||
int argc; /* temporary for method calling */
|
|
||||||
|
|
||||||
/* inline cache: keys */
|
/* inline cache: keys */
|
||||||
rb_serial_t method_state;
|
rb_serial_t method_state;
|
||||||
@ -158,9 +156,10 @@ typedef struct rb_call_info_struct {
|
|||||||
/* temporary values for method calling */
|
/* temporary values for method calling */
|
||||||
struct rb_block_struct *blockptr;
|
struct rb_block_struct *blockptr;
|
||||||
VALUE recv;
|
VALUE recv;
|
||||||
|
int argc;
|
||||||
union {
|
union {
|
||||||
int opt_pc; /* used by iseq */
|
int opt_pc; /* used by iseq */
|
||||||
long index; /* used by ivar */
|
int index; /* used by ivar */
|
||||||
int missing_reason; /* used by method_missing */
|
int missing_reason; /* used by method_missing */
|
||||||
int inc_sp; /* used by cfunc */
|
int inc_sp; /* used by cfunc */
|
||||||
} aux;
|
} aux;
|
||||||
|
@ -498,7 +498,7 @@ vm_getivar(VALUE obj, ID id, IC ic, rb_call_info_t *ci, int is_attr)
|
|||||||
|
|
||||||
if (LIKELY((!is_attr && ic->ic_serial == RCLASS_SERIAL(klass)) ||
|
if (LIKELY((!is_attr && ic->ic_serial == RCLASS_SERIAL(klass)) ||
|
||||||
(is_attr && ci->aux.index > 0))) {
|
(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);
|
long len = ROBJECT_NUMIV(obj);
|
||||||
VALUE *ptr = ROBJECT_IVPTR(obj);
|
VALUE *ptr = ROBJECT_IVPTR(obj);
|
||||||
|
|
||||||
@ -522,7 +522,7 @@ vm_getivar(VALUE obj, ID id, IC ic, rb_call_info_t *ci, int is_attr)
|
|||||||
ic->ic_serial = RCLASS_SERIAL(klass);
|
ic->ic_serial = RCLASS_SERIAL(klass);
|
||||||
}
|
}
|
||||||
else { /* call_info */
|
else { /* call_info */
|
||||||
ci->aux.index = index + 1;
|
ci->aux.index = (int)index + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user