summaryrefslogtreecommitdiffhomepage
path: root/src/gc.c
diff options
context:
space:
mode:
authorPaolo Bosetti <[email protected]>2012-05-31 18:52:33 -0700
committerPaolo Bosetti <[email protected]>2012-05-31 18:52:33 -0700
commit9c0bfd343679fcd84090b7611ed582ae31e0e3b9 (patch)
tree75e6ac394862821a0e466ccfee361655c40ae749 /src/gc.c
parent6dbba7b799e0cf1a86ec86f347bbc1b40420d372 (diff)
parent8180fee1808c56048b9fa18a8dd16014e694e48e (diff)
downloadmruby-9c0bfd343679fcd84090b7611ed582ae31e0e3b9.tar.gz
mruby-9c0bfd343679fcd84090b7611ed582ae31e0e3b9.zip
Merge branch 'master' of git://github.com/mruby/mruby into XCode
Diffstat (limited to 'src/gc.c')
-rw-r--r--src/gc.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/src/gc.c b/src/gc.c
index 999a1a7d2..04be437c1 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -242,6 +242,24 @@ mrb_init_heap(mrb_state *mrb)
#endif
}
+static void
+gc_protect(mrb_state *mrb, struct RBasic *p)
+{
+ if (mrb->arena_idx > MRB_ARENA_SIZE) {
+ /* arena overflow error */
+ mrb->arena_idx = MRB_ARENA_SIZE - 4; /* force room in arena */
+ mrb_raise(mrb, mrb->eRuntimeError_class, "arena overflow error");
+ }
+ mrb->arena[mrb->arena_idx++] = p;
+}
+
+void
+mrb_gc_protect(mrb_state *mrb, mrb_value obj)
+{
+ if (SPECIAL_CONST_P(obj)) return;
+ gc_protect(mrb, RBASIC(obj));
+}
+
struct RBasic*
mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls)
{
@@ -264,12 +282,7 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls)
}
mrb->live++;
- if (mrb->arena_idx > MRB_ARENA_SIZE) {
- /* arena overflow error */
- mrb->arena_idx = MRB_ARENA_SIZE - 2; /* force room in arena */
- mrb_raise(mrb, mrb->eRuntimeError_class, "arena overflow error");
- }
- mrb->arena[mrb->arena_idx++] = p;
+ gc_protect(mrb, p);
memset(p, 0, sizeof(RVALUE));
p->tt = ttype;
p->c = cls;
@@ -362,9 +375,8 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj)
{
struct RString *s = (struct RString*)obj;
- while (s->flags & MRB_STR_SHARED) {
- s = s->aux.shared;
- if (!s) break;
+ if (s->flags & MRB_STR_SHARED) {
+ mrb_gc_mark(mrb, (struct RBasic*)s->aux.shared);
}
}
break;