diff --git a/.github/workflows/zjit-macos.yml b/.github/workflows/zjit-macos.yml index de0da85f1baa2f..666a673e5710ac 100644 --- a/.github/workflows/zjit-macos.yml +++ b/.github/workflows/zjit-macos.yml @@ -93,7 +93,7 @@ jobs: rustup install ${{ matrix.rust_version }} --profile minimal rustup default ${{ matrix.rust_version }} - - uses: taiki-e/install-action@db5fb34fa772531a3ece57ca434f579eb334e0fb # v2.75.30 + - uses: taiki-e/install-action@7ea35f098a7369cd23488403f58be9c491a6c55f # v2.77.0 with: tool: nextest@0.9 if: ${{ matrix.test_task == 'zjit-check' }} diff --git a/.github/workflows/zjit-ubuntu.yml b/.github/workflows/zjit-ubuntu.yml index c37d2fae22c693..a01c985f5560f3 100644 --- a/.github/workflows/zjit-ubuntu.yml +++ b/.github/workflows/zjit-ubuntu.yml @@ -119,7 +119,7 @@ jobs: ruby-version: '3.1' bundler: none - - uses: taiki-e/install-action@db5fb34fa772531a3ece57ca434f579eb334e0fb # v2.75.30 + - uses: taiki-e/install-action@7ea35f098a7369cd23488403f58be9c491a6c55f # v2.77.0 with: tool: nextest@0.9 if: ${{ matrix.test_task == 'zjit-check' }} diff --git a/gc.c b/gc.c index 706c395e8b2d6b..463145edda22e7 100644 --- a/gc.c +++ b/gc.c @@ -367,24 +367,12 @@ rb_gc_shutdown_call_finalizer_p(VALUE obj) } } -uint32_t -rb_gc_get_shape(VALUE obj) -{ - return (uint32_t)rb_obj_shape_id(obj); -} - void -rb_gc_set_shape(VALUE obj, uint32_t shape_id) -{ - RBASIC_SET_SHAPE_ID(obj, (uint32_t)shape_id); -} - -uint32_t -rb_gc_rebuild_shape(VALUE obj, size_t heap_id) +rb_gc_obj_changed_pool(VALUE obj, size_t heap_id) { RUBY_ASSERT(RB_TYPE_P(obj, T_OBJECT)); - return (uint32_t)rb_obj_shape_transition_heap(obj, heap_id); + RBASIC_SET_SHAPE_ID(obj, rb_obj_shape_transition_heap(obj, heap_id)); } void rb_vm_update_references(void *ptr); diff --git a/gc/default/default.c b/gc/default/default.c index d8dfdfa13dca0f..6465b5c70e6313 100644 --- a/gc/default/default.c +++ b/gc/default/default.c @@ -438,7 +438,6 @@ struct RMoved { VALUE flags; VALUE dummy; VALUE destination; - uint32_t original_shape_id; }; #define RMOVED(obj) ((struct RMoved *)(obj)) @@ -3213,7 +3212,7 @@ gc_setup_mark_bits(struct heap_page *page) } static int gc_is_moveable_obj(rb_objspace_t *objspace, VALUE obj); -static VALUE gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free, size_t src_slot_size, size_t slot_size); +static VALUE gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free, struct heap_page *src_page, struct heap_page *dest_page); #if defined(_WIN32) enum {HEAP_PAGE_LOCK = PAGE_NOACCESS, HEAP_PAGE_UNLOCK = PAGE_READWRITE}; @@ -3296,7 +3295,7 @@ try_move(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *free_page, objspace->rcompactor.moved_count_table[BUILTIN_TYPE(src)]++; objspace->rcompactor.total_moved++; - gc_move(objspace, src, dest, src_page->slot_size, free_page->slot_size); + gc_move(objspace, src, dest, src_page, free_page); gc_pin(objspace, src); free_page->free_slots--; @@ -4096,20 +4095,10 @@ invalidate_moved_plane(rb_objspace_t *objspace, struct heap_page *page, uintptr_ CLEAR_IN_BITMAP(GET_HEAP_PINNED_BITS(forwarding_object), forwarding_object); object = rb_gc_impl_location(objspace, forwarding_object); - - uint32_t original_shape_id = 0; - if (RB_TYPE_P(object, T_OBJECT)) { - original_shape_id = RMOVED(forwarding_object)->original_shape_id; - } - - gc_move(objspace, object, forwarding_object, GET_HEAP_PAGE(object)->slot_size, page->slot_size); + gc_move(objspace, object, forwarding_object, GET_HEAP_PAGE(object), page); /* forwarding_object is now our actual object, and "object" * is the free slot for the original page */ - if (original_shape_id) { - rb_gc_set_shape(forwarding_object, original_shape_id); - } - struct heap_page *orig_page = GET_HEAP_PAGE(object); orig_page->free_slots++; RVALUE_AGE_SET_BITMAP(object, 0); @@ -5582,25 +5571,10 @@ gc_compact_move(rb_objspace_t *objspace, rb_heap_t *heap, VALUE src) GC_ASSERT(gc_is_moveable_obj(objspace, src)); rb_heap_t *dest_pool = gc_compact_destination_pool(objspace, heap, src); - uint32_t orig_shape = 0; - uint32_t new_shape = 0; - if (gc_compact_heap_cursors_met_p(dest_pool)) { return dest_pool != heap; } - if (RB_TYPE_P(src, T_OBJECT)) { - orig_shape = rb_gc_get_shape(src); - - if (dest_pool != heap) { - new_shape = rb_gc_rebuild_shape(src, dest_pool - heaps); - - if (new_shape == 0) { - dest_pool = heap; - } - } - } - while (!try_move(objspace, dest_pool, dest_pool->free_pages, src)) { struct gc_sweep_context ctx = { .page = dest_pool->sweeping_page, @@ -5626,14 +5600,6 @@ gc_compact_move(rb_objspace_t *objspace, rb_heap_t *heap, VALUE src) } } - if (orig_shape != 0) { - if (new_shape != 0) { - VALUE dest = rb_gc_impl_location(objspace, src); - rb_gc_set_shape(dest, new_shape); - } - RMOVED(src)->original_shape_id = orig_shape; - } - return true; } @@ -6985,8 +6951,11 @@ gc_is_moveable_obj(rb_objspace_t *objspace, VALUE obj) void rb_mv_generic_ivar(VALUE src, VALUE dst); static VALUE -gc_move(rb_objspace_t *objspace, VALUE src, VALUE dest, size_t src_slot_size, size_t slot_size) +gc_move(rb_objspace_t *objspace, VALUE src, VALUE dest, struct heap_page *src_page, struct heap_page *dest_page) { + size_t src_slot_size = src_page->slot_size; + size_t slot_size = dest_page->slot_size; + int marked; int wb_unprotected; int uncollectible; @@ -7015,6 +6984,10 @@ gc_move(rb_objspace_t *objspace, VALUE src, VALUE dest, size_t src_slot_size, si /* Move the object */ memcpy((void *)dest, (void *)src, MIN(src_slot_size, slot_size)); + if (src_slot_size != slot_size && RB_TYPE_P(src, T_OBJECT)) { + rb_gc_obj_changed_pool(dest, dest_page->heap - heaps); + } + if (RVALUE_OVERHEAD > 0) { void *dest_overhead = (void *)(((uintptr_t)dest) + slot_size - RVALUE_OVERHEAD); void *src_overhead = (void *)(((uintptr_t)src) + src_slot_size - RVALUE_OVERHEAD); diff --git a/gc/gc.h b/gc/gc.h index d38a129887d27f..31ce736778d295 100644 --- a/gc/gc.h +++ b/gc/gc.h @@ -86,9 +86,7 @@ MODULAR_GC_FN void rb_gc_mark_roots(void *objspace, const char **categoryp); MODULAR_GC_FN void rb_gc_ractor_newobj_cache_foreach(void (*func)(void *cache, void *data), void *data); MODULAR_GC_FN bool rb_gc_multi_ractor_p(void); MODULAR_GC_FN bool rb_gc_shutdown_call_finalizer_p(VALUE obj); -MODULAR_GC_FN uint32_t rb_gc_get_shape(VALUE obj); -MODULAR_GC_FN void rb_gc_set_shape(VALUE obj, uint32_t shape_id); -MODULAR_GC_FN uint32_t rb_gc_rebuild_shape(VALUE obj, size_t heap_id); +MODULAR_GC_FN void rb_gc_obj_changed_pool(VALUE obj, size_t heap_id); MODULAR_GC_FN void rb_gc_prepare_heap_process_object(VALUE obj); MODULAR_GC_FN bool rb_memerror_reentered(void); MODULAR_GC_FN bool rb_obj_id_p(VALUE); diff --git a/io.c b/io.c index 63e015750b80df..39131ee11115e1 100644 --- a/io.c +++ b/io.c @@ -500,6 +500,7 @@ rb_cloexec_fcntl_dupfd(int fd, int minfd) #define argf_of(obj) (*(struct argf *)DATA_PTR(obj)) #define ARGF argf_of(argf) +#define ARGF_SET(field, value) RB_OBJ_WRITE(argf, &ARGF.field, value) #define GetWriteIO(io) rb_io_get_write_io(io) @@ -10017,16 +10018,16 @@ argf_memsize(const void *ptr) static const rb_data_type_t argf_type = { "ARGF", {argf_mark_and_move, RUBY_TYPED_DEFAULT_FREE, argf_memsize, argf_mark_and_move}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED }; static inline void -argf_init(struct argf *p, VALUE v) +argf_init(VALUE argf, struct argf *p, VALUE v) { p->filename = Qnil; p->current_file = Qnil; p->lineno = 0; - p->argv = v; + RB_OBJ_WRITE(argf, &p->argv, v); } static VALUE @@ -10035,7 +10036,7 @@ argf_alloc(VALUE klass) struct argf *p; VALUE argf = TypedData_Make_Struct(klass, struct argf, &argf_type, p); - argf_init(p, Qnil); + argf_init(argf, p, Qnil); return argf; } @@ -10046,7 +10047,7 @@ static VALUE argf_initialize(VALUE argf, VALUE argv) { memset(&ARGF, 0, sizeof(ARGF)); - argf_init(&ARGF, argv); + argf_init(argf, &ARGF, argv); return argf; } @@ -10057,7 +10058,8 @@ argf_initialize_copy(VALUE argf, VALUE orig) { if (!OBJ_INIT_COPY(argf, orig)) return argf; ARGF = argf_of(orig); - ARGF.argv = rb_obj_dup(ARGF.argv); + rb_gc_writebarrier_remember(argf); + ARGF_SET(argv, rb_obj_dup(ARGF.argv)); return argf; } @@ -10176,11 +10178,11 @@ argf_next_argv(VALUE argf) if (RARRAY_LEN(ARGF.argv) > 0) { VALUE filename = rb_ary_shift(ARGF.argv); FilePathValue(filename); - ARGF.filename = filename; + ARGF_SET(filename, filename); filename = rb_str_encode_ospath(filename); fn = StringValueCStr(filename); if (RSTRING_LEN(filename) == 1 && fn[0] == '-') { - ARGF.current_file = rb_stdin; + ARGF_SET(current_file, rb_stdin); if (ARGF.inplace) { rb_warn("Can't do inplace edit for stdio; skipping"); goto retry; @@ -10275,7 +10277,7 @@ argf_next_argv(VALUE argf) if (!ARGF.binmode) { fmode |= DEFAULT_TEXTMODE; } - ARGF.current_file = prep_io(fr, fmode, rb_cFile, fn); + ARGF_SET(current_file, prep_io(fr, fmode, rb_cFile, fn)); if (!NIL_P(write_io)) { rb_io_set_write_io(ARGF.current_file, write_io); } @@ -10304,8 +10306,8 @@ argf_next_argv(VALUE argf) } } else if (ARGF.next_p == -1) { - ARGF.current_file = rb_stdin; - ARGF.filename = rb_str_new2("-"); + ARGF_SET(current_file, rb_stdin); + ARGF_SET(filename, rb_str_new2("-")); if (ARGF.inplace) { rb_warn("Can't do inplace edit for stdio"); rb_ractor_stdout_set(orig_stdout); @@ -13674,6 +13676,7 @@ argf_set_encoding(int argc, VALUE *argv, VALUE argf) rb_io_set_encoding(argc, argv, ARGF.current_file); GetOpenFile(ARGF.current_file, fptr); ARGF.encs = fptr->encs; + RB_OBJ_WRITTEN(argf, Qundef, ARGF.encs.ecopts); return argf; } @@ -14606,7 +14609,7 @@ argf_inplace_mode_set(VALUE argf, VALUE val) ARGF.inplace = Qnil; } else { - ARGF.inplace = rb_str_new_frozen(val); + ARGF_SET(inplace, rb_str_new_frozen(val)); } return argf; } @@ -14620,7 +14623,7 @@ opt_i_set(VALUE val, ID id, VALUE *var) void ruby_set_inplace_mode(const char *suffix) { - ARGF.inplace = !suffix ? Qfalse : !*suffix ? Qnil : rb_str_new(suffix, strlen(suffix)); + ARGF_SET(inplace, !suffix ? Qfalse : !*suffix ? Qnil : rb_str_new(suffix, strlen(suffix))); } /* @@ -15968,7 +15971,7 @@ Init_IO(void) rb_define_hooked_variable("$.", &argf, argf_lineno_getter, argf_lineno_setter); rb_define_hooked_variable("$FILENAME", &argf, argf_filename_getter, rb_gvar_readonly_setter); - ARGF.filename = rb_str_new2("-"); + ARGF_SET(filename, rb_str_new2("-")); rb_define_hooked_variable("$-i", &argf, opt_i_get, opt_i_set); rb_gvar_ractor_local("$-i"); diff --git a/memory_view.c b/memory_view.c index 9f5d6715804b22..2de756d681e4c7 100644 --- a/memory_view.c +++ b/memory_view.c @@ -65,7 +65,7 @@ const rb_data_type_t rb_memory_view_exported_object_registry_data_type = { exported_object_registry_free, 0, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED }; static int @@ -101,6 +101,7 @@ register_exported_object(VALUE obj) { RB_VM_LOCKING() { st_update(exported_object_table, (st_data_t)obj, exported_object_add_ref, 0); + RB_OBJ_WRITTEN(rb_memory_view_exported_object_registry, Qundef, obj); } }