зеркало из https://github.com/github/ruby.git
Pin instruction storage
The operands in each instruction needs to be pinned because if auto-compaction runs in iseq_set_sequence, then the objects could exist on the generated_iseq buffer, which would not be reference updated which can lead to T_MOVED (and subsequently T_NONE) objects on the iseq.
This commit is contained in:
Родитель
092a17e7bd
Коммит
d1691617d6
16
compile.c
16
compile.c
|
@ -1375,7 +1375,7 @@ new_adjust_body(rb_iseq_t *iseq, LABEL *label, int line)
|
|||
}
|
||||
|
||||
static void
|
||||
iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE *, VALUE), VALUE data)
|
||||
iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE, VALUE), VALUE data)
|
||||
{
|
||||
const char *types = insn_op_types(insn->insn_id);
|
||||
for (int j = 0; types[j]; j++) {
|
||||
|
@ -1386,7 +1386,7 @@ iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE *, VALUE), VALUE d
|
|||
case TS_VALUE:
|
||||
case TS_IC: // constant path array
|
||||
case TS_CALLDATA: // ci is stored.
|
||||
func(&OPERAND_AT(insn, j), data);
|
||||
func(OPERAND_AT(insn, j), data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1395,9 +1395,9 @@ iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE *, VALUE), VALUE d
|
|||
}
|
||||
|
||||
static void
|
||||
iseq_insn_each_object_write_barrier(VALUE *obj_ptr, VALUE iseq)
|
||||
iseq_insn_each_object_write_barrier(VALUE obj, VALUE iseq)
|
||||
{
|
||||
RB_OBJ_WRITTEN(iseq, Qundef, *obj_ptr);
|
||||
RB_OBJ_WRITTEN(iseq, Qundef, obj);
|
||||
}
|
||||
|
||||
static INSN *
|
||||
|
@ -10877,13 +10877,13 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords)
|
|||
}
|
||||
|
||||
static void
|
||||
iseq_insn_each_object_mark_and_move(VALUE *obj_ptr, VALUE _)
|
||||
iseq_insn_each_object_mark_and_pin(VALUE obj, VALUE _)
|
||||
{
|
||||
rb_gc_mark_and_move(obj_ptr);
|
||||
rb_gc_mark(obj);
|
||||
}
|
||||
|
||||
void
|
||||
rb_iseq_mark_and_move_insn_storage(struct iseq_compile_data_storage *storage)
|
||||
rb_iseq_mark_and_pin_insn_storage(struct iseq_compile_data_storage *storage)
|
||||
{
|
||||
INSN *iobj = 0;
|
||||
size_t size = sizeof(INSN);
|
||||
|
@ -10908,7 +10908,7 @@ rb_iseq_mark_and_move_insn_storage(struct iseq_compile_data_storage *storage)
|
|||
iobj = (INSN *)&storage->buff[pos];
|
||||
|
||||
if (iobj->operands) {
|
||||
iseq_insn_each_markable_object(iobj, iseq_insn_each_object_mark_and_move, (VALUE)0);
|
||||
iseq_insn_each_markable_object(iobj, iseq_insn_each_object_mark_and_pin, (VALUE)0);
|
||||
}
|
||||
pos += (int)size;
|
||||
}
|
||||
|
|
9
iseq.c
9
iseq.c
|
@ -393,7 +393,14 @@ rb_iseq_mark_and_move(rb_iseq_t *iseq, bool reference_updating)
|
|||
else if (FL_TEST_RAW((VALUE)iseq, ISEQ_USE_COMPILE_DATA)) {
|
||||
const struct iseq_compile_data *const compile_data = ISEQ_COMPILE_DATA(iseq);
|
||||
|
||||
rb_iseq_mark_and_move_insn_storage(compile_data->insn.storage_head);
|
||||
if (!reference_updating) {
|
||||
/* The operands in each instruction needs to be pinned because
|
||||
* if auto-compaction runs in iseq_set_sequence, then the objects
|
||||
* could exist on the generated_iseq buffer, which would not be
|
||||
* reference updated which can lead to T_MOVED (and subsequently
|
||||
* T_NONE) objects on the iseq. */
|
||||
rb_iseq_mark_and_pin_insn_storage(compile_data->insn.storage_head);
|
||||
}
|
||||
|
||||
rb_gc_mark_and_move((VALUE *)&compile_data->err_info);
|
||||
rb_gc_mark_and_move((VALUE *)&compile_data->catch_table_ary);
|
||||
|
|
2
iseq.h
2
iseq.h
|
@ -189,7 +189,7 @@ VALUE *rb_iseq_original_iseq(const rb_iseq_t *iseq);
|
|||
void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc,
|
||||
VALUE locals, VALUE args,
|
||||
VALUE exception, VALUE body);
|
||||
void rb_iseq_mark_and_move_insn_storage(struct iseq_compile_data_storage *arena);
|
||||
void rb_iseq_mark_and_pin_insn_storage(struct iseq_compile_data_storage *arena);
|
||||
|
||||
VALUE rb_iseq_load(VALUE data, VALUE parent, VALUE opt);
|
||||
VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc);
|
||||
|
|
Загрузка…
Ссылка в новой задаче