diff options
| author | Koichi Sasada <ko1@atdot.net> | 2025-09-25 05:50:05 +0900 |
|---|---|---|
| committer | Koichi Sasada <ko1@atdot.net> | 2025-10-23 13:08:26 +0900 |
| commit | bc00c4468e0054ca896d2b83d3020180915f64cf (patch) | |
| tree | 3942c12dbba8254925400f16c022661dcbb7ffb0 /internal | |
| parent | 45907b1b00d09ce2c40f5073ff540d8b63217d96 (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.h | 4 | ||||
| -rw-r--r-- | internal/gc.h | 1 | ||||
| -rw-r--r-- | internal/imemo.h | 11 |
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); |
