From 4f401816ffaf9b641cfbc8ad12203eedcdb527de Mon Sep 17 00:00:00 2001 From: ko1 Date: Mon, 13 May 2013 18:07:47 +0000 Subject: * gc.c: support RGENGC. [ruby-trunk - Feature #8339] See this ticet about RGENGC. * gc.c: Add several flags: * RGENGC_DEBUG: if >0, then prints debug information. * RGENGC_CHECK_MODE: if >0, add assertions. * RGENGC_PROFILE: if >0, add profiling features. check GC.stat and GC::Profiler. * include/ruby/ruby.h: disable RGENGC by default (USE_RGENGC == 0). * array.c: add write barriers for T_ARRAY and generate sunny objects. * include/ruby/ruby.h (RARRAY_PTR_USE): added. Use this macro if you want to access raw pointers. If you modify the contents which pointer pointed, then you need to care write barrier. * bignum.c, marshal.c, random.c: generate T_BIGNUM sunny objects. * complex.c, include/ruby/ruby.h: add write barriers for T_COMPLEX and generate sunny objects. * rational.c (nurat_s_new_internal), include/ruby/ruby.h: add write barriers for T_RATIONAL and generate sunny objects. * internal.h: add write barriers for RBasic::klass. * numeric.c (rb_float_new_in_heap): generate sunny T_FLOAT objects. * object.c (rb_class_allocate_instance), range.c: generate sunny T_OBJECT objects. * string.c: add write barriers for T_STRING and generate sunny objects. * variable.c: add write barriers for ivars. * vm_insnhelper.c (vm_setivar): ditto. * include/ruby/ruby.h, debug.c: use two flags FL_WB_PROTECTED and FL_OLDGEN. * node.h (NODE_FL_CREF_PUSHED_BY_EVAL, NODE_FL_CREF_OMOD_SHARED): move flag bits. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40703 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- array.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'array.c') diff --git a/array.c b/array.c index f605af264b..f5f6d6f82f 100644 --- a/array.c +++ b/array.c @@ -128,10 +128,12 @@ memfill(register VALUE *mem, register long size, register VALUE val) #define ARY_SHARED(ary) (assert(ARY_SHARED_P(ary)), RARRAY(ary)->as.heap.aux.shared) #define ARY_SET_SHARED(ary, value) do { \ - assert(!ARY_EMBED_P(ary)); \ - assert(ARY_SHARED_P(ary)); \ - assert(ARY_SHARED_ROOT_P(value)); \ - RARRAY(ary)->as.heap.aux.shared = (value); \ + const VALUE _ary_ = (ary); \ + const VALUE _value_ = (value); \ + assert(!ARY_EMBED_P(_ary_)); \ + assert(ARY_SHARED_P(_ary_)); \ + assert(ARY_SHARED_ROOT_P(_value_)); \ + OBJ_WRITE(_ary_, &RARRAY(_ary_)->as.heap.aux.shared, _value_); \ } while (0) #define RARRAY_SHARED_ROOT_FLAG FL_USER5 #define ARY_SHARED_ROOT_P(ary) (FL_TEST((ary), RARRAY_SHARED_ROOT_FLAG)) @@ -370,7 +372,7 @@ rb_ary_shared_with_p(VALUE ary1, VALUE ary2) static VALUE ary_alloc(VALUE klass) { - NEWOBJ_OF(ary, struct RArray, klass, T_ARRAY); + NEWOBJ_OF(ary, struct RArray, klass, T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0)); FL_SET_EMBED((VALUE)ary); ARY_SET_EMBED_LEN((VALUE)ary, 0); @@ -409,6 +411,14 @@ ary_new(VALUE klass, long capa) ARY_SET_PTR(ary, ALLOC_N(VALUE, capa)); ARY_SET_CAPA(ary, capa); ARY_SET_HEAP_LEN(ary, 0); + + /* NOTE: `ary' can be old because the following suquence is possible. + * (1) ary = ary_alloc(); + * (2) GC (for (3)) -> promote ary + * (3) ALLOC_N(VALUE, capa) + * So that force ary as young object. + */ + RBASIC(ary)->flags &= ~FL_OLDGEN; } return ary; @@ -455,7 +465,9 @@ rb_ary_new4(long n, const VALUE *elts) ary = rb_ary_new2(n); if (n > 0 && elts) { - MEMCPY(RARRAY_PTR(ary), elts, VALUE, n); + RARRAY_PTR_USE(ary, ptr, { + MEMCPY(ptr, elts, VALUE, n); /* new array is not old gen */ + }); ARY_SET_LEN(ary, n); } @@ -512,7 +524,7 @@ ary_make_shared(VALUE ary) return ary; } else { - NEWOBJ_OF(shared, struct RArray, 0, T_ARRAY); + NEWOBJ_OF(shared, struct RArray, 0, T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0)); FL_UNSET_EMBED(shared); ARY_SET_LEN((VALUE)shared, ARY_CAPA(ary)); @@ -649,8 +661,8 @@ rb_ary_initialize(int argc, VALUE *argv, VALUE ary) rb_ary_modify(ary); if (argc == 0) { - if (ARY_OWNS_HEAP_P(ary) && RARRAY_PTR(ary)) { - xfree(RARRAY_PTR(ary)); + if (ARY_OWNS_HEAP_P(ary) && RARRAY_RAWPTR(ary) != 0) { + xfree(RARRAY_RAWPTR(ary)); } rb_ary_unshare_safe(ary); FL_SET_EMBED(ary); @@ -690,7 +702,10 @@ rb_ary_initialize(int argc, VALUE *argv, VALUE ary) } } else { - memfill(RARRAY_PTR(ary), len, val); + RARRAY_PTR_USE(ary, ptr, { + memfill(ptr, len, val); + }); + OBJ_WRITTEN(ary, Qundef, val); ARY_SET_LEN(ary, len); } return ary; -- cgit v1.2.3