mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Revert any references that are on the machine stack after compacting
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.
This commit is contained in:
parent
7c716b686c
commit
e4e416380d
Notes:
git
2021-05-19 06:53:40 +09:00
1 changed files with 39 additions and 17 deletions
56
gc.c
56
gc.c
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue