Skip to content

Commit bc00c44

Browse files
committed
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
1 parent 45907b1 commit bc00c44

File tree

25 files changed

+347
-142
lines changed

25 files changed

+347
-142
lines changed

array.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "ruby/st.h"
3030
#include "ruby/thread.h"
3131
#include "ruby/util.h"
32+
#include "ruby/ractor.h"
3233
#include "vm_core.h"
3334
#include "builtin.h"
3435

@@ -107,10 +108,12 @@ should_be_T_ARRAY(VALUE ary)
107108
} while (0)
108109
#define FL_UNSET_SHARED(ary) FL_UNSET((ary), RARRAY_SHARED_FLAG)
109110

111+
#define ARY_SET_PTR_FORCE(ary, p) \
112+
RARRAY(ary)->as.heap.ptr = (p);
110113
#define ARY_SET_PTR(ary, p) do { \
111114
RUBY_ASSERT(!ARY_EMBED_P(ary)); \
112115
RUBY_ASSERT(!OBJ_FROZEN(ary)); \
113-
RARRAY(ary)->as.heap.ptr = (p); \
116+
ARY_SET_PTR_FORCE(ary, p); \
114117
} while (0)
115118
#define ARY_SET_EMBED_LEN(ary, n) do { \
116119
long tmp_n = (n); \
@@ -148,11 +151,13 @@ should_be_T_ARRAY(VALUE ary)
148151

149152
#define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? ary_embed_capa(ary) : \
150153
ARY_SHARED_ROOT_P(ary) ? RARRAY_LEN(ary) : ARY_HEAP_CAPA(ary))
154+
#define ARY_SET_CAPA_FORCE(ary, n) \
155+
RARRAY(ary)->as.heap.aux.capa = (n);
151156
#define ARY_SET_CAPA(ary, n) do { \
152157
RUBY_ASSERT(!ARY_EMBED_P(ary)); \
153158
RUBY_ASSERT(!ARY_SHARED_P(ary)); \
154159
RUBY_ASSERT(!OBJ_FROZEN(ary)); \
155-
RARRAY(ary)->as.heap.aux.capa = (n); \
160+
ARY_SET_CAPA_FORCE(ary, n); \
156161
} while (0)
157162

158163
#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)
560565
VALUE *ptr = ary_heap_alloc_buffer(len);
561566
MEMCPY(ptr, ARY_HEAP_PTR(ary), VALUE, len);
562567
rb_ary_unshare(ary);
563-
ARY_SET_CAPA(ary, len);
564-
ARY_SET_PTR(ary, ptr);
568+
ARY_SET_CAPA_FORCE(ary, len);
569+
ARY_SET_PTR_FORCE(ary, ptr);
565570
}
566571

567572
rb_gc_writebarrier_remember(ary);
@@ -4729,6 +4734,8 @@ rb_ary_replace(VALUE copy, VALUE orig)
47294734
ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
47304735
ARY_SET_LEN(copy, ARY_HEAP_LEN(orig));
47314736
rb_ary_set_shared(copy, shared_root);
4737+
4738+
RUBY_ASSERT(RB_OBJ_SHAREABLE_P(copy) ? RB_OBJ_SHAREABLE_P(shared_root) : 1);
47324739
}
47334740
ary_verify(copy);
47344741
return copy;
@@ -8883,7 +8890,7 @@ Init_Array(void)
88838890

88848891
rb_define_method(rb_cArray, "deconstruct", rb_ary_deconstruct, 0);
88858892

8886-
rb_cArray_empty_frozen = rb_ary_freeze(rb_ary_new());
8893+
rb_cArray_empty_frozen = RB_OBJ_SET_SHAREABLE(rb_ary_freeze(rb_ary_new()));
88878894
rb_vm_register_global_object(rb_cArray_empty_frozen);
88888895
}
88898896

class.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ class_alloc0(enum ruby_value_type type, VALUE klass, bool namespaceable)
775775

776776
RUBY_ASSERT(type == T_CLASS || type == T_ICLASS || type == T_MODULE);
777777

778-
VALUE flags = type;
778+
VALUE flags = type | FL_SHAREABLE;
779779
if (RGENGC_WB_PROTECTED_CLASS) flags |= FL_WB_PROTECTED;
780780
if (namespaceable) flags |= RCLASS_NAMESPACEABLE;
781781

compile.c

Lines changed: 74 additions & 25 deletions
Large diffs are not rendered by default.

