aboutsummaryrefslogtreecommitdiffstats
path: root/array.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-05-13 18:07:47 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-05-13 18:07:47 +0000
commit4f401816ffaf9b641cfbc8ad12203eedcdb527de (patch)
treec6a4a87c877c3cc69b308af6bcf72e4cefcdd86e /array.c
parent7958c71ee57b0e394ed5e99f724161eacadf3056 (diff)
downloadruby-4f401816ffaf9b641cfbc8ad12203eedcdb527de.tar.gz
* 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
Diffstat (limited to 'array.c')
-rw-r--r--array.c35
1 files changed, 25 insertions, 10 deletions
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;