Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 31 additions & 12 deletions gc/default/default.c
Original file line number Diff line number Diff line change
Expand Up @@ -4393,6 +4393,7 @@ static void
gc_mark(rb_objspace_t *objspace, VALUE obj)
{
GC_ASSERT(during_gc);
GC_ASSERT(!objspace->flags.during_reference_updating);

rgengc_check_relation(objspace, obj);
if (!gc_mark_set(objspace, obj)) return; /* already marked */
Expand Down Expand Up @@ -4543,6 +4544,28 @@ pin_value(st_data_t key, st_data_t value, st_data_t data)
return ST_CONTINUE;
}

static inline void
gc_mark_set_parent_raw(rb_objspace_t *objspace, VALUE obj, bool old_p)
{
asan_unpoison_memory_region(&objspace->rgengc.parent_object, sizeof(objspace->rgengc.parent_object), false);
asan_unpoison_memory_region(&objspace->rgengc.parent_object_old_p, sizeof(objspace->rgengc.parent_object_old_p), false);
objspace->rgengc.parent_object = obj;
objspace->rgengc.parent_object_old_p = old_p;
}

static inline void
gc_mark_set_parent(rb_objspace_t *objspace, VALUE obj)
{
gc_mark_set_parent_raw(objspace, obj, RVALUE_OLD_P(objspace, obj));
}

static inline void
gc_mark_set_parent_invalid(rb_objspace_t *objspace)
{
asan_poison_memory_region(&objspace->rgengc.parent_object, sizeof(objspace->rgengc.parent_object));
asan_poison_memory_region(&objspace->rgengc.parent_object_old_p, sizeof(objspace->rgengc.parent_object_old_p));
}

static void
mark_roots(rb_objspace_t *objspace, const char **categoryp)
{
Expand All @@ -4551,8 +4574,7 @@ mark_roots(rb_objspace_t *objspace, const char **categoryp)
} while (0)

MARK_CHECKPOINT("objspace");
objspace->rgengc.parent_object = Qundef;
objspace->rgengc.parent_object_old_p = false;
gc_mark_set_parent_raw(objspace, Qundef, false);

if (finalizer_table != NULL) {
st_foreach(finalizer_table, pin_value, (st_data_t)objspace);
Expand All @@ -4562,20 +4584,15 @@ mark_roots(rb_objspace_t *objspace, const char **categoryp)

rb_gc_save_machine_context();
rb_gc_mark_roots(objspace, categoryp);
}

static inline void
gc_mark_set_parent(rb_objspace_t *objspace, VALUE obj)
{
objspace->rgengc.parent_object = obj;
objspace->rgengc.parent_object_old_p = RVALUE_OLD_P(objspace, obj);
gc_mark_set_parent_invalid(objspace);
}

static void
gc_mark_children(rb_objspace_t *objspace, VALUE obj)
{
gc_mark_set_parent(objspace, obj);
rb_gc_mark_children(objspace, obj);
gc_mark_set_parent_invalid(objspace);
}

/**
Expand Down Expand Up @@ -5985,9 +6002,11 @@ gc_mark_from(rb_objspace_t *objspace, VALUE obj, VALUE parent)
{
gc_mark_set_parent(objspace, parent);
rgengc_check_relation(objspace, obj);
if (gc_mark_set(objspace, obj) == FALSE) return;
gc_aging(objspace, obj);
gc_grey(objspace, obj);
if (gc_mark_set(objspace, obj) != FALSE) {
gc_aging(objspace, obj);
gc_grey(objspace, obj);
}
gc_mark_set_parent_invalid(objspace);
}

NOINLINE(static void gc_writebarrier_incremental(VALUE a, VALUE b, rb_objspace_t *objspace));
Expand Down
22 changes: 18 additions & 4 deletions io_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ io_buffer_free(struct rb_io_buffer *buffer)
}

static void
rb_io_buffer_type_mark_and_move(void *_buffer)
rb_io_buffer_type_mark(void *_buffer)
{
struct rb_io_buffer *buffer = _buffer;
if (buffer->source != Qnil) {
Expand All @@ -282,7 +282,21 @@ rb_io_buffer_type_mark_and_move(void *_buffer)
// which can be otherwise moved by GC compaction.
rb_gc_mark(buffer->source);
} else {
rb_gc_mark_and_move(&buffer->source);
rb_gc_mark_movable(buffer->source);
}
}
}

static void
rb_io_buffer_type_compact(void *_buffer)
{
struct rb_io_buffer *buffer = _buffer;
if (buffer->source != Qnil) {
if (RB_TYPE_P(buffer->source, T_STRING)) {
// The `source` String has to be pinned, because the `base` may point to the embedded String content,
// which can be otherwise moved by GC compaction.
} else {
buffer->source = rb_gc_location(buffer->source);
}
}
}
Expand Down Expand Up @@ -311,10 +325,10 @@ rb_io_buffer_type_size(const void *_buffer)
static const rb_data_type_t rb_io_buffer_type = {
.wrap_struct_name = "IO::Buffer",
.function = {
.dmark = rb_io_buffer_type_mark_and_move,
.dmark = rb_io_buffer_type_mark,
.dfree = rb_io_buffer_type_free,
.dsize = rb_io_buffer_type_size,
.dcompact = rb_io_buffer_type_mark_and_move,
.dcompact = rb_io_buffer_type_compact,
},
.data = NULL,
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE,
Expand Down
6 changes: 2 additions & 4 deletions vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3343,10 +3343,8 @@ ruby_vm_destruct(rb_vm_t *vm)
rb_objspace_free_objects(objspace);
rb_free_generic_fields_tbl_();
rb_free_default_rand_key();
if (th && vm->fork_gen == 0) {
/* If we have forked, main_thread may not be the initial thread */
ruby_mimfree(th);
}

ruby_mimfree(th);
}
rb_objspace_free(objspace);
}
Expand Down