summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gc.c56
1 files changed, 39 insertions, 17 deletions
diff --git a/gc.c b/gc.c
index e36282bd8d..1d34917dd5 100644
--- a/gc.c
+++ b/gc.c
@@ -5112,11 +5112,27 @@ 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
}