Skip to content

Commit

Permalink
Prevent GC during each_object; fix #3616
Browse files Browse the repository at this point in the history
  • Loading branch information
matz committed Apr 25, 2017
1 parent 88cd807 commit aa8e490
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
1 change: 1 addition & 0 deletions include/mruby/gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ typedef struct mrb_gc {
size_t threshold;
int interval_ratio;
int step_ratio;
mrb_bool iterating :1;
mrb_bool disabled :1;
mrb_bool full :1;
mrb_bool generational :1;
Expand Down
32 changes: 29 additions & 3 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <mruby/variable.h>
#include <mruby/gc.h>
#include <mruby/error.h>
#include <mruby/throw.h>

/*
= Tri-color Incremental Garbage Collection
Expand Down Expand Up @@ -1162,7 +1163,7 @@ mrb_incremental_gc(mrb_state *mrb)
{
mrb_gc *gc = &mrb->gc;

if (gc->disabled) return;
if (gc->disabled || gc->iterating) return;

GC_INVOKE_TIME_REPORT("mrb_incremental_gc()");
GC_TIME_START;
Expand Down Expand Up @@ -1202,7 +1203,7 @@ mrb_full_gc(mrb_state *mrb)
{
mrb_gc *gc = &mrb->gc;

if (gc->disabled) return;
if (gc->disabled || gc->iterating) return;

GC_INVOKE_TIME_REPORT("mrb_full_gc()");
GC_TIME_START;
Expand Down Expand Up @@ -1508,7 +1509,32 @@ gc_each_objects(mrb_state *mrb, mrb_gc *gc, mrb_each_object_callback *callback,
void
mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, void *data)
{
gc_each_objects(mrb, &mrb->gc, callback, data);
mrb_bool iterating = mrb->gc.iterating;

mrb_full_gc(mrb);
mrb->gc.iterating = TRUE;
if (iterating) {
gc_each_objects(mrb, &mrb->gc, callback, data);
}
else {
struct mrb_jmpbuf *prev_jmp = mrb->jmp;
struct mrb_jmpbuf c_jmp;

MRB_TRY(&c_jmp) {
mrb->jmp = &c_jmp;
gc_each_objects(mrb, &mrb->gc, callback, data);
mrb->jmp = prev_jmp;
mrb->gc.iterating = iterating;
} MRB_CATCH(&c_jmp) {
mrb->jmp = prev_jmp;
mrb->gc.iterating = iterating;
if (mrb->exc) {
mrb_value exc = mrb_obj_value(mrb->exc);
mrb->exc = NULL;
mrb_exc_raise(mrb, exc);
}
} MRB_END_EXC(&c_jmp);
}
}

#ifdef GC_TEST
Expand Down

0 comments on commit aa8e490

Please sign in to comment.