@@ -63,20 +63,6 @@ typedef khint_t kset_iter_t;
6363#define kset_is_uninitialized(s) ((s)->data == NULL)
6464#define kset_is_empty(s) (kset_is_uninitialized(s) || kset_size(s) == 0)
656566-/* Copy all elements from src to dst (merge operation) */
67-static void
68-kset_copy_merge(mrb_state *mrb, kset_t *dst, kset_t *src)
69-{
70-if (!kset_is_empty(src)) {
71-int ai = mrb_gc_arena_save(mrb);
72-KSET_FOREACH(src, k) {
73-kset_put(mrb, dst, kset_key(src, k));
74-mrb_gc_arena_restore(mrb, ai);
75- }
76- }
77-}
78-79-8066/* Embedded set structure in RSet - exactly 3 pointers */
8167struct RSet {
8268MRB_OBJECT_HEADER;
@@ -95,6 +81,25 @@ set_get_kset(mrb_state *mrb, mrb_value self)
9581return &mrb_set_ptr(self)->set;
9682}
978384+/* Get RSet pointer from embedded kset_t pointer */
85+#define kset_to_rset(kset) ((struct RBasic*)((char*)(kset) - offsetof(struct RSet, set)))
86+87+/* Copy all elements from src to dst (merge operation) */
88+static void
89+kset_copy_merge(mrb_state *mrb, kset_t *dst, kset_t *src)
90+{
91+if (!kset_is_empty(src)) {
92+struct RBasic *dst_obj = kset_to_rset(dst);
93+int ai = mrb_gc_arena_save(mrb);
94+KSET_FOREACH(src, k) {
95+mrb_value key = kset_key(src, k);
96+kset_put(mrb, dst, key);
97+mrb_field_write_barrier_value(mrb, dst_obj, key);
98+mrb_gc_arena_restore(mrb, ai);
99+ }
100+ }
101+}
102+98103/* Helper function to ensure set is initialized */
99104static void
100105set_ensure_initialized(mrb_state *mrb, kset_t *set)
@@ -298,6 +303,7 @@ set_add(mrb_state *mrb, mrb_value self)
298303set_ensure_initialized(mrb, set);
299304300305kset_put(mrb, set, obj);
306+mrb_field_write_barrier_value(mrb, kset_to_rset(set), obj);
301307return self;
302308}
303309@@ -317,6 +323,7 @@ set_add_p(mrb_state *mrb, mrb_value self)
317323318324int ret;
319325kset_put2(mrb, set, obj, &ret);
326+mrb_field_write_barrier_value(mrb, kset_to_rset(set), obj);
320327return (ret == 0) ? mrb_nil_value() : self;
321328}
322329@@ -516,6 +523,7 @@ set_core_intersection(mrb_state *mrb, mrb_value self)
516523/* If key exists in self, add it to result */
517524if (!kset_is_end(self_set, self_k)) {
518525kset_put(mrb, result_set, key);
526+mrb_field_write_barrier_value(mrb, kset_to_rset(result_set), key);
519527 }
520528 }
521529@@ -564,6 +572,7 @@ set_core_xor(mrb_state *mrb, mrb_value self)
564572/* Add to result if not in other */
565573if (kset_is_end(other_set, other_k)) {
566574kset_put(mrb, result_set, key);
575+mrb_field_write_barrier_value(mrb, kset_to_rset(result_set), key);
567576 }
568577mrb_gc_arena_restore(mrb, ai);
569578 }
@@ -576,6 +585,7 @@ set_core_xor(mrb_state *mrb, mrb_value self)
576585/* Add to result if not in self */
577586if (kset_is_end(self_set, self_k)) {
578587kset_put(mrb, result_set, key);
588+mrb_field_write_barrier_value(mrb, kset_to_rset(result_set), key);
579589 }
580590mrb_gc_arena_restore(mrb, ai);
581591 }
@@ -1148,6 +1158,7 @@ set_add_all(mrb_state *mrb, mrb_value self)
11481158int ai = mrb_gc_arena_save(mrb);
11491159for (mrb_int i = 0; i < argc; i++) {
11501160kset_put(mrb, set, argv[i]);
1161+mrb_field_write_barrier_value(mrb, kset_to_rset(set), argv[i]);
11511162mrb_gc_arena_restore(mrb, ai);
11521163 }
11531164@@ -1178,6 +1189,7 @@ set_flatten_recursive(mrb_state *mrb, kset_t *target, kset_t *source, int *seen_
11781189if (!source || !target) return 0;
11791190if (*seen_count >= MAX_NESTED_DEPTH) return -1;
118011911192+struct RBasic *target_obj = kset_to_rset(target);
11811193int ai = mrb_gc_arena_save(mrb);
11821194/* Process each element in the source set */
11831195KSET_FOREACH(source, k) {
@@ -1203,6 +1215,7 @@ set_flatten_recursive(mrb_state *mrb, kset_t *target, kset_t *source, int *seen_
12031215else {
12041216/* Add non-Set element directly */
12051217kset_put(mrb, target, elem);
1218+mrb_field_write_barrier_value(mrb, target_obj, elem);
12061219 }
12071220mrb_gc_arena_restore(mrb, ai);
12081221 }
@@ -1409,6 +1422,7 @@ set_s_create(mrb_state *mrb, mrb_value klass)
1409142214101423for (mrb_int i = 0; i < argc; i++) {
14111424kset_put(mrb, ks, argv[i]);
1425+mrb_field_write_barrier_value(mrb, kset_to_rset(ks), argv[i]);
14121426 }
1413142714141428return set;