1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Scan the ISEQ arena for markables and mark them

This commit scans the ISEQ arena for objects that can be marked and
marks them.  This should make the mark array unnecessary.
This commit is contained in:
Aaron Patterson 2019-09-16 17:19:44 -07:00
parent a618d64086
commit 50fadefb7e
No known key found for this signature in database
GPG key ID: 953170BCB4FFAFC6
3 changed files with 55 additions and 0 deletions

View file

@ -8952,6 +8952,57 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords)
return keyword;
}
void
rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *storage)
{
INSN *iobj = 0;
size_t size = sizeof(INSN);
unsigned int pos = 0;
while (storage) {
#ifdef STRICT_ALIGNMENT
size_t padding = calc_padding((void *)&storage->buff[pos], size);
#else
const size_t padding = 0; /* expected to be optimized by compiler */
#endif /* STRICT_ALIGNMENT */
size_t offset = pos + size + padding;
if (offset > storage->size || offset > storage->pos) {
pos = 0;
storage = storage->next;
} else {
#ifdef STRICT_ALIGNMENT
pos += (int)padding;
#endif /* STRICT_ALIGNMENT */
iobj = (INSN *)&storage->buff[pos];
if (iobj->operands) {
int j;
const char *types = insn_op_types(iobj->insn_id);
for(j = 0; types[j]; j++) {
char type = types[j];
switch(type) {
case TS_CDHASH:
case TS_ISEQ:
case TS_VALUE:
{
VALUE op = OPERAND_AT(iobj, j);
if (!SPECIAL_CONST_P(op)) {
rb_gc_mark(op);
}
break;
}
default:
break;
}
}
}
pos += (int)size;
}
}
}
void
rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params,
VALUE exception, VALUE body)

3
iseq.c
View file

@ -336,6 +336,9 @@ rb_iseq_mark(const rb_iseq_t *iseq)
}
else if (FL_TEST_RAW(iseq, ISEQ_USE_COMPILE_DATA)) {
const struct iseq_compile_data *const compile_data = ISEQ_COMPILE_DATA(iseq);
rb_iseq_mark_insn_storage(compile_data->insn.storage_head);
if (RTEST(compile_data->mark_ary)) {
rb_gc_mark(compile_data->mark_ary);
}

1
iseq.h
View file

@ -174,6 +174,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_insn_storage(struct iseq_compile_data_storage *arena);
/* iseq.c */
VALUE rb_iseq_load(VALUE data, VALUE parent, VALUE opt);