summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2025-08-07 14:42:14 +0200
committerJean Boussier <jean.boussier@gmail.com>2025-08-07 21:00:00 +0200
commitbc9781c264b9e37c2482dba429b560436104a1f5 (patch)
treecd4c9153befc532d8e41b2939beea632c7f997d7
parentaee8e65c702283af8a70cb1fdac0797aa7c75001 (diff)
Convert `name_err_mesg` to use `rb_gc_mark_and_move`
The `p->field = rb_gc_location(p->field)` isn't ideal because it means all references are rewritten on compaction, regardless of whether the referenced object has moved. This isn't good for caches nor for Copy-on-Write. `rb_gc_mark_and_move` avoid needless writes, and most of the time allow to have a single function for both marking and updating references.
-rw-r--r--error.c21
1 files changed, 6 insertions, 15 deletions
diff --git a/error.c b/error.c
index 9a758a7dd7..e07c99e6df 100644
--- a/error.c
+++ b/error.c
@@ -2517,30 +2517,21 @@ typedef struct name_error_message_struct {
} name_error_message_t;
static void
-name_err_mesg_mark(void *p)
+name_err_mesg_mark_and_move(void *p)
{
name_error_message_t *ptr = (name_error_message_t *)p;
- rb_gc_mark_movable(ptr->mesg);
- rb_gc_mark_movable(ptr->recv);
- rb_gc_mark_movable(ptr->name);
-}
-
-static void
-name_err_mesg_update(void *p)
-{
- name_error_message_t *ptr = (name_error_message_t *)p;
- ptr->mesg = rb_gc_location(ptr->mesg);
- ptr->recv = rb_gc_location(ptr->recv);
- ptr->name = rb_gc_location(ptr->name);
+ rb_gc_mark_and_move(&ptr->mesg);
+ rb_gc_mark_and_move(&ptr->recv);
+ rb_gc_mark_and_move(&ptr->name);
}
static const rb_data_type_t name_err_mesg_data_type = {
"name_err_mesg",
{
- name_err_mesg_mark,
+ name_err_mesg_mark_and_move,
RUBY_TYPED_DEFAULT_FREE,
NULL, // No external memory to report,
- name_err_mesg_update,
+ name_err_mesg_mark_and_move,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
};