summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/macos.yml4
-rw-r--r--.github/workflows/ubuntu.yml4
-rw-r--r--common.mk4
-rw-r--r--compile.c26
-rw-r--r--iseq.c4
-rw-r--r--prism_compile.c3
-rw-r--r--ractor.c6
-rw-r--r--ractor_sync.c2
-rw-r--r--time.c22
9 files changed, 51 insertions, 24 deletions
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index 54161f888c..d418912f35 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -107,6 +107,10 @@ jobs:
- run: make hello
+ - name: runirb
+ run: |
+ echo IRB::VERSION | make runirb RUNOPT="-- -f"
+
- name: Set test options for skipped tests
run: |
set -x
diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml
index ac7963649b..041cb412fd 100644
--- a/.github/workflows/ubuntu.yml
+++ b/.github/workflows/ubuntu.yml
@@ -99,6 +99,10 @@ jobs:
- run: $SETARCH make hello
+ - name: runirb
+ run: |
+ echo IRB::VERSION | $SETARCH make runirb RUNOPT="-- -f"
+
- name: Set test options for skipped tests
run: |
set -x
diff --git a/common.mk b/common.mk
index f94ad33d88..e5a4d34a0a 100644
--- a/common.mk
+++ b/common.mk
@@ -1427,8 +1427,8 @@ run: yes-fake miniruby$(EXEEXT) PHONY
runruby: $(PROGRAM) PHONY
RUBY_ON_BUG='gdb -x $(srcdir)/.gdbinit -p' $(RUNRUBY) $(RUNOPT0) $(TESTRUN_SCRIPT) $(RUNOPT)
-runirb: $(PROGRAM) PHONY
- RUBY_ON_BUG='gdb -x $(srcdir)/.gdbinit -p' $(RUNRUBY) $(RUNOPT0) -r irb -e 'IRB.start("make runirb")' $(RUNOPT)
+runirb: $(PROGRAM) update-default-gemspecs
+ RUBY_ON_BUG='gdb -x $(srcdir)/.gdbinit -p' $(RUNRUBY) $(RUNOPT0) -rrubygems -r irb -e 'IRB.start("make runirb")' $(RUNOPT)
parse: yes-fake miniruby$(EXEEXT) PHONY
$(BTESTRUBY) --dump=parsetree_with_comment,insns $(TESTRUN_SCRIPT)
diff --git a/compile.c b/compile.c
index 6bcfcd3398..477f082144 100644
--- a/compile.c
+++ b/compile.c
@@ -3493,7 +3493,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
iobj->insn_id = BIN(opt_ary_freeze);
iobj->operand_size = 2;
iobj->operands = compile_data_calloc2(iseq, iobj->operand_size, sizeof(VALUE));
- iobj->operands[0] = rb_cArray_empty_frozen;
+ RB_OBJ_WRITE(iseq, &iobj->operands[0], rb_cArray_empty_frozen);
iobj->operands[1] = (VALUE)ci;
ELEM_REMOVE(next);
}
@@ -3516,7 +3516,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
iobj->insn_id = BIN(opt_hash_freeze);
iobj->operand_size = 2;
iobj->operands = compile_data_calloc2(iseq, iobj->operand_size, sizeof(VALUE));
- iobj->operands[0] = rb_cHash_empty_frozen;
+ RB_OBJ_WRITE(iseq, &iobj->operands[0], rb_cHash_empty_frozen);
iobj->operands[1] = (VALUE)ci;
ELEM_REMOVE(next);
}
@@ -4094,7 +4094,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
unsigned int flags = vm_ci_flag(ci);
if ((flags & set_flags) == set_flags && !(flags & unset_flags)) {
((INSN*)niobj)->insn_id = BIN(putobject);
- OPERAND_AT(niobj, 0) = rb_hash_freeze(rb_hash_resurrect(OPERAND_AT(niobj, 0)));
+ RB_OBJ_WRITE(iseq, &OPERAND_AT(niobj, 0), rb_hash_freeze(rb_hash_resurrect(OPERAND_AT(niobj, 0))));
const struct rb_callinfo *nci = vm_ci_new(vm_ci_mid(ci),
flags & ~VM_CALL_KW_SPLAT_MUT, vm_ci_argc(ci), vm_ci_kwarg(ci));
@@ -9257,12 +9257,13 @@ compile_builtin_mandatory_only_method(rb_iseq_t *iseq, const NODE *node, const N
VALUE ast_value = rb_ruby_ast_new(RNODE(&scope_node));
- ISEQ_BODY(iseq)->mandatory_only_iseq =
+ const rb_iseq_t *mandatory_only_iseq =
rb_iseq_new_with_opt(ast_value, rb_iseq_base_label(iseq),
rb_iseq_path(iseq), rb_iseq_realpath(iseq),
nd_line(line_node), NULL, 0,
ISEQ_TYPE_METHOD, ISEQ_COMPILE_DATA(iseq)->option,
ISEQ_BODY(iseq)->variable.script_lines);
+ RB_OBJ_WRITE(iseq, &ISEQ_BODY(iseq)->mandatory_only_iseq, (VALUE)mandatory_only_iseq);
ALLOCV_END(idtmp);
return COMPILE_OK;
@@ -13288,7 +13289,7 @@ ibf_dump_catch_table(struct ibf_dump *dump, const rb_iseq_t *iseq)
}
static struct iseq_catch_table *
-ibf_load_catch_table(const struct ibf_load *load, ibf_offset_t catch_table_offset, unsigned int size)
+ibf_load_catch_table(const struct ibf_load *load, ibf_offset_t catch_table_offset, unsigned int size, const rb_iseq_t *parent_iseq)
{
if (size) {
struct iseq_catch_table *table = ruby_xmalloc(iseq_catch_table_bytes(size));
@@ -13305,7 +13306,8 @@ ibf_load_catch_table(const struct ibf_load *load, ibf_offset_t catch_table_offse
table->entries[i].cont = (unsigned int)ibf_load_small_value(load, &reading_pos);
table->entries[i].sp = (unsigned int)ibf_load_small_value(load, &reading_pos);
- table->entries[i].iseq = ibf_load_iseq(load, (const rb_iseq_t *)(VALUE)iseq_index);
+ rb_iseq_t *catch_iseq = (rb_iseq_t *)ibf_load_iseq(load, (const rb_iseq_t *)(VALUE)iseq_index);
+ RB_OBJ_WRITE(parent_iseq, &table->entries[i].iseq, catch_iseq);
}
return table;
}
@@ -13823,10 +13825,14 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset)
load_body->insns_info.body = ibf_load_insns_info_body(load, insns_info_body_offset, insns_info_size);
load_body->insns_info.positions = ibf_load_insns_info_positions(load, insns_info_positions_offset, insns_info_size);
load_body->local_table = ibf_load_local_table(load, local_table_offset, local_table_size);
- load_body->catch_table = ibf_load_catch_table(load, catch_table_offset, catch_table_size);
- load_body->parent_iseq = ibf_load_iseq(load, (const rb_iseq_t *)(VALUE)parent_iseq_index);
- load_body->local_iseq = ibf_load_iseq(load, (const rb_iseq_t *)(VALUE)local_iseq_index);
- load_body->mandatory_only_iseq = ibf_load_iseq(load, (const rb_iseq_t *)(VALUE)mandatory_only_iseq_index);
+ load_body->catch_table = ibf_load_catch_table(load, catch_table_offset, catch_table_size, iseq);
+ const rb_iseq_t *parent_iseq = ibf_load_iseq(load, (const rb_iseq_t *)(VALUE)parent_iseq_index);
+ const rb_iseq_t *local_iseq = ibf_load_iseq(load, (const rb_iseq_t *)(VALUE)local_iseq_index);
+ const rb_iseq_t *mandatory_only_iseq = ibf_load_iseq(load, (const rb_iseq_t *)(VALUE)mandatory_only_iseq_index);
+
+ RB_OBJ_WRITE(iseq, &load_body->parent_iseq, parent_iseq);
+ RB_OBJ_WRITE(iseq, &load_body->local_iseq, local_iseq);
+ RB_OBJ_WRITE(iseq, &load_body->mandatory_only_iseq, mandatory_only_iseq);
// This must be done after the local table is loaded.
if (load_body->param.keyword != NULL) {
diff --git a/iseq.c b/iseq.c
index dcde27ba1b..1201b877ab 100644
--- a/iseq.c
+++ b/iseq.c
@@ -602,11 +602,11 @@ set_relation(rb_iseq_t *iseq, const rb_iseq_t *piseq)
body->local_iseq = iseq;
}
else if (piseq) {
- body->local_iseq = ISEQ_BODY(piseq)->local_iseq;
+ RB_OBJ_WRITE(iseq, &body->local_iseq, ISEQ_BODY(piseq)->local_iseq);
}
if (piseq) {
- body->parent_iseq = piseq;
+ RB_OBJ_WRITE(iseq, &body->parent_iseq, piseq);
}
if (type == ISEQ_TYPE_MAIN) {
diff --git a/prism_compile.c b/prism_compile.c
index 2ae6c1db9e..05697ff5cf 100644
--- a/prism_compile.c
+++ b/prism_compile.c
@@ -3497,7 +3497,7 @@ pm_compile_builtin_mandatory_only_method(rb_iseq_t *iseq, pm_scope_node_t *scope
pm_scope_node_init(&def.base, &next_scope_node, scope_node);
int error_state;
- ISEQ_BODY(iseq)->mandatory_only_iseq = pm_iseq_new_with_opt(
+ const rb_iseq_t *mandatory_only_iseq = pm_iseq_new_with_opt(
&next_scope_node,
rb_iseq_base_label(iseq),
rb_iseq_path(iseq),
@@ -3509,6 +3509,7 @@ pm_compile_builtin_mandatory_only_method(rb_iseq_t *iseq, pm_scope_node_t *scope
ISEQ_COMPILE_DATA(iseq)->option,
&error_state
);
+ RB_OBJ_WRITE(iseq, &ISEQ_BODY(iseq)->mandatory_only_iseq, (VALUE)mandatory_only_iseq);
if (error_state) {
RUBY_ASSERT(ISEQ_BODY(iseq)->mandatory_only_iseq == NULL);
diff --git a/ractor.c b/ractor.c
index a4a746b495..317b24dca2 100644
--- a/ractor.c
+++ b/ractor.c
@@ -1188,6 +1188,7 @@ obj_traverse_i(VALUE obj, struct obj_traverse_data *data)
// already traversed
return 0;
}
+ RB_OBJ_WRITTEN(data->rec_hash, Qundef, obj);
struct obj_traverse_callback_data d = {
.stop = false,
@@ -1644,6 +1645,8 @@ obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
}
else {
st_insert(obj_traverse_replace_rec(data), (st_data_t)obj, replacement);
+ RB_OBJ_WRITTEN(data->rec_hash, Qundef, obj);
+ RB_OBJ_WRITTEN(data->rec_hash, Qundef, replacement);
}
if (!data->move) {
@@ -1882,6 +1885,9 @@ move_leave(VALUE obj, struct obj_traverse_replace_data *data)
rb_gc_obj_slot_size(obj) - sizeof(VALUE)
);
+ // We've copied obj's references to the replacement
+ rb_gc_writebarrier_remember(data->replacement);
+
void rb_replace_generic_ivar(VALUE clone, VALUE obj); // variable.c
rb_gc_obj_id_moved(data->replacement);
diff --git a/ractor_sync.c b/ractor_sync.c
index 204c800a06..30c386663c 100644
--- a/ractor_sync.c
+++ b/ractor_sync.c
@@ -81,6 +81,7 @@ ractor_port_init(VALUE rpv, rb_ractor_t *r)
struct ractor_port *rp = RACTOR_PORT_PTR(rpv);
rp->r = r;
+ RB_OBJ_WRITTEN(rpv, Qundef, r->pub.self);
rp->id_ = ractor_genid_for_port(r);
ractor_add_port(r, ractor_port_id(rp));
@@ -102,6 +103,7 @@ ractor_port_initialzie_copy(VALUE self, VALUE orig)
struct ractor_port *dst = RACTOR_PORT_PTR(self);
struct ractor_port *src = RACTOR_PORT_PTR(orig);
dst->r = src->r;
+ RB_OBJ_WRITTEN(self, Qundef, dst->r->pub.self);
dst->id_ = ractor_port_id(src);
return self;
diff --git a/time.c b/time.c
index 0e91521db1..1eb8f8da9c 100644
--- a/time.c
+++ b/time.c
@@ -2307,14 +2307,14 @@ utc_offset_arg(VALUE arg)
static void
zone_set_offset(VALUE zone, struct time_object *tobj,
- wideval_t tlocal, wideval_t tutc)
+ wideval_t tlocal, wideval_t tutc, VALUE time)
{
/* tlocal and tutc must be unmagnified and in seconds */
wideval_t w = wsub(tlocal, tutc);
VALUE off = w2v(w);
validate_utc_offset(off);
- tobj->vtm.utc_offset = off;
- tobj->vtm.zone = zone;
+ RB_OBJ_WRITE(time, &tobj->vtm.utc_offset, off);
+ RB_OBJ_WRITE(time, &tobj->vtm.zone, zone);
TZMODE_SET_LOCALTIME(tobj);
}
@@ -2429,7 +2429,7 @@ zone_timelocal(VALUE zone, VALUE time)
if (UNDEF_P(utc)) return 0;
s = extract_time(utc);
- zone_set_offset(zone, tobj, t, s);
+ zone_set_offset(zone, tobj, t, s, time);
s = rb_time_magnify(s);
if (tobj->vtm.subsecx != INT2FIX(0)) {
s = wadd(s, v2w(tobj->vtm.subsecx));
@@ -2458,7 +2458,7 @@ zone_localtime(VALUE zone, VALUE time)
s = extract_vtm(local, time, tobj, subsecx);
tobj->vtm.tm_got = 1;
- zone_set_offset(zone, tobj, s, t);
+ zone_set_offset(zone, tobj, s, t, time);
zone_set_dst(zone, tobj, tm);
RB_GC_GUARD(time);
@@ -4088,7 +4088,9 @@ time_init_copy(VALUE copy, VALUE time)
if (!OBJ_INIT_COPY(copy, time)) return copy;
GetTimeval(time, tobj);
GetNewTimeval(copy, tcopy);
- MEMCPY(tcopy, tobj, struct time_object, 1);
+
+ time_set_timew(copy, tcopy, tobj->timew);
+ time_set_vtm(copy, tcopy, tobj->vtm);
return copy;
}
@@ -5752,7 +5754,7 @@ end_submicro: ;
}
if (!NIL_P(zone)) {
zone = mload_zone(time, zone);
- tobj->vtm.zone = zone;
+ RB_OBJ_WRITE(time, &tobj->vtm.zone, zone);
zone_localtime(zone, time);
}
@@ -5798,8 +5800,10 @@ tm_from_time(VALUE klass, VALUE time)
tm = time_s_alloc(klass);
ttm = RTYPEDDATA_GET_DATA(tm);
v = &vtm;
- GMTIMEW(ttm->timew = tobj->timew, v);
- ttm->timew = wsub(ttm->timew, v->subsecx);
+
+ WIDEVALUE timew = tobj->timew;
+ GMTIMEW(timew, v);
+ time_set_timew(tm, ttm, wsub(timew, v->subsecx));
v->subsecx = INT2FIX(0);
v->zone = Qnil;
time_set_vtm(tm, ttm, *v);