depend

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ array.$(OBJEXT): {$(VPATH)}onigmo.h
263263
array.$(OBJEXT): {$(VPATH)}oniguruma.h
264264
array.$(OBJEXT): {$(VPATH)}probes.dmyh
265265
array.$(OBJEXT): {$(VPATH)}probes.h
266+
array.$(OBJEXT): {$(VPATH)}ractor.h
266267
array.$(OBJEXT): {$(VPATH)}ruby_assert.h
267268
array.$(OBJEXT): {$(VPATH)}ruby_atomic.h
268269
array.$(OBJEXT): {$(VPATH)}rubyparser.h
@@ -4385,6 +4386,7 @@ encoding.$(OBJEXT): {$(VPATH)}missing.h
43854386
encoding.$(OBJEXT): {$(VPATH)}node.h
43864387
encoding.$(OBJEXT): {$(VPATH)}onigmo.h
43874388
encoding.$(OBJEXT): {$(VPATH)}oniguruma.h
4389+
encoding.$(OBJEXT): {$(VPATH)}ractor.h
43884390
encoding.$(OBJEXT): {$(VPATH)}regenc.h
43894391
encoding.$(OBJEXT): {$(VPATH)}ruby_assert.h
43904392
encoding.$(OBJEXT): {$(VPATH)}ruby_atomic.h
@@ -16794,6 +16796,7 @@ string.$(OBJEXT): {$(VPATH)}onigmo.h
1679416796
string.$(OBJEXT): {$(VPATH)}oniguruma.h
1679516797
string.$(OBJEXT): {$(VPATH)}probes.dmyh
1679616798
string.$(OBJEXT): {$(VPATH)}probes.h
16799+
string.$(OBJEXT): {$(VPATH)}ractor.h
1679716800
string.$(OBJEXT): {$(VPATH)}re.h
1679816801
string.$(OBJEXT): {$(VPATH)}regex.h
1679916802
string.$(OBJEXT): {$(VPATH)}ruby_assert.h
@@ -17265,6 +17268,7 @@ symbol.$(OBJEXT): {$(VPATH)}onigmo.h
1726517268
symbol.$(OBJEXT): {$(VPATH)}oniguruma.h
1726617269
symbol.$(OBJEXT): {$(VPATH)}probes.dmyh
1726717270
symbol.$(OBJEXT): {$(VPATH)}probes.h
17271+
symbol.$(OBJEXT): {$(VPATH)}ractor.h
1726817272
symbol.$(OBJEXT): {$(VPATH)}ruby_assert.h
1726917273
symbol.$(OBJEXT): {$(VPATH)}ruby_atomic.h
1727017274
symbol.$(OBJEXT): {$(VPATH)}rubyparser.h

encoding.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "ruby/atomic.h"
2828
#include "ruby/encoding.h"
2929
#include "ruby/util.h"
30+
#include "ruby/ractor.h"
3031
#include "ruby_assert.h"
3132
#include "vm_sync.h"
3233
#include "ruby_atomic.h"
@@ -135,8 +136,7 @@ static VALUE
135136
enc_new(rb_encoding *encoding)
136137
{
137138
VALUE enc = TypedData_Wrap_Struct(rb_cEncoding, &encoding_data_type, (void *)encoding);
138-
rb_obj_freeze(enc);
139-
FL_SET_RAW(enc, RUBY_FL_SHAREABLE);
139+
RB_OBJ_SET_FROZEN_SHAREABLE(enc);
140140
return enc;
141141
}
142142

gc.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2804,13 +2804,17 @@ mark_m_tbl(void *objspace, struct rb_id_table *tbl)
28042804
}
28052805
}
28062806

2807+
bool rb_gc_impl_checking_shareable(void *objspace_ptr); // in defaut/deafult.c
2808+
28072809
static enum rb_id_table_iterator_result
28082810
mark_const_entry_i(VALUE value, void *objspace)
28092811
{
28102812
const rb_const_entry_t *ce = (const rb_const_entry_t *)value;
28112813

2812-
gc_mark_internal(ce->value);
2813-
gc_mark_internal(ce->file);
2814+
if (!rb_gc_impl_checking_shareable(objspace)) {
2815+
gc_mark_internal(ce->value);
2816+
gc_mark_internal(ce->file); // TODO: ce->file should be shareable?
2817+
}
28142818
return ID_TABLE_CONTINUE;
28152819
}
28162820

