Project

General

Profile

Actions

Backport #8142

closed

[patch] iseq: reduce array allocations for simple sequences

Added by tmm1 (Aman Karmani) about 11 years ago. Updated almost 11 years ago.


Description

Allocate iseq->mark_ary on demand, only if needed.

In my application, this reduces long lived arrays on the heap significantly.

:T_ARRAY=>88166 # before
:T_ARRAY=>62932 # after

diff --git a/compile.c b/compile.c
index 9360f5b..aafae05 100644
--- a/compile.c
+++ b/compile.c
@@ -416,7 +416,7 @@ static int
iseq_add_mark_object(rb_iseq_t *iseq, VALUE v)
{
if (!SPECIAL_CONST_P(v)) {

  • rb_ary_push(iseq->mark_ary, v);
  • rb_iseq_add_mark_object(iseq, v);
    }
    return COMPILE_OK;
    }
    diff --git a/insns.def b/insns.def
    index 979aa1c..bb9fc3f 100644
    --- a/insns.def
    +++ b/insns.def
    @@ -1237,7 +1237,7 @@ setinlinecache
    (VALUE val)
    {
    if (ic->ic_value.value == Qundef) {
  • rb_ary_push(GET_ISEQ()->mark_ary, val);
  • rb_iseq_add_mark_object(GET_ISEQ(), val);
    }
    ic->ic_value.value = val;
    ic->ic_vmstat = GET_VM_STATE_VERSION() - ruby_vm_const_missing_count;
    diff --git a/iseq.c b/iseq.c
    index 288d3bf..eab237a 100644
    --- a/iseq.c
    +++ b/iseq.c
    @@ -237,6 +237,17 @@ set_relation(rb_iseq_t *iseq, const VALUE parent)
    }
    }

+void
+rb_iseq_add_mark_object(rb_iseq_t *iseq, VALUE obj)
+{

  • if (!RTEST(iseq->mark_ary)) {
  •    iseq->mark_ary = rb_ary_tmp_new(3);
    
  •    OBJ_UNTRUST(iseq->mark_ary);
    
  •    RBASIC(iseq->mark_ary)->klass = 0;
    
  • }
  • rb_ary_push(iseq->mark_ary, obj);
    +}

static VALUE
prepare_iseq_build(rb_iseq_t *iseq,
VALUE name, VALUE path, VALUE absolute_path, VALUE first_lineno,
@@ -259,9 +270,7 @@ prepare_iseq_build(rb_iseq_t *iseq,
}

 iseq->defined_method_id = 0;
  • iseq->mark_ary = rb_ary_tmp_new(3);
  • OBJ_UNTRUST(iseq->mark_ary);
  • RBASIC(iseq->mark_ary)->klass = 0;
  • iseq->mark_ary = 0;

    /*
    @@ -2060,8 +2069,7 @@ rb_iseq_build_for_ruby2cext(
    iseq->location.label = rb_str_new2(name);
    iseq->location.path = rb_str_new2(path);
    iseq->location.first_lineno = first_lineno;

  • iseq->mark_ary = rb_ary_tmp_new(3);
  • OBJ_UNTRUST(iseq->mark_ary);
  • iseq->mark_ary = 0;
    iseq->self = iseqval;

    iseq->iseq = ALLOC_N(VALUE, iseq->iseq_size);
    diff --git a/iseq.h b/iseq.h
    index 0790529..4de0816 100644
    --- a/iseq.h
    +++ b/iseq.h
    @@ -23,6 +23,7 @@ VALUE rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE locals, VALUE args,
    VALUE exception, VALUE body);

/* iseq.c */
+void rb_iseq_add_mark_object(rb_iseq_t *iseq, VALUE obj);
VALUE rb_iseq_load(VALUE data, VALUE parent, VALUE opt);
VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc);
struct st_table *ruby_insn_make_insn_table(void);

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0