summaryrefslogtreecommitdiff
path: root/internal
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 /internal
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 'internal')
-rw-r--r--internal/class.h4
-rw-r--r--internal/gc.h1
-rw-r--r--internal/imemo.h11
3 files changed, 10 insertions, 6 deletions
diff --git a/internal/class.h b/internal/class.h
index a791672cad..5d843e58da 100644
--- a/internal/class.h
+++ b/internal/class.h
@@ -555,7 +555,7 @@ RCLASS_WRITABLE_ENSURE_FIELDS_OBJ(VALUE obj)
RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
rb_classext_t *ext = RCLASS_EXT_WRITABLE(obj);
if (!ext->fields_obj) {
- RB_OBJ_WRITE(obj, &ext->fields_obj, rb_imemo_fields_new(obj, 1));
+ RB_OBJ_WRITE(obj, &ext->fields_obj, rb_imemo_fields_new(obj, 1, true));
}
return ext->fields_obj;
}
@@ -762,6 +762,7 @@ RCLASS_SET_CLASSPATH(VALUE klass, VALUE classpath, bool permanent)
rb_classext_t *ext = RCLASS_EXT_READABLE(klass);
assert(BUILTIN_TYPE(klass) == T_CLASS || BUILTIN_TYPE(klass) == T_MODULE);
assert(classpath == 0 || BUILTIN_TYPE(classpath) == T_STRING);
+ assert(FL_TEST_RAW(classpath, RUBY_FL_SHAREABLE));
RB_OBJ_WRITE(klass, &(RCLASSEXT_CLASSPATH(ext)), classpath);
RCLASSEXT_PERMANENT_CLASSPATH(ext) = permanent;
@@ -773,6 +774,7 @@ RCLASS_WRITE_CLASSPATH(VALUE klass, VALUE classpath, bool permanent)
rb_classext_t *ext = RCLASS_EXT_WRITABLE(klass);
assert(BUILTIN_TYPE(klass) == T_CLASS || BUILTIN_TYPE(klass) == T_MODULE);
assert(classpath == 0 || BUILTIN_TYPE(classpath) == T_STRING);
+ assert(!RB_FL_ABLE(classpath) || FL_TEST_RAW(classpath, RUBY_FL_SHAREABLE));
RB_OBJ_WRITE(klass, &(RCLASSEXT_CLASSPATH(ext)), classpath);
RCLASSEXT_PERMANENT_CLASSPATH(ext) = permanent;
diff --git a/internal/gc.h b/internal/gc.h
index 7357bef732..ec408d7fac 100644
--- a/internal/gc.h
+++ b/internal/gc.h
@@ -353,5 +353,6 @@ ruby_sized_realloc_n(void *ptr, size_t new_count, size_t element_size, size_t ol
#define ruby_sized_xfree ruby_sized_xfree_inlined
void rb_gc_verify_shareable(VALUE);
+bool rb_gc_checking_shareable(void);
#endif /* INTERNAL_GC_H */
diff --git a/internal/imemo.h b/internal/imemo.h
index 3b91ef4b81..f8bda26f0b 100644
--- a/internal/imemo.h
+++ b/internal/imemo.h
@@ -114,7 +114,8 @@ struct MEMO {
} u3;
};
-#define IMEMO_NEW(T, type, v0) ((T *)rb_imemo_new((type), (v0), sizeof(T)))
+#define IMEMO_NEW(T, type, v0) ((T *)rb_imemo_new((type), (v0), sizeof(T), false))
+#define SHAREABLE_IMEMO_NEW(T, type, v0) ((T *)rb_imemo_new((type), (v0), sizeof(T), true))
/* ment is in method.h */
@@ -131,7 +132,7 @@ struct MEMO {
#ifndef RUBY_RUBYPARSER_H
typedef struct rb_imemo_tmpbuf_struct rb_imemo_tmpbuf_t;
#endif
-VALUE rb_imemo_new(enum imemo_type type, VALUE v0, size_t size);
+VALUE rb_imemo_new(enum imemo_type type, VALUE v0, size_t size, bool is_shareable);
VALUE rb_imemo_tmpbuf_new(void);
struct vm_ifunc *rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc);
static inline enum imemo_type imemo_type(VALUE imemo);
@@ -270,9 +271,9 @@ STATIC_ASSERT(imemo_fields_embed_offset, offsetof(struct RObject, as.heap.fields
#define IMEMO_OBJ_FIELDS(fields) ((struct rb_fields *)fields)
-VALUE rb_imemo_fields_new(VALUE owner, size_t capa);
-VALUE rb_imemo_fields_new_complex(VALUE owner, size_t capa);
-VALUE rb_imemo_fields_new_complex_tbl(VALUE owner, st_table *tbl);
+VALUE rb_imemo_fields_new(VALUE owner, size_t capa, bool shareable);
+VALUE rb_imemo_fields_new_complex(VALUE owner, size_t capa, bool shareable);
+VALUE rb_imemo_fields_new_complex_tbl(VALUE owner, st_table *tbl, bool shareable);
VALUE rb_imemo_fields_clone(VALUE fields_obj);
void rb_imemo_fields_clear(VALUE fields_obj);