Permalink
Browse files

accessing to ivar should be fast

  • Loading branch information...
tarui committed Apr 12, 2016
1 parent 456523e commit dd993da80c7ad84340689137bf8b308793595cae
Showing with 46 additions and 8 deletions.
  1. +18 −5 compile.c
  2. +23 −3 insns.def
  3. +4 −0 iseq.c
  4. +1 −0 iseq.h
View
@@ -4571,8 +4571,16 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
if (!poped) {
ADD_INSN(ret, line, dup);
}
ADD_INSN2(ret, line, setinstancevariable,
ID2SYM(node->nd_vid), INT2FIX(iseq->body->is_size++));
{
st_table *tbl = ISEQ_COMPILE_DATA(iseq)->ivar_cache_table;
VALUE id,val;
id = ID2SYM(node->nd_vid);
if(!st_lookup(tbl,id,&val)){
val = INT2FIX(iseq->body->is_size++);
st_insert(tbl,id,val);
}
ADD_INSN2(ret, line, setinstancevariable,id,val);
}
break;
}
case NODE_CDECL:{
@@ -5381,8 +5389,14 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
case NODE_IVAR:{
debugi("nd_vid", node->nd_vid);
if (!poped) {
ADD_INSN2(ret, line, getinstancevariable,
ID2SYM(node->nd_vid), INT2FIX(iseq->body->is_size++));
st_table *tbl = ISEQ_COMPILE_DATA(iseq)->ivar_cache_table;
VALUE id,val;
id = ID2SYM(node->nd_vid);
if(!st_lookup(tbl,id,&val)){
val = INT2FIX(iseq->body->is_size++);
st_insert(tbl,id,val);
}
ADD_INSN2(ret, line, getinstancevariable,id,val);
}
break;
}
@@ -8441,4 +8455,3 @@ iseq_ibf_load_extra_data(VALUE str)
RB_GC_GUARD(loader_obj);
return extra_str;
}
View
@@ -130,7 +130,20 @@ getinstancevariable
()
(VALUE val)
{
val = vm_getinstancevariable(GET_SELF(), id, ic);
if (LIKELY(ic->ic_serial == RCLASS_SERIAL(RBASIC(GET_SELF())->klass))) {
long index = ic->ic_value.index;
val = Qundef;
if (index < ROBJECT_NUMIV(GET_SELF())) {
val = ROBJECT_IVPTR(GET_SELF())[index];
}
if (UNLIKELY(val == Qundef)) {
if (RTEST(ruby_verbose))
rb_warning("instance variable %"PRIsVALUE" not initialized", QUOTE_ID(id));
val = Qnil;
}
}else{
val = vm_getinstancevariable(GET_SELF(), id, ic);
}
}
/**
@@ -145,7 +158,15 @@ setinstancevariable
(VALUE val)
()
{
vm_setinstancevariable(GET_SELF(), id, val, ic);
if (LIKELY(
RB_TYPE_P(GET_SELF(),T_OBJECT) &&
ic->ic_serial == RCLASS_SERIAL(RBASIC(GET_SELF())->klass) &&
(long)ic->ic_value.index < ROBJECT_NUMIV(GET_SELF()))) {
rb_check_frozen(GET_SELF());
RB_OBJ_WRITE(GET_SELF(),&ROBJECT_IVPTR(GET_SELF())[(long)ic->ic_value.index],val);
}else{
vm_setinstancevariable(GET_SELF(), id, val, ic);
}
}
/**
@@ -2193,4 +2214,3 @@ answer
{
ret = INT2FIX(42);
}
View
4 iseq.c
@@ -58,6 +58,8 @@ compile_data_free(struct iseq_compile_data *compile_data)
ruby_xfree(cur);
cur = next;
}
st_free_table(compile_data->ivar_cache_table);
ruby_xfree(compile_data);
}
}
@@ -298,6 +300,8 @@ prepare_iseq_build(rb_iseq_t *iseq,
ISEQ_COMPILE_DATA(iseq)->option = option;
ISEQ_COMPILE_DATA(iseq)->last_coverable_line = -1;
ISEQ_COMPILE_DATA(iseq)->ivar_cache_table = st_init_numtable();
if (option->coverage_enabled) {
VALUE coverages = rb_get_coverages();
if (RTEST(coverages)) {
View
1 iseq.h
@@ -213,6 +213,7 @@ struct iseq_compile_data {
unsigned int ci_index;
unsigned int ci_kw_index;
const rb_compile_option_t *option;
st_table *ivar_cache_table;
#if SUPPORT_JOKE
st_table *labels_table;
#endif

2 comments on commit dd993da

@tarui

This comment has been minimized.

Show comment
Hide comment
@tarui

tarui Apr 12, 2016

Owner

On mame's optcarrot benchmark, (https://github.com/mame/optcarrot/)
it is 10 % faster than trunk.

$ ./ruby -v --disable-gems ../../optcarrot/bin/optcarrot --benchmark ../../optcarrot/examples/Lan_Master.nes
ruby 2.4.0dev (2016-04-12 trunk 54553) [x86_64-linux]
fps: 13.664029283085743
checksum: 59662

$ ./ruby -v --disable-gems ../../optcarrot/bin/optcarrot --benchmark ../../optcarrot/examples/Lan_Master.nes
ruby 2.4.0dev (2016-04-12 fast-ivar-access 54553) [x86_64-linux]
fps: 15.120651593726231
checksum: 59662

Owner

tarui replied Apr 12, 2016

On mame's optcarrot benchmark, (https://github.com/mame/optcarrot/)
it is 10 % faster than trunk.

$ ./ruby -v --disable-gems ../../optcarrot/bin/optcarrot --benchmark ../../optcarrot/examples/Lan_Master.nes
ruby 2.4.0dev (2016-04-12 trunk 54553) [x86_64-linux]
fps: 13.664029283085743
checksum: 59662

$ ./ruby -v --disable-gems ../../optcarrot/bin/optcarrot --benchmark ../../optcarrot/examples/Lan_Master.nes
ruby 2.4.0dev (2016-04-12 fast-ivar-access 54553) [x86_64-linux]
fps: 15.120651593726231
checksum: 59662

@dhiachou

This comment has been minimized.

Show comment
Hide comment
@dhiachou

dhiachou Oct 11, 2016

I am not an expert here, but I believe that you can extract the repetitive code and DRY up a bit ?

dhiachou replied Oct 11, 2016

I am not an expert here, but I believe that you can extract the repetitive code and DRY up a bit ?

Please sign in to comment.