summaryrefslogtreecommitdiff
path: root/array.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2025-09-25 05:50:05 +0900
committerKoichi Sasada <ko1@atdot.net>2025-10-23 13:08:26 +0900
commitbc00c4468e0054ca896d2b83d3020180915f64cf (patch)
tree3942c12dbba8254925400f16c022661dcbb7ffb0 /array.c
parent45907b1b00d09ce2c40f5073ff540d8b63217d96 (diff)
use `SET_SHAREABLE`
to adopt strict shareable rule. * (basically) shareable objects only refer shareable objects * (exception) shareable objects can refere unshareable objects but should not leak reference to unshareable objects to Ruby world
Diffstat (limited to 'array.c')
-rw-r--r--array.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/array.c b/array.c
index 378da150ee..12f45e2cbb 100644
--- a/array.c
+++ b/array.c
@@ -29,6 +29,7 @@
#include "ruby/st.h"
#include "ruby/thread.h"
#include "ruby/util.h"
+#include "ruby/ractor.h"
#include "vm_core.h"
#include "builtin.h"
@@ -107,10 +108,12 @@ should_be_T_ARRAY(VALUE ary)
} while (0)
#define FL_UNSET_SHARED(ary) FL_UNSET((ary), RARRAY_SHARED_FLAG)
+#define ARY_SET_PTR_FORCE(ary, p) \
+ RARRAY(ary)->as.heap.ptr = (p);
#define ARY_SET_PTR(ary, p) do { \
RUBY_ASSERT(!ARY_EMBED_P(ary)); \
RUBY_ASSERT(!OBJ_FROZEN(ary)); \
- RARRAY(ary)->as.heap.ptr = (p); \
+ ARY_SET_PTR_FORCE(ary, p); \
} while (0)
#define ARY_SET_EMBED_LEN(ary, n) do { \
long tmp_n = (n); \
@@ -148,11 +151,13 @@ should_be_T_ARRAY(VALUE ary)
#define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? ary_embed_capa(ary) : \
ARY_SHARED_ROOT_P(ary) ? RARRAY_LEN(ary) : ARY_HEAP_CAPA(ary))
+#define ARY_SET_CAPA_FORCE(ary, n) \
+ RARRAY(ary)->as.heap.aux.capa = (n);
#define ARY_SET_CAPA(ary, n) do { \
RUBY_ASSERT(!ARY_EMBED_P(ary)); \
RUBY_ASSERT(!ARY_SHARED_P(ary)); \
RUBY_ASSERT(!OBJ_FROZEN(ary)); \
- RARRAY(ary)->as.heap.aux.capa = (n); \
+ ARY_SET_CAPA_FORCE(ary, n); \
} while (0)
#define ARY_SHARED_ROOT_OCCUPIED(ary) (!OBJ_FROZEN(ary) && ARY_SHARED_ROOT_REFCNT(ary) == 1)
@@ -560,8 +565,8 @@ rb_ary_cancel_sharing(VALUE ary)
VALUE *ptr = ary_heap_alloc_buffer(len);
MEMCPY(ptr, ARY_HEAP_PTR(ary), VALUE, len);
rb_ary_unshare(ary);
- ARY_SET_CAPA(ary, len);
- ARY_SET_PTR(ary, ptr);
+ ARY_SET_CAPA_FORCE(ary, len);
+ ARY_SET_PTR_FORCE(ary, ptr);
}
rb_gc_writebarrier_remember(ary);
@@ -4729,6 +4734,8 @@ rb_ary_replace(VALUE copy, VALUE orig)
ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
ARY_SET_LEN(copy, ARY_HEAP_LEN(orig));
rb_ary_set_shared(copy, shared_root);
+
+ RUBY_ASSERT(RB_OBJ_SHAREABLE_P(copy) ? RB_OBJ_SHAREABLE_P(shared_root) : 1);
}
ary_verify(copy);
return copy;
@@ -8883,7 +8890,7 @@ Init_Array(void)
rb_define_method(rb_cArray, "deconstruct", rb_ary_deconstruct, 0);
- rb_cArray_empty_frozen = rb_ary_freeze(rb_ary_new());
+ rb_cArray_empty_frozen = RB_OBJ_SET_SHAREABLE(rb_ary_freeze(rb_ary_new()));
rb_vm_register_global_object(rb_cArray_empty_frozen);
}