summaryrefslogtreecommitdiffhomepage
path: root/src/gc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gc.c')
-rw-r--r--src/gc.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/src/gc.c b/src/gc.c
index 5531207db..0f2c3bfab 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -6,6 +6,9 @@
#include <string.h>
#include <stdlib.h>
+#ifdef MRB_USE_MALLOC_TRIM
+#include <malloc.h>
+#endif
#include <mruby.h>
#include <mruby/array.h>
#include <mruby/class.h>
@@ -35,6 +38,11 @@
* Gray - Marked, But the child objects are unmarked.
* Black - Marked, the child objects are also marked.
+ Extra color
+
+ * Red - Static (ROM object) no need to be collected.
+ - All child objects should be Red as well.
+
== Two White Types
There're two white color types in a flip-flop fashion: White-A and White-B,
@@ -117,7 +125,7 @@ typedef struct {
struct RException exc;
struct RBreak brk;
#ifdef MRB_WORD_BOXING
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
struct RFloat floatv;
#endif
struct RCptr cptr;
@@ -185,6 +193,7 @@ gettimeofday_time(void)
#define GC_WHITE_A 1
#define GC_WHITE_B (1 << 1)
#define GC_BLACK (1 << 2)
+#define GC_RED 7
#define GC_WHITES (GC_WHITE_A | GC_WHITE_B)
#define GC_COLOR_MASK 7
@@ -194,7 +203,8 @@ gettimeofday_time(void)
#define paint_partial_white(s, o) ((o)->color = (s)->current_white_part)
#define is_gray(o) ((o)->color == GC_GRAY)
#define is_white(o) ((o)->color & GC_WHITES)
-#define is_black(o) ((o)->color & GC_BLACK)
+#define is_black(o) ((o)->color == GC_BLACK)
+#define is_red(o) ((o)->color == GC_RED)
#define flip_white_part(s) ((s)->current_white_part = other_white_part(s))
#define other_white_part(s) ((s)->current_white_part ^ GC_WHITES)
#define is_dead(s, o) (((o)->color & other_white_part(s) & GC_WHITES) || (o)->tt == MRB_TT_FREE)
@@ -581,11 +591,11 @@ add_gray_list(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
gc->gray_list = obj;
}
-static int
+static mrb_int
ci_nregs(mrb_callinfo *ci)
{
- struct RProc *p = ci->proc;
- int n = 0;
+ const struct RProc *p = ci->proc;
+ mrb_int n = 0;
if (!p) {
if (ci->argc < 0) return 3;
@@ -633,7 +643,6 @@ mark_context_stack(mrb_state *mrb, struct mrb_context *c)
static void
mark_context(mrb_state *mrb, struct mrb_context *c)
{
- int i;
mrb_callinfo *ci;
start:
@@ -650,10 +659,6 @@ mark_context(mrb_state *mrb, struct mrb_context *c)
mrb_gc_mark(mrb, (struct RBasic*)ci->target_class);
}
}
- /* mark ensure stack */
- for (i=0; i<c->eidx; i++) {
- mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]);
- }
/* mark fibers */
mrb_gc_mark(mrb, (struct RBasic*)c->fib);
if (c->prev) {
@@ -765,6 +770,7 @@ mrb_gc_mark(mrb_state *mrb, struct RBasic *obj)
{
if (obj == 0) return;
if (!is_white(obj)) return;
+ if (is_red(obj)) return;
mrb_assert((obj)->tt != MRB_TT_FREE);
add_gray_list(mrb, &mrb->gc, obj);
}
@@ -776,12 +782,12 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end)
switch (obj->tt) {
/* immediate - no mark */
case MRB_TT_TRUE:
- case MRB_TT_FIXNUM:
+ case MRB_TT_INTEGER:
case MRB_TT_SYMBOL:
/* cannot happen */
return;
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
case MRB_TT_FLOAT:
#ifdef MRB_WORD_BOXING
break;
@@ -803,12 +809,14 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end)
case MRB_TT_SCLASS:
mrb_gc_free_mt(mrb, (struct RClass*)obj);
mrb_gc_free_iv(mrb, (struct RObject*)obj);
- mrb_mc_clear_by_class(mrb, (struct RClass*)obj);
+ if (!end)
+ mrb_mc_clear_by_class(mrb, (struct RClass*)obj);
break;
case MRB_TT_ICLASS:
if (MRB_FLAG_TEST(obj, MRB_FL_CLASS_IS_ORIGIN))
mrb_gc_free_mt(mrb, (struct RClass*)obj);
- mrb_mc_clear_by_class(mrb, (struct RClass*)obj);
+ if (!end)
+ mrb_mc_clear_by_class(mrb, (struct RClass*)obj);
break;
case MRB_TT_ENV:
{
@@ -868,7 +876,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end)
struct RProc *p = (struct RProc*)obj;
if (!MRB_PROC_CFUNC_P(p) && p->body.irep) {
- mrb_irep *irep = p->body.irep;
+ mrb_irep *irep = (mrb_irep*)p->body.irep;
if (end) {
mrb_irep_cutref(mrb, irep);
}
@@ -924,10 +932,10 @@ root_scan_phase(mrb_state *mrb, mrb_gc *gc)
mrb_gc_mark(mrb, (struct RBasic*)mrb->hash_class);
mrb_gc_mark(mrb, (struct RBasic*)mrb->range_class);
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
mrb_gc_mark(mrb, (struct RBasic*)mrb->float_class);
#endif
- mrb_gc_mark(mrb, (struct RBasic*)mrb->fixnum_class);
+ mrb_gc_mark(mrb, (struct RBasic*)mrb->integer_class);
mrb_gc_mark(mrb, (struct RBasic*)mrb->true_class);
mrb_gc_mark(mrb, (struct RBasic*)mrb->false_class);
mrb_gc_mark(mrb, (struct RBasic*)mrb->nil_class);
@@ -1004,9 +1012,6 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
if (c->stbase + i > c->stend) i = c->stend - c->stbase;
children += i;
- /* mark ensure stack */
- children += c->eidx;
-
/* mark closure */
if (c->cibase) {
for (i=0, ci = c->cibase; ci <= c->ci; i++, ci++)
@@ -1317,6 +1322,9 @@ mrb_full_gc(mrb_state *mrb)
gc->full = FALSE;
}
+#ifdef MRB_USE_MALLOC_TRIM
+ malloc_trim(0);
+#endif
GC_TIME_STOP_AND_REPORT;
}