summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Valentine-House <matt@eightbitraptor.com>2023-08-31 15:35:56 +0100
committerMatt Valentine-House <matt@eightbitraptor.com>2023-08-31 19:31:18 +0100
commit322548180d01ce99dcb8ecb3c36f2a9261554657 (patch)
treed8d5df55533cce301eecffd60a2a6f070a52bad4
parent84fa8ae84eeb20a35ff2040dbf107c6d9babfdec (diff)
Prevent rb_gc_mark_values from pinning objects
This is an internal only function not exposed to the C extension API. It's only use so far is from rb_vm_mark, where it's used to mark the values in the vm->trap_list.cmd array. There shouldn't be any reason why these cannot move. This commit allows them to move by updating their references during the reference updating step of compaction. To do this we've introduced another internal function rb_gc_update_values as a partner to rb_gc_mark_values. This allows us to refactor rb_gc_mark_values to not pin
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/8341
-rw-r--r--gc.c8
-rw-r--r--internal/gc.h1
-rw-r--r--vm.c2
3 files changed, 10 insertions, 1 deletions
diff --git a/gc.c b/gc.c
index 59c507369e..d780bb0613 100644
--- a/gc.c
+++ b/gc.c
@@ -6348,7 +6348,7 @@ rb_gc_mark_values(long n, const VALUE *values)
rb_objspace_t *objspace = &rb_objspace;
for (i=0; i<n; i++) {
- gc_mark_and_pin(objspace, values[i]);
+ gc_mark(objspace, values[i]);
}
}
@@ -10135,6 +10135,12 @@ gc_update_values(rb_objspace_t *objspace, long n, VALUE *values)
}
}
+void
+rb_gc_update_values(long n, VALUE *values)
+{
+ gc_update_values(&rb_objspace, n, values);
+}
+
static bool
moved_or_living_object_strictly_p(rb_objspace_t *objspace, VALUE obj)
{
diff --git a/internal/gc.h b/internal/gc.h
index 7e0942a76a..be40a7a2f7 100644
--- a/internal/gc.h
+++ b/internal/gc.h
@@ -274,6 +274,7 @@ void rb_gc_verify_internal_consistency(void);
size_t rb_obj_gc_flags(VALUE, ID[], size_t);
void rb_gc_mark_values(long n, const VALUE *values);
void rb_gc_mark_vm_stack_values(long n, const VALUE *values);
+void rb_gc_update_values(long n, VALUE *values);
void *ruby_sized_xrealloc(void *ptr, size_t new_size, size_t old_size) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2));
void *ruby_sized_xrealloc2(void *ptr, size_t new_count, size_t element_size, size_t old_count) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2, 3));
void ruby_sized_xfree(void *x, size_t size);
diff --git a/vm.c b/vm.c
index 56442231cb..4b2b1ad344 100644
--- a/vm.c
+++ b/vm.c
@@ -2743,6 +2743,8 @@ rb_vm_update_references(void *ptr)
rb_gc_update_tbl_refs(vm->overloaded_cme_table);
+ rb_gc_update_values(RUBY_NSIG, vm->trap_list.cmd);
+
if (vm->coverages) {
vm->coverages = rb_gc_location(vm->coverages);
vm->me2counter = rb_gc_location(vm->me2counter);