Skip to content

Commit 0f5e36a

Browse files
committed
Add void rb_gc_update_reference(VALUE *ptr) API
The existing `VALUE rb_gc_location(VALUE obj)` API isn't ideal in my opinion, because the idomatic way to use it is: ```c struct->field = rb_gc_location(struct->field); ``` Which means that when running `GC.compact`, any reference that is movable is rewritten, even if the referenced object didn't move. I suspect this is a lot of unnecessary writes that are trashing shared pages. Inside the GC itself, there's the much more convenient `UPDATE_IF_MOVED` macro, that only update the reference if it's actually needed.
1 parent 547f111 commit 0f5e36a

3 files changed

Lines changed: 11 additions & 1 deletion

File tree

gc.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2878,6 +2878,15 @@ rb_gc_location(VALUE value)
28782878
return gc_location_internal(rb_gc_get_objspace(), value);
28792879
}
28802880

2881+
void
2882+
rb_gc_update_reference(VALUE *value_ptr)
2883+
{
2884+
void *objspace = rb_gc_get_objspace();
2885+
if (rb_gc_impl_object_moved_p(objspace, *value_ptr)) {
2886+
*value_ptr = gc_location_internal(objspace, *value_ptr);
2887+
}
2888+
}
2889+
28812890
#if defined(__wasm__)
28822891

28832892

internal/gc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ bool rb_gc_size_allocatable_p(size_t size);
210210
size_t *rb_gc_heap_sizes(void);
211211
size_t rb_gc_heap_id_for_size(size_t size);
212212

213+
void rb_gc_update_reference(VALUE *ptr);
213214
void rb_gc_mark_and_move(VALUE *ptr);
214215

215216
void rb_gc_mark_weak(VALUE *ptr);

vm_backtrace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ static void
138138
location_ref_update(void *ptr)
139139
{
140140
struct valued_frame_info *vfi = ptr;
141-
vfi->btobj = rb_gc_location(vfi->btobj);
141+
rb_gc_update_reference(&vfi->btobj);
142142
}
143143

144144
static void

0 commit comments

Comments
 (0)