summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-12-10 08:21:33 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-12-10 08:21:33 +0000
commitcdc2eeda6a66359d295620792adb67102673ce54 (patch)
tree1beb2c348b1fe34bbe1d7be8e9115cef6918e3a0 /gc.c
parent27947a449f885e71bbb62fcffcd3545cb28dcae0 (diff)
gc.c: simple array for wmap
* gc.c (wmap_finalize, wmap_aset_update): use simple malloced array instead of T_ARRAY, to reduce GC pressure. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44119 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c56
1 files changed, 37 insertions, 19 deletions
diff --git a/gc.c b/gc.c
index 154febc08a..0bfba71530 100644
--- a/gc.c
+++ b/gc.c
@@ -6235,7 +6235,6 @@ wmap_mark_map(st_data_t key, st_data_t val, st_data_t arg)
rb_objspace_t *objspace = (rb_objspace_t *)arg;
VALUE obj = (VALUE)val;
if (!is_live_object(objspace, obj)) return ST_DELETE;
- gc_mark_ptr(objspace, obj);
return ST_CONTINUE;
}
@@ -6250,7 +6249,8 @@ wmap_mark(void *ptr)
static int
wmap_free_map(st_data_t key, st_data_t val, st_data_t arg)
{
- rb_ary_resize((VALUE)val, 0);
+ VALUE *ptr = (VALUE *)val;
+ ruby_sized_xfree(ptr, (ptr[0] + 1) * sizeof(VALUE));
return ST_CONTINUE;
}
@@ -6263,11 +6263,11 @@ wmap_free(void *ptr)
st_free_table(w->wmap2obj);
}
-size_t rb_ary_memsize(VALUE ary);
static int
wmap_memsize_map(st_data_t key, st_data_t val, st_data_t arg)
{
- *(size_t *)arg += rb_ary_memsize((VALUE)val);
+ VALUE *ptr = (VALUE *)val;
+ *(size_t *)arg += (ptr[0] + 1) * sizeof(VALUE);
return ST_CONTINUE;
}
@@ -6308,11 +6308,22 @@ wmap_allocate(VALUE klass)
static int
wmap_final_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
{
- VALUE wmap, ary;
+ VALUE wmap, *ptr, size, i, j;
if (!existing) return ST_STOP;
- wmap = (VALUE)arg, ary = (VALUE)*value;
- rb_ary_delete_same(ary, wmap);
- if (!RARRAY_LEN(ary)) return ST_DELETE;
+ wmap = (VALUE)arg, ptr = (VALUE *)*value;
+ for (i = j = 1, size = ptr[0]; i <= size; ++i) {
+ if (ptr[i] != wmap) {
+ ptr[j++] = ptr[i];
+ }
+ }
+ if (j == 1) {
+ ruby_sized_xfree(ptr, i * sizeof(VALUE));
+ return ST_DELETE;
+ }
+ if (j < i) {
+ ptr = ruby_sized_xrealloc2(ptr, j, sizeof(VALUE), i);
+ ptr[0] = j;
+ }
return ST_CONTINUE;
}
@@ -6320,8 +6331,7 @@ static VALUE
wmap_finalize(VALUE self, VALUE objid)
{
st_data_t orig, wmap, data;
- VALUE obj, rids;
- long i;
+ VALUE obj, *rids, i, size;
struct weakmap *w;
TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
@@ -6331,11 +6341,13 @@ wmap_finalize(VALUE self, VALUE objid)
/* obj is original referenced object and/or weak reference. */
orig = (st_data_t)obj;
if (st_delete(w->obj2wmap, &orig, &data)) {
- rids = (VALUE)data;
- for (i = 0; i < RARRAY_LEN(rids); ++i) {
- wmap = (st_data_t)RARRAY_AREF(rids, i);
+ rids = (VALUE *)data;
+ size = *rids++;
+ for (i = 0; i < size; ++i) {
+ wmap = (st_data_t)rids[i];
st_delete(w->wmap2obj, &wmap, NULL);
}
+ ruby_sized_xfree((VALUE *)data, (size + 1) * sizeof(VALUE));
}
wmap = (st_data_t)obj;
@@ -6511,15 +6523,21 @@ wmap_values(VALUE self)
static int
wmap_aset_update(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
{
+ VALUE size, *ptr, *optr;
if (existing) {
- rb_ary_push((VALUE)*val, (VALUE)arg);
- return ST_STOP;
+ size = (ptr = optr = (VALUE *)*val)[0];
+ ++size;
+ ptr = ruby_sized_xrealloc2(ptr, size + 1, sizeof(VALUE), size);
}
else {
- VALUE ary = rb_ary_tmp_new(1);
- *val = (st_data_t)ary;
- rb_ary_push(ary, (VALUE)arg);
- }
+ optr = 0;
+ size = 1;
+ ptr = ruby_xmalloc2(2, sizeof(VALUE));
+ }
+ ptr[0] = size;
+ ptr[size] = (VALUE)arg;
+ if (ptr == optr) return ST_STOP;
+ *val = (st_data_t)ptr;
return ST_CONTINUE;
}