This commit is contained in:
John Hawthorn 2025-08-15 08:17:11 +05:30 committed by GitHub
commit 8c17c4de3e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 1705 additions and 27 deletions

1
.gitignore vendored
View file

@ -97,6 +97,7 @@ lcov*.info
/enc.mk
/encdb.h
/exts.mk
/gc/*/exts.mk
/goruby
/id.[ch]
/largefile.h

View file

@ -990,6 +990,7 @@ copy_tables(VALUE clone, VALUE orig)
arg.klass = clone;
rb_id_table_foreach(orig_tbl, clone_const_i, &arg);
RCLASS_WRITE_CONST_TBL(clone, const_tbl, false);
rb_gc_writebarrier_remember(clone);
}
}

View file

@ -2932,7 +2932,6 @@ iseq_set_exception_table(rb_iseq_t *iseq)
RUBY_ASSERT(pos >= 0);
entry->end = (unsigned int)pos;
entry->iseq = (rb_iseq_t *)ptr[3];
RB_OBJ_WRITTEN(iseq, Qundef, entry->iseq);
/* stack depth */
if (ptr[4]) {
@ -2953,6 +2952,9 @@ iseq_set_exception_table(rb_iseq_t *iseq)
}
}
ISEQ_BODY(iseq)->catch_table = table;
for (i = 0; i < table->size; i++) {
RB_OBJ_WRITTEN(iseq, Qundef, table->entries[i].iseq);
}
RB_OBJ_WRITE(iseq, &ISEQ_COMPILE_DATA(iseq)->catch_table_ary, 0); /* free */
}
@ -12913,23 +12915,25 @@ ibf_load_code(const struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t bytecod
VALUE iseqv = (VALUE)iseq;
unsigned int code_index;
ibf_offset_t reading_pos = bytecode_offset;
VALUE *code = ALLOC_N(VALUE, iseq_size);
VALUE *code = ZALLOC_N(VALUE, iseq_size);
struct rb_iseq_constant_body *load_body = ISEQ_BODY(iseq);
struct rb_call_data *cd_entries = load_body->call_data;
int ic_index = 0;
bool needs_bitmap = false;
iseq_bits_t * mark_offset_bits;
iseq_bits_t tmp[1] = {0};
if (ISEQ_MBITS_BUFLEN(iseq_size) == 1) {
mark_offset_bits = tmp;
load_body->mark_bits.single = 0;
mark_offset_bits = &load_body->mark_bits.single;
}
else {
mark_offset_bits = ZALLOC_N(iseq_bits_t, ISEQ_MBITS_BUFLEN(iseq_size));
load_body->mark_bits.list = ZALLOC_N(iseq_bits_t, ISEQ_MBITS_BUFLEN(iseq_size));
mark_offset_bits = load_body->mark_bits.list;
}
bool needs_bitmap = false;
load_body->iseq_encoded = code;
load_body->iseq_size = iseq_size;
for (code_index=0; code_index<iseq_size;) {
/* opcode */
@ -13048,22 +13052,12 @@ ibf_load_code(const struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t bytecod
if (insn_len(insn) != op_index+1) {
rb_raise(rb_eRuntimeError, "operand size mismatch");
}
rb_gc();
}
load_body->iseq_encoded = code;
load_body->iseq_size = code_index;
if (ISEQ_MBITS_BUFLEN(load_body->iseq_size) == 1) {
load_body->mark_bits.single = mark_offset_bits[0];
}
else {
if (needs_bitmap) {
load_body->mark_bits.list = mark_offset_bits;
}
else {
load_body->mark_bits.list = 0;
ruby_xfree(mark_offset_bits);
}
if (!needs_bitmap) {
ruby_xfree(load_body->mark_bits.list);
load_body->mark_bits.list = NULL;
}
RUBY_ASSERT(code_index == iseq_size);

3
gc/wbcheck/extconf.rb Normal file
View file

@ -0,0 +1,3 @@
require_relative '../extconf_base'
create_gc_makefile("wbcheck")

1668
gc/wbcheck/wbcheck.c Normal file

File diff suppressed because it is too large Load diff

3
hash.c
View file

@ -1975,6 +1975,9 @@ rb_hash_rehash_i(VALUE key, VALUE value, VALUE arg)
else {
st_insert(RHASH_ST_TABLE(arg), (st_data_t)key, (st_data_t)value);
}
RB_OBJ_WRITTEN(arg, Qundef, key);
RB_OBJ_WRITTEN(arg, Qundef, value);
return ST_CONTINUE;
}

1
io.c
View file

@ -15982,6 +15982,7 @@ Init_IO(void)
rb_define_method(rb_cARGF, "set_encoding", argf_set_encoding, -1);
argf = rb_class_new_instance(0, 0, rb_cARGF);
rb_vm_register_global_object(argf);
rb_define_readonly_variable("$<", &argf);
/*

2
iseq.c
View file

@ -348,7 +348,7 @@ rb_iseq_mark_and_move(rb_iseq_t *iseq, bool reference_updating)
if (ISEQ_BODY(iseq)) {
struct rb_iseq_constant_body *body = ISEQ_BODY(iseq);
rb_iseq_mark_and_move_each_body_value(iseq, reference_updating ? ISEQ_ORIGINAL_ISEQ(iseq) : NULL);
rb_iseq_mark_and_move_each_body_value(iseq, ISEQ_ORIGINAL_ISEQ(iseq));
rb_gc_mark_and_move(&body->variable.coverage);
rb_gc_mark_and_move(&body->variable.pc2branchindex);

8
proc.c
View file

@ -722,6 +722,7 @@ rb_func_proc_dup(VALUE src_obj)
ep[VM_ENV_DATA_INDEX_ME_CREF] = src_proc->block.as.captured.ep[VM_ENV_DATA_INDEX_ME_CREF];
ep[VM_ENV_DATA_INDEX_SPECVAL] = src_proc->block.as.captured.ep[VM_ENV_DATA_INDEX_SPECVAL];
ep[VM_ENV_DATA_INDEX_ENV] = src_proc->block.as.captured.ep[VM_ENV_DATA_INDEX_ENV];
rb_gc_writebarrier_remember(proc_obj);
return proc_obj;
}
@ -992,7 +993,12 @@ rb_proc_call_kw(VALUE self, VALUE args, int kw_splat)
VALUE vret;
rb_proc_t *proc;
int argc = check_argc(RARRAY_LEN(args));
const VALUE *argv = RARRAY_CONST_PTR(args);
// rb_vm_invoke_proc may end up modifying argv as part of calling and so we
// must use RARRAY_PTR, which marks the array as WB_UNPROTECTED instead of
// RARRAY_CONST_PTR. Unfortunately this is worse for GC.
// See invoke_block_from_c_proc
VALUE *argv = RARRAY_PTR(args);
GetProcPtr(self, proc);
vret = rb_vm_invoke_proc(GET_EC(), proc, argc, argv,
kw_splat, VM_BLOCK_HANDLER_NONE);

View file

@ -1921,7 +1921,7 @@ move_leave(VALUE obj, struct obj_traverse_replace_data *data)
// Avoid mutations using bind_call, etc.
MEMZERO((char *)obj, char, sizeof(struct RBasic));
RBASIC(obj)->flags = flags;
RBASIC_SET_CLASS_RAW(obj, rb_cRactorMovedObject);
RBASIC_SET_CLASS(obj, rb_cRactorMovedObject);
return traverse_cont;
}

View file

@ -6,7 +6,7 @@
#include "vm_debug.h"
#ifndef RACTOR_CHECK_MODE
#define RACTOR_CHECK_MODE (VM_CHECK_MODE || RUBY_DEBUG) && (SIZEOF_UINT64_T == SIZEOF_VALUE)
#define RACTOR_CHECK_MODE 0
#endif
struct rb_ractor_sync {

2
ruby.c
View file

@ -790,7 +790,7 @@ require_libraries(VALUE *req_list)
while (list && RARRAY_LEN(list) > 0) {
VALUE feature = rb_ary_shift(list);
rb_enc_associate(feature, extenc);
RBASIC_SET_CLASS_RAW(feature, rb_cString);
RBASIC_SET_CLASS(feature, rb_cString);
OBJ_FREEZE(feature);
rb_funcallv(self, require, 1, &feature);
}

1
st.c
View file

@ -1508,6 +1508,7 @@ st_update(st_table *tab, st_data_t key,
switch (retval) {
case ST_CONTINUE:
if (! existing) {
xfree(xmalloc(1));
st_add_direct_with_hash(tab, key, value, hash);
break;
}