Guard callinfo
Callinfo was being written in to an array and the GC would not see the
reference on the stack. `new_insn_send` creates a new callinfo object,
then it calls `new_insn_core`. `new_insn_core` allocates a new INSN
linked list item, which can end up calling `xmalloc` which will trigger
a GC:
70cd351c7c/compile.c (L968-L969)
Since the callinfo object isn't on the stack, the GC won't see it, and
it can get collected. This patch just refactors `new_insn_send` to keep
the object on the stack
Co-authored-by: John Hawthorn <john@hawthorn.email>
This commit is contained in:
parent
f4ce78d5c1
commit
efcdf68e64
Notes:
git
2021-01-14 09:14:19 +09:00
@ -1302,12 +1302,15 @@ static INSN *
|
|||||||
new_insn_send(rb_iseq_t *iseq, int line_no, ID id, VALUE argc, const rb_iseq_t *blockiseq, VALUE flag, struct rb_callinfo_kwarg *keywords)
|
new_insn_send(rb_iseq_t *iseq, int line_no, ID id, VALUE argc, const rb_iseq_t *blockiseq, VALUE flag, struct rb_callinfo_kwarg *keywords)
|
||||||
{
|
{
|
||||||
VALUE *operands = compile_data_calloc2(iseq, sizeof(VALUE), 2);
|
VALUE *operands = compile_data_calloc2(iseq, sizeof(VALUE), 2);
|
||||||
operands[0] = (VALUE)new_callinfo(iseq, id, FIX2INT(argc), FIX2INT(flag), keywords, blockiseq != NULL);
|
VALUE ci = (VALUE)new_callinfo(iseq, id, FIX2INT(argc), FIX2INT(flag), keywords, blockiseq != NULL);
|
||||||
|
operands[0] = ci;
|
||||||
operands[1] = (VALUE)blockiseq;
|
operands[1] = (VALUE)blockiseq;
|
||||||
if (blockiseq) {
|
if (blockiseq) {
|
||||||
RB_OBJ_WRITTEN(iseq, Qundef, blockiseq);
|
RB_OBJ_WRITTEN(iseq, Qundef, blockiseq);
|
||||||
}
|
}
|
||||||
return new_insn_core(iseq, line_no, BIN(send), 2, operands);
|
INSN *insn = new_insn_core(iseq, line_no, BIN(send), 2, operands);
|
||||||
|
RB_GC_GUARD(ci);
|
||||||
|
return insn;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rb_iseq_t *
|
static rb_iseq_t *
|
||||||
|
@ -175,6 +175,16 @@ class TestGc < Test::Unit::TestCase
|
|||||||
assert_raise_with_message(ArgumentError, /\u{30eb 30d3 30fc}/) {GC.latest_gc_info(:"\u{30eb 30d3 30fc}")}
|
assert_raise_with_message(ArgumentError, /\u{30eb 30d3 30fc}/) {GC.latest_gc_info(:"\u{30eb 30d3 30fc}")}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_stress_compile_send
|
||||||
|
assert_in_out_err(%w[--disable-gems], <<-EOS, [], [], "")
|
||||||
|
GC.stress = true
|
||||||
|
begin
|
||||||
|
eval("A::B.c(1, 1, d: 234)")
|
||||||
|
rescue
|
||||||
|
end
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
def test_singleton_method
|
def test_singleton_method
|
||||||
assert_in_out_err(%w[--disable-gems], <<-EOS, [], [], "[ruby-dev:42832]")
|
assert_in_out_err(%w[--disable-gems], <<-EOS, [], [], "[ruby-dev:42832]")
|
||||||
GC.stress = true
|
GC.stress = true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user