@@ -3071,7 +3075,12 @@ gc_mark_classext_module(rb_classext_t *ext, bool prime, VALUE namespace, void *a
30713075
gc_mark_internal(RCLASSEXT_SUPER(ext));
30723076
}
30733077
mark_m_tbl(objspace, RCLASSEXT_M_TBL(ext));
3074-
gc_mark_internal(RCLASSEXT_FIELDS_OBJ(ext));
3078+
3079+
if (!rb_gc_impl_checking_shareable(objspace)) {
3080+
// unshareable
3081+
gc_mark_internal(RCLASSEXT_FIELDS_OBJ(ext));
3082+
}
3083+
30753084
if (!RCLASSEXT_SHARED_CONST_TBL(ext) && RCLASSEXT_CONST_TBL(ext)) {
30763085
mark_const_tbl(objspace, RCLASSEXT_CONST_TBL(ext));
30773086
}
@@ -3137,7 +3146,8 @@ rb_gc_mark_children(void *objspace, VALUE obj)
31373146

31383147
switch (BUILTIN_TYPE(obj)) {
31393148
case T_CLASS:
3140-
if (FL_TEST_RAW(obj, FL_SINGLETON)) {
3149+
if (FL_TEST_RAW(obj, FL_SINGLETON) &&
3150+
!rb_gc_impl_checking_shareable(objspace)) {
31413151
gc_mark_internal(RCLASS_ATTACHED_OBJECT(obj));
31423152
}
31433153
// Continue to the shared T_CLASS/T_MODULE

gc/default/default.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5053,6 +5053,10 @@ verify_internal_consistency_i(void *page_start, void *page_end, size_t stride,
50535053
rb_objspace_reachable_objects_from(obj, check_generation_i, (void *)data);
50545054
}
50555055

5056+
if (!is_marking(objspace) && RB_OBJ_SHAREABLE_P(obj)) {
5057+
gc_verify_shareable(objspace, obj, data);
5058+
}
5059+
50565060
if (is_incremental_marking(objspace)) {
50575061
if (RVALUE_BLACK_P(objspace, obj)) {
50585062
/* reachable objects from black objects should be black or grey objects */
@@ -8975,6 +8979,12 @@ gc_profile_disable(VALUE _)
89758979
return Qnil;
89768980
}
89778981

8982+
void
8983+
rb_gc_verify_internal_consistency(void)
8984+
{
8985+
gc_verify_internal_consistency(rb_gc_get_objspace());
8986+
}
8987+
89788988
/*
89798989
* call-seq:
89808990
* GC.verify_internal_consistency -> nil
@@ -8988,7 +8998,7 @@ gc_profile_disable(VALUE _)
89888998
static VALUE
89898999
gc_verify_internal_consistency_m(VALUE dummy)
89909000
{
8991-
gc_verify_internal_consistency(rb_gc_get_objspace());
9001+
rb_gc_verify_internal_consistency();
89929002
return Qnil;
89939003
}
89949004

hash.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7474,6 +7474,7 @@ Init_Hash(void)
74747474
rb_define_singleton_method(rb_cHash, "ruby2_keywords_hash", rb_hash_s_ruby2_keywords_hash, 1);
74757475

74767476
rb_cHash_empty_frozen = rb_hash_freeze(rb_hash_new());
7477+
RB_OBJ_SET_SHAREABLE(rb_cHash_empty_frozen);
74777478
rb_vm_register_global_object(rb_cHash_empty_frozen);
74787479

74797480
/* Document-class: ENV
@@ -7643,8 +7644,7 @@ Init_Hash(void)
76437644
origenviron = environ;
76447645
envtbl = TypedData_Wrap_Struct(rb_cObject, &env_data_type, NULL);
76457646
rb_extend_object(envtbl, rb_mEnumerable);
7646-
FL_SET_RAW(envtbl, RUBY_FL_SHAREABLE);
7647-
7647+
RB_OBJ_SET_SHAREABLE(envtbl);
76487648

76497649
rb_define_singleton_method(envtbl, "[]", rb_f_getenv, 1);
76507650
rb_define_singleton_method(envtbl, "fetch", env_fetch, -1);

id_table.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ rb_managed_id_table_create(const rb_data_type_t *type, size_t capa)
373373
{
374374
struct rb_id_table *tbl;
375375
VALUE obj = TypedData_Make_Struct(0, struct rb_id_table, type, tbl);
376+
RB_OBJ_SET_SHAREABLE(obj);
376377
rb_id_table_init(tbl, capa);
377378
return obj;
378379
}

0 commit comments

Comments
 (0)