Skip to content

Commit

Permalink
Revert any references that are on the machine stack after compacting
Browse files Browse the repository at this point in the history
Since compaction can be concurrent, the machine stack is allowed to
change while compaction is happening.  When compaction finishes, there
may be references on the machine stack that need to be reverted so that
we can remove the read barrier.
  • Loading branch information
tenderlove committed May 18, 2021
1 parent 7c716b6 commit e4e4163
Showing 1 changed file with 39 additions and 17 deletions.
56 changes: 39 additions & 17 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -5111,12 +5111,28 @@ revert_stack_objects(VALUE stack_obj, void *ctx)
}
}

static void
revert_machine_stack_references(rb_objspace_t *objspace, VALUE v)
{
if (is_pointer_to_heap(objspace, (void *)v)) {
if (BUILTIN_TYPE(v) == T_MOVED) {
/* For now we'll revert the whole page if the object made it to the
* stack. I think we can change this to move just the one object
* back though */
invalidate_moved_page(objspace, GET_HEAP_PAGE(v));
}
}
}

static void each_machine_stack_value(const rb_execution_context_t *ec, void (*cb)(rb_objspace_t *, VALUE));

static void
check_stack_for_moved(rb_objspace_t *objspace)
{
rb_execution_context_t *ec = GET_EC();
rb_vm_t *vm = rb_ec_vm_ptr(ec);
rb_vm_each_stack_value(vm, revert_stack_objects, (void*)objspace);
each_machine_stack_value(ec, revert_machine_stack_references);
}

static void
Expand Down Expand Up @@ -6001,32 +6017,32 @@ ruby_stack_check(void)
return stack_check(GET_EC(), STACKFRAME_FOR_CALL_CFUNC);
}

ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(static void mark_locations_array(rb_objspace_t *objspace, register const VALUE *x, register long n));
ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(static void each_location(rb_objspace_t *objspace, register const VALUE *x, register long n, void (*cb)(rb_objspace_t *, VALUE)));
static void
mark_locations_array(rb_objspace_t *objspace, register const VALUE *x, register long n)
each_location(rb_objspace_t *objspace, register const VALUE *x, register long n, void (*cb)(rb_objspace_t *, VALUE))
{
VALUE v;
while (n--) {
v = *x;
gc_mark_maybe(objspace, v);
cb(objspace, v);
x++;
}
}

static void
gc_mark_locations(rb_objspace_t *objspace, const VALUE *start, const VALUE *end)
gc_mark_locations(rb_objspace_t *objspace, const VALUE *start, const VALUE *end, void (*cb)(rb_objspace_t *, VALUE))
{
long n;

if (end <= start) return;
n = end - start;
mark_locations_array(objspace, start, n);
each_location(objspace, start, n, cb);
}

void
rb_gc_mark_locations(const VALUE *start, const VALUE *end)
{
gc_mark_locations(&rb_objspace, start, end);
gc_mark_locations(&rb_objspace, start, end, gc_mark_maybe);
}

static void
Expand Down Expand Up @@ -6284,8 +6300,8 @@ mark_const_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl)
((start) = STACK_END, (end) = STACK_START) : ((start) = STACK_START, (end) = STACK_END+(appendix)))
#endif

static void mark_stack_locations(rb_objspace_t *objspace, const rb_execution_context_t *ec,
const VALUE *stack_start, const VALUE *stack_end);
static void each_stack_location(rb_objspace_t *objspace, const rb_execution_context_t *ec,
const VALUE *stack_start, const VALUE *stack_end, void (*cb)(rb_objspace_t *, VALUE));

#ifndef __EMSCRIPTEN__
static void
Expand All @@ -6308,9 +6324,9 @@ mark_current_machine_context(rb_objspace_t *objspace, rb_execution_context_t *ec
SET_STACK_END;
GET_STACK_BOUNDS(stack_start, stack_end, 1);

mark_locations_array(objspace, save_regs_gc_mark.v, numberof(save_regs_gc_mark.v));
each_location(objspace, save_regs_gc_mark.v, numberof(save_regs_gc_mark.v), gc_mark_maybe);

mark_stack_locations(objspace, ec, stack_start, stack_end);
each_stack_location(objspace, ec, stack_start, stack_end, gc_mark_maybe);
}
#else

Expand All @@ -6334,27 +6350,33 @@ mark_current_machine_context(rb_objspace_t *objspace, rb_execution_context_t *ec
}
#endif

void
rb_gc_mark_machine_stack(const rb_execution_context_t *ec)
static void
each_machine_stack_value(const rb_execution_context_t *ec, void (*cb)(rb_objspace_t *, VALUE))
{
rb_objspace_t *objspace = &rb_objspace;
VALUE *stack_start, *stack_end;

GET_STACK_BOUNDS(stack_start, stack_end, 0);
mark_stack_locations(objspace, ec, stack_start, stack_end);
each_stack_location(objspace, ec, stack_start, stack_end, cb);
}

void
rb_gc_mark_machine_stack(const rb_execution_context_t *ec)
{
each_machine_stack_value(ec, gc_mark_maybe);
}

static void
mark_stack_locations(rb_objspace_t *objspace, const rb_execution_context_t *ec,
const VALUE *stack_start, const VALUE *stack_end)
each_stack_location(rb_objspace_t *objspace, const rb_execution_context_t *ec,
const VALUE *stack_start, const VALUE *stack_end, void (*cb)(rb_objspace_t *, VALUE))
{

gc_mark_locations(objspace, stack_start, stack_end);
gc_mark_locations(objspace, stack_start, stack_end, cb);

#if defined(__mc68000__)
gc_mark_locations(objspace,
(VALUE*)((char*)stack_start + 2),
(VALUE*)((char*)stack_end - 2));
(VALUE*)((char*)stack_end - 2), cb);
#endif
}

Expand Down

0 comments on commit e4e4163

Please sign in to comment.