void test_gc_gray_mark(void) { mrb_state *mrb = mrb_open(); mrb_value obj_v, value_v; struct RBasic *obj; size_t gray_num = 0; puts("test_gc_gray_mark"); puts(" in MRB_TT_CLASS"); obj = (struct RBasic*)mrb->object_class; paint_gray(obj); gray_num = gc_gray_mark(mrb, obj); mrb_assert(is_black(obj)); mrb_assert(gray_num > 1); puts(" in MRB_TT_ARRAY"); obj_v = mrb_ary_new(mrb); value_v = mrb_str_new_lit(mrb, "test"); paint_gray(mrb_basic_ptr(obj_v)); paint_partial_white(mrb, mrb_basic_ptr(value_v)); mrb_ary_push(mrb, obj_v, value_v); gray_num = gc_gray_mark(mrb, mrb_basic_ptr(obj_v)); mrb_assert(is_black(mrb_basic_ptr(obj_v))); mrb_assert(is_gray(mrb_basic_ptr(value_v))); mrb_assert(gray_num == 1); mrb_close(mrb); }
void test_mrb_write_barrier(void) { mrb_state *mrb = mrb_open(); struct RBasic *obj; puts("test_mrb_write_barrier"); obj = mrb_basic_ptr(mrb_ary_new(mrb)); paint_black(obj); puts(" in GC_STATE_MARK"); mrb->gc_state = GC_STATE_MARK; mrb_write_barrier(mrb, obj); mrb_assert(is_gray(obj)); mrb_assert(mrb->atomic_gray_list == obj); puts(" fail with gray"); paint_gray(obj); mrb_write_barrier(mrb, obj); mrb_assert(is_gray(obj)); mrb_close(mrb); }
static inline void add_gray_list(mrb_state *mrb, struct RBasic *obj) { paint_gray(obj); obj->gcnext = mrb->gray_list; mrb->gray_list = obj; }
void mrb_write_barrier(mrb_state *mrb, struct RBasic *obj) { if (!is_black(obj)) return; mrb_assert(!is_dead(mrb, obj)); mrb_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_NONE); paint_gray(obj); obj->gcnext = mrb->atomic_gray_list; mrb->atomic_gray_list = obj; }
void mrb_write_barrier(mrb_state *mrb, struct RBasic *obj) { if (!is_black(obj)) return; gc_assert(!is_dead(mrb, obj)); gc_assert(mrb->gc_state != GC_STATE_NONE); paint_gray(obj); obj->gcnext = mrb->variable_gray_list; mrb->variable_gray_list = obj; }
static inline void add_gray_list(mrb_state *mrb, struct RBasic *obj) { #ifdef MRB_GC_STRESS if (obj->tt > MRB_TT_MAXDEFINE) { abort(); } #endif paint_gray(obj); obj->gcnext = mrb->gray_list; mrb->gray_list = obj; }
MRB_API void mrb_write_barrier(mrb_state *mrb, struct RBasic *obj) { mrb_gc *gc = &mrb->gc; if (!is_black(obj)) return; mrb_assert(!is_dead(gc, obj)); mrb_assert(is_generational(gc) || gc->state != MRB_GC_STATE_ROOT); paint_gray(obj); obj->gcnext = gc->atomic_gray_list; gc->atomic_gray_list = obj; }
void test_mrb_field_write_barrier(void) { mrb_state *mrb = mrb_open(); struct RBasic *obj, *value; puts("test_mrb_field_write_barrier"); mrb->is_generational_gc_mode = FALSE; obj = mrb_basic_ptr(mrb_ary_new(mrb)); value = mrb_basic_ptr(mrb_str_new_lit(mrb, "value")); paint_black(obj); paint_partial_white(mrb,value); puts(" in GC_STATE_MARK"); mrb->gc_state = GC_STATE_MARK; mrb_field_write_barrier(mrb, obj, value); mrb_assert(is_gray(value)); puts(" in GC_STATE_SWEEP"); paint_partial_white(mrb,value); mrb->gc_state = GC_STATE_SWEEP; mrb_field_write_barrier(mrb, obj, value); mrb_assert(obj->color & mrb->current_white_part); mrb_assert(value->color & mrb->current_white_part); puts(" fail with black"); mrb->gc_state = GC_STATE_MARK; paint_white(obj); paint_partial_white(mrb,value); mrb_field_write_barrier(mrb, obj, value); mrb_assert(obj->color & mrb->current_white_part); puts(" fail with gray"); mrb->gc_state = GC_STATE_MARK; paint_black(obj); paint_gray(value); mrb_field_write_barrier(mrb, obj, value); mrb_assert(is_gray(value)); { puts("test_mrb_field_write_barrier_value"); obj = mrb_basic_ptr(mrb_ary_new(mrb)); mrb_value value = mrb_str_new_lit(mrb, "value"); paint_black(obj); paint_partial_white(mrb, mrb_basic_ptr(value)); mrb->gc_state = GC_STATE_MARK; mrb_field_write_barrier_value(mrb, obj, value); mrb_assert(is_gray(mrb_basic_ptr(value))); } mrb_close(mrb); }