Use rb_gc_mark_and_move for imemo
This commit is contained in:
parent
20f03100d5
commit
c184aa8740
271
gc.c
271
gc.c
@ -4710,6 +4710,14 @@ is_live_object(rb_objspace_t *objspace, VALUE ptr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
moved_or_living_object_strictly_p(rb_objspace_t *objspace, VALUE obj)
|
||||||
|
{
|
||||||
|
return obj &&
|
||||||
|
is_pointer_to_heap(objspace, (void *)obj) &&
|
||||||
|
(is_live_object(objspace, obj) || BUILTIN_TYPE(obj) == T_MOVED);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
is_markable_object(VALUE obj)
|
is_markable_object(VALUE obj)
|
||||||
{
|
{
|
||||||
@ -6675,38 +6683,44 @@ rb_mark_hash(st_table *tbl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mark_method_entry(rb_objspace_t *objspace, const rb_method_entry_t *me)
|
mark_and_move_method_entry(rb_objspace_t *objspace, rb_method_entry_t *me, bool reference_updating)
|
||||||
{
|
{
|
||||||
const rb_method_definition_t *def = me->def;
|
rb_method_definition_t *def = me->def;
|
||||||
|
|
||||||
gc_mark(objspace, me->owner);
|
rb_gc_mark_and_move(&me->owner);
|
||||||
gc_mark(objspace, me->defined_class);
|
rb_gc_mark_and_move(&me->defined_class);
|
||||||
|
|
||||||
if (def) {
|
if (def) {
|
||||||
switch (def->type) {
|
switch (def->type) {
|
||||||
case VM_METHOD_TYPE_ISEQ:
|
case VM_METHOD_TYPE_ISEQ:
|
||||||
if (def->body.iseq.iseqptr) gc_mark(objspace, (VALUE)def->body.iseq.iseqptr);
|
if (def->body.iseq.iseqptr) {
|
||||||
gc_mark(objspace, (VALUE)def->body.iseq.cref);
|
rb_gc_mark_and_move_ptr(&def->body.iseq.iseqptr);
|
||||||
|
}
|
||||||
|
rb_gc_mark_and_move_ptr(&def->body.iseq.cref);
|
||||||
|
|
||||||
if (def->iseq_overload && me->defined_class) {
|
if (!reference_updating) {
|
||||||
// it can be a key of "overloaded_cme" table
|
if (def->iseq_overload && me->defined_class) {
|
||||||
// so it should be pinned.
|
// it can be a key of "overloaded_cme" table
|
||||||
gc_mark_and_pin(objspace, (VALUE)me);
|
// so it should be pinned.
|
||||||
|
gc_mark_and_pin(objspace, (VALUE)me);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VM_METHOD_TYPE_ATTRSET:
|
case VM_METHOD_TYPE_ATTRSET:
|
||||||
case VM_METHOD_TYPE_IVAR:
|
case VM_METHOD_TYPE_IVAR:
|
||||||
gc_mark(objspace, def->body.attr.location);
|
rb_gc_mark_and_move(&def->body.attr.location);
|
||||||
break;
|
break;
|
||||||
case VM_METHOD_TYPE_BMETHOD:
|
case VM_METHOD_TYPE_BMETHOD:
|
||||||
gc_mark(objspace, def->body.bmethod.proc);
|
rb_gc_mark_and_move(&def->body.bmethod.proc);
|
||||||
if (def->body.bmethod.hooks) rb_hook_list_mark(def->body.bmethod.hooks);
|
if (!reference_updating) {
|
||||||
|
if (def->body.bmethod.hooks) rb_hook_list_mark(def->body.bmethod.hooks);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case VM_METHOD_TYPE_ALIAS:
|
case VM_METHOD_TYPE_ALIAS:
|
||||||
gc_mark(objspace, (VALUE)def->body.alias.original_me);
|
rb_gc_mark_and_move_ptr(&def->body.alias.original_me);
|
||||||
return;
|
return;
|
||||||
case VM_METHOD_TYPE_REFINED:
|
case VM_METHOD_TYPE_REFINED:
|
||||||
gc_mark(objspace, (VALUE)def->body.refined.orig_me);
|
rb_gc_mark_and_move_ptr(&def->body.refined.orig_me);
|
||||||
break;
|
break;
|
||||||
case VM_METHOD_TYPE_CFUNC:
|
case VM_METHOD_TYPE_CFUNC:
|
||||||
case VM_METHOD_TYPE_ZSUPER:
|
case VM_METHOD_TYPE_ZSUPER:
|
||||||
@ -7189,65 +7203,80 @@ gc_mark_set_parent(rb_objspace_t *objspace, VALUE obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gc_mark_imemo(rb_objspace_t *objspace, VALUE obj)
|
gc_mark_and_move_imemo(rb_objspace_t *objspace, VALUE obj, bool reference_updating)
|
||||||
{
|
{
|
||||||
switch (imemo_type(obj)) {
|
switch (imemo_type(obj)) {
|
||||||
case imemo_env:
|
case imemo_env:
|
||||||
{
|
{
|
||||||
const rb_env_t *env = (const rb_env_t *)obj;
|
rb_env_t *env = (rb_env_t *)obj;
|
||||||
|
|
||||||
if (LIKELY(env->ep)) {
|
if (LIKELY(env->ep)) {
|
||||||
// just after newobj() can be NULL here.
|
// just after newobj() can be NULL here.
|
||||||
GC_ASSERT(env->ep[VM_ENV_DATA_INDEX_ENV] == obj);
|
GC_ASSERT(rb_gc_location(env->ep[VM_ENV_DATA_INDEX_ENV]) == rb_gc_location(obj));
|
||||||
GC_ASSERT(VM_ENV_ESCAPED_P(env->ep));
|
GC_ASSERT(reference_updating || VM_ENV_ESCAPED_P(env->ep));
|
||||||
rb_gc_mark_values((long)env->env_size, env->env);
|
|
||||||
VM_ENV_FLAGS_SET(env->ep, VM_ENV_FLAG_WB_REQUIRED);
|
for (unsigned int i = 0; i < env->env_size; i++) {
|
||||||
gc_mark(objspace, (VALUE)rb_vm_env_prev_env(env));
|
rb_gc_mark_and_move((VALUE *)&env->env[i]);
|
||||||
gc_mark(objspace, (VALUE)env->iseq);
|
}
|
||||||
|
|
||||||
|
rb_gc_mark_and_move_ptr(&env->iseq);
|
||||||
|
|
||||||
|
if (reference_updating) {
|
||||||
|
UPDATE_IF_MOVED(objspace, env->ep[VM_ENV_DATA_INDEX_ENV]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
VM_ENV_FLAGS_SET(env->ep, VM_ENV_FLAG_WB_REQUIRED);
|
||||||
|
gc_mark(objspace, (VALUE)rb_vm_env_prev_env(env));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case imemo_cref:
|
case imemo_cref:
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.cref.klass_or_self);
|
rb_gc_mark_and_move(&RANY(obj)->as.imemo.cref.klass_or_self);
|
||||||
gc_mark(objspace, (VALUE)RANY(obj)->as.imemo.cref.next);
|
rb_gc_mark_and_move_ptr(&RANY(obj)->as.imemo.cref.next);
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.cref.refinements);
|
rb_gc_mark_and_move(&RANY(obj)->as.imemo.cref.refinements);
|
||||||
return;
|
return;
|
||||||
case imemo_svar:
|
case imemo_svar:
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.svar.cref_or_me);
|
rb_gc_mark_and_move((VALUE *)&RANY(obj)->as.imemo.svar.cref_or_me);
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.svar.lastline);
|
rb_gc_mark_and_move((VALUE *)&RANY(obj)->as.imemo.svar.lastline);
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.svar.backref);
|
rb_gc_mark_and_move((VALUE *)&RANY(obj)->as.imemo.svar.backref);
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.svar.others);
|
rb_gc_mark_and_move((VALUE *)&RANY(obj)->as.imemo.svar.others);
|
||||||
return;
|
return;
|
||||||
case imemo_throw_data:
|
case imemo_throw_data:
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.throw_data.throw_obj);
|
rb_gc_mark_and_move((VALUE *)&RANY(obj)->as.imemo.throw_data.throw_obj);
|
||||||
return;
|
return;
|
||||||
case imemo_ifunc:
|
case imemo_ifunc:
|
||||||
gc_mark_maybe(objspace, (VALUE)RANY(obj)->as.imemo.ifunc.data);
|
if (!reference_updating) {
|
||||||
|
gc_mark_maybe(objspace, (VALUE)RANY(obj)->as.imemo.ifunc.data);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case imemo_memo:
|
case imemo_memo:
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.memo.v1);
|
rb_gc_mark_and_move((VALUE *)&RANY(obj)->as.imemo.memo.v1);
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.memo.v2);
|
rb_gc_mark_and_move((VALUE *)&RANY(obj)->as.imemo.memo.v2);
|
||||||
gc_mark_maybe(objspace, RANY(obj)->as.imemo.memo.u3.value);
|
if (!reference_updating) {
|
||||||
|
gc_mark_maybe(objspace, RANY(obj)->as.imemo.memo.u3.value);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case imemo_ment:
|
case imemo_ment:
|
||||||
mark_method_entry(objspace, &RANY(obj)->as.imemo.ment);
|
mark_and_move_method_entry(objspace, &RANY(obj)->as.imemo.ment, reference_updating);
|
||||||
return;
|
return;
|
||||||
case imemo_iseq:
|
case imemo_iseq:
|
||||||
rb_iseq_mark_and_move((rb_iseq_t *)obj, false);
|
rb_iseq_mark_and_move((rb_iseq_t *)obj, reference_updating);
|
||||||
return;
|
return;
|
||||||
case imemo_tmpbuf:
|
case imemo_tmpbuf:
|
||||||
{
|
{
|
||||||
const rb_imemo_tmpbuf_t *m = &RANY(obj)->as.imemo.alloc;
|
if (!reference_updating) {
|
||||||
do {
|
const rb_imemo_tmpbuf_t *m = &RANY(obj)->as.imemo.alloc;
|
||||||
rb_gc_mark_locations(m->ptr, m->ptr + m->cnt);
|
do {
|
||||||
} while ((m = m->next) != NULL);
|
rb_gc_mark_locations(m->ptr, m->ptr + m->cnt);
|
||||||
|
} while ((m = m->next) != NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case imemo_ast:
|
case imemo_ast:
|
||||||
rb_ast_mark(&RANY(obj)->as.imemo.ast);
|
rb_ast_mark_and_move(&RANY(obj)->as.imemo.ast, reference_updating);
|
||||||
return;
|
return;
|
||||||
case imemo_parser_strterm:
|
case imemo_parser_strterm:
|
||||||
return;
|
|
||||||
case imemo_callinfo:
|
case imemo_callinfo:
|
||||||
return;
|
return;
|
||||||
case imemo_callcache:
|
case imemo_callcache:
|
||||||
@ -7272,15 +7301,32 @@ gc_mark_imemo(rb_objspace_t *objspace, VALUE obj)
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
const struct rb_callcache *cc = (const struct rb_callcache *)obj;
|
const struct rb_callcache *cc = (const struct rb_callcache *)obj;
|
||||||
if (vm_cc_super_p(cc) || vm_cc_refinement_p(cc)) {
|
if (reference_updating) {
|
||||||
gc_mark(objspace, (VALUE)cc->cme_);
|
if (!cc->klass) {
|
||||||
|
// already invalidated
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (moved_or_living_object_strictly_p(objspace, cc->klass) &&
|
||||||
|
moved_or_living_object_strictly_p(objspace, (VALUE)cc->cme_)) {
|
||||||
|
UPDATE_IF_MOVED(objspace, cc->klass);
|
||||||
|
TYPED_UPDATE_IF_MOVED(objspace, struct rb_callable_method_entry_struct *, cc->cme_);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vm_cc_invalidate(cc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (vm_cc_super_p(cc) || vm_cc_refinement_p(cc)) {
|
||||||
|
gc_mark(objspace, (VALUE)cc->cme_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case imemo_constcache:
|
case imemo_constcache:
|
||||||
{
|
{
|
||||||
const struct iseq_inline_constant_cache_entry *ice = (struct iseq_inline_constant_cache_entry *)obj;
|
struct iseq_inline_constant_cache_entry *ice = (struct iseq_inline_constant_cache_entry *)obj;
|
||||||
gc_mark(objspace, ice->value);
|
rb_gc_mark_and_move(&ice->value);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
#if VM_CHECK_MODE > 0
|
#if VM_CHECK_MODE > 0
|
||||||
@ -7328,7 +7374,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case T_IMEMO:
|
case T_IMEMO:
|
||||||
gc_mark_imemo(objspace, obj);
|
gc_mark_and_move_imemo(objspace, obj, false);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -10359,46 +10405,6 @@ gc_ref_update_hash(rb_objspace_t * objspace, VALUE v)
|
|||||||
rb_hash_stlike_foreach_with_replace(v, hash_foreach_replace, hash_replace_ref, (st_data_t)objspace);
|
rb_hash_stlike_foreach_with_replace(v, hash_foreach_replace, hash_replace_ref, (st_data_t)objspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gc_ref_update_method_entry(rb_objspace_t *objspace, rb_method_entry_t *me)
|
|
||||||
{
|
|
||||||
rb_method_definition_t *def = me->def;
|
|
||||||
|
|
||||||
UPDATE_IF_MOVED(objspace, me->owner);
|
|
||||||
UPDATE_IF_MOVED(objspace, me->defined_class);
|
|
||||||
|
|
||||||
if (def) {
|
|
||||||
switch (def->type) {
|
|
||||||
case VM_METHOD_TYPE_ISEQ:
|
|
||||||
if (def->body.iseq.iseqptr) {
|
|
||||||
TYPED_UPDATE_IF_MOVED(objspace, rb_iseq_t *, def->body.iseq.iseqptr);
|
|
||||||
}
|
|
||||||
TYPED_UPDATE_IF_MOVED(objspace, rb_cref_t *, def->body.iseq.cref);
|
|
||||||
break;
|
|
||||||
case VM_METHOD_TYPE_ATTRSET:
|
|
||||||
case VM_METHOD_TYPE_IVAR:
|
|
||||||
UPDATE_IF_MOVED(objspace, def->body.attr.location);
|
|
||||||
break;
|
|
||||||
case VM_METHOD_TYPE_BMETHOD:
|
|
||||||
UPDATE_IF_MOVED(objspace, def->body.bmethod.proc);
|
|
||||||
break;
|
|
||||||
case VM_METHOD_TYPE_ALIAS:
|
|
||||||
TYPED_UPDATE_IF_MOVED(objspace, struct rb_method_entry_struct *, def->body.alias.original_me);
|
|
||||||
return;
|
|
||||||
case VM_METHOD_TYPE_REFINED:
|
|
||||||
TYPED_UPDATE_IF_MOVED(objspace, struct rb_method_entry_struct *, def->body.refined.orig_me);
|
|
||||||
break;
|
|
||||||
case VM_METHOD_TYPE_CFUNC:
|
|
||||||
case VM_METHOD_TYPE_ZSUPER:
|
|
||||||
case VM_METHOD_TYPE_MISSING:
|
|
||||||
case VM_METHOD_TYPE_OPTIMIZED:
|
|
||||||
case VM_METHOD_TYPE_UNDEF:
|
|
||||||
case VM_METHOD_TYPE_NOTIMPLEMENTED:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gc_update_values(rb_objspace_t *objspace, long n, VALUE *values)
|
gc_update_values(rb_objspace_t *objspace, long n, VALUE *values)
|
||||||
{
|
{
|
||||||
@ -10415,93 +10421,6 @@ rb_gc_update_values(long n, VALUE *values)
|
|||||||
gc_update_values(&rb_objspace, n, values);
|
gc_update_values(&rb_objspace, n, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
moved_or_living_object_strictly_p(rb_objspace_t *objspace, VALUE obj)
|
|
||||||
{
|
|
||||||
return obj &&
|
|
||||||
is_pointer_to_heap(objspace, (void *)obj) &&
|
|
||||||
(is_live_object(objspace, obj) || BUILTIN_TYPE(obj) == T_MOVED);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gc_ref_update_imemo(rb_objspace_t *objspace, VALUE obj)
|
|
||||||
{
|
|
||||||
switch (imemo_type(obj)) {
|
|
||||||
case imemo_env:
|
|
||||||
{
|
|
||||||
rb_env_t *env = (rb_env_t *)obj;
|
|
||||||
if (LIKELY(env->ep)) {
|
|
||||||
// just after newobj() can be NULL here.
|
|
||||||
TYPED_UPDATE_IF_MOVED(objspace, rb_iseq_t *, env->iseq);
|
|
||||||
UPDATE_IF_MOVED(objspace, env->ep[VM_ENV_DATA_INDEX_ENV]);
|
|
||||||
gc_update_values(objspace, (long)env->env_size, (VALUE *)env->env);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case imemo_cref:
|
|
||||||
UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.cref.klass_or_self);
|
|
||||||
TYPED_UPDATE_IF_MOVED(objspace, struct rb_cref_struct *, RANY(obj)->as.imemo.cref.next);
|
|
||||||
UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.cref.refinements);
|
|
||||||
break;
|
|
||||||
case imemo_svar:
|
|
||||||
UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.svar.cref_or_me);
|
|
||||||
UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.svar.lastline);
|
|
||||||
UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.svar.backref);
|
|
||||||
UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.svar.others);
|
|
||||||
break;
|
|
||||||
case imemo_throw_data:
|
|
||||||
UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.throw_data.throw_obj);
|
|
||||||
break;
|
|
||||||
case imemo_ifunc:
|
|
||||||
break;
|
|
||||||
case imemo_memo:
|
|
||||||
UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.memo.v1);
|
|
||||||
UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.memo.v2);
|
|
||||||
break;
|
|
||||||
case imemo_ment:
|
|
||||||
gc_ref_update_method_entry(objspace, &RANY(obj)->as.imemo.ment);
|
|
||||||
break;
|
|
||||||
case imemo_iseq:
|
|
||||||
rb_iseq_mark_and_move((rb_iseq_t *)obj, true);
|
|
||||||
break;
|
|
||||||
case imemo_ast:
|
|
||||||
rb_ast_update_references((rb_ast_t *)obj);
|
|
||||||
break;
|
|
||||||
case imemo_callcache:
|
|
||||||
{
|
|
||||||
const struct rb_callcache *cc = (const struct rb_callcache *)obj;
|
|
||||||
|
|
||||||
if (!cc->klass) {
|
|
||||||
// already invalidated
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (moved_or_living_object_strictly_p(objspace, cc->klass) &&
|
|
||||||
moved_or_living_object_strictly_p(objspace, (VALUE)cc->cme_)) {
|
|
||||||
UPDATE_IF_MOVED(objspace, cc->klass);
|
|
||||||
TYPED_UPDATE_IF_MOVED(objspace, struct rb_callable_method_entry_struct *, cc->cme_);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
vm_cc_invalidate(cc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case imemo_constcache:
|
|
||||||
{
|
|
||||||
const struct iseq_inline_constant_cache_entry *ice = (struct iseq_inline_constant_cache_entry *)obj;
|
|
||||||
UPDATE_IF_MOVED(objspace, ice->value);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case imemo_parser_strterm:
|
|
||||||
case imemo_tmpbuf:
|
|
||||||
case imemo_callinfo:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
rb_bug("not reachable %d", imemo_type(obj));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum rb_id_table_iterator_result
|
static enum rb_id_table_iterator_result
|
||||||
check_id_table_move(VALUE value, void *data)
|
check_id_table_move(VALUE value, void *data)
|
||||||
{
|
{
|
||||||
@ -10754,7 +10673,7 @@ gc_update_object_references(rb_objspace_t *objspace, VALUE obj)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case T_IMEMO:
|
case T_IMEMO:
|
||||||
gc_ref_update_imemo(objspace, obj);
|
gc_mark_and_move_imemo(objspace, obj, true);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case T_NIL:
|
case T_NIL:
|
||||||
|
44
node.c
44
node.c
@ -86,7 +86,7 @@ rb_node_buffer_new(void)
|
|||||||
#define ruby_xrealloc(var,size) (ast->node_buffer->config->realloc_n((void *)var, 1, size))
|
#define ruby_xrealloc(var,size) (ast->node_buffer->config->realloc_n((void *)var, 1, size))
|
||||||
#define rb_gc_mark ast->node_buffer->config->gc_mark
|
#define rb_gc_mark ast->node_buffer->config->gc_mark
|
||||||
#define rb_gc_location ast->node_buffer->config->gc_location
|
#define rb_gc_location ast->node_buffer->config->gc_location
|
||||||
#define rb_gc_mark_movable ast->node_buffer->config->gc_mark_movable
|
#define rb_gc_mark_and_move ast->node_buffer->config->gc_mark_and_move
|
||||||
#undef Qnil
|
#undef Qnil
|
||||||
#define Qnil ast->node_buffer->config->qnil
|
#define Qnil ast->node_buffer->config->qnil
|
||||||
#define Qtrue ast->node_buffer->config->qtrue
|
#define Qtrue ast->node_buffer->config->qtrue
|
||||||
@ -367,7 +367,7 @@ iterate_node_values(rb_ast_t *ast, node_buffer_list_t *nb, node_itr_t * func, vo
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mark_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
|
mark_and_move_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
|
||||||
{
|
{
|
||||||
#ifdef UNIVERSAL_PARSER
|
#ifdef UNIVERSAL_PARSER
|
||||||
bug_report_func rb_bug = ast->node_buffer->config->bug;
|
bug_report_func rb_bug = ast->node_buffer->config->bug;
|
||||||
@ -376,53 +376,23 @@ mark_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
|
|||||||
switch (nd_type(node)) {
|
switch (nd_type(node)) {
|
||||||
case NODE_MATCH:
|
case NODE_MATCH:
|
||||||
case NODE_LIT:
|
case NODE_LIT:
|
||||||
rb_gc_mark_movable(RNODE_LIT(node)->nd_lit);
|
rb_gc_mark_and_move(&RNODE_LIT(node)->nd_lit);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
rb_bug("unreachable node %s", ruby_node_name(nd_type(node)));
|
rb_bug("unreachable node %s", ruby_node_name(nd_type(node)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
update_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
|
|
||||||
{
|
|
||||||
#ifdef UNIVERSAL_PARSER
|
|
||||||
bug_report_func rb_bug = ast->node_buffer->config->bug;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (nd_type(node)) {
|
|
||||||
case NODE_MATCH:
|
|
||||||
case NODE_LIT:
|
|
||||||
RNODE_LIT(node)->nd_lit = rb_gc_location(RNODE_LIT(node)->nd_lit);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
rb_bug("unreachable");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_ast_update_references(rb_ast_t *ast)
|
rb_ast_mark_and_move(rb_ast_t *ast, bool reference_updating)
|
||||||
{
|
{
|
||||||
if (ast->node_buffer) {
|
if (ast->node_buffer) {
|
||||||
ast->node_buffer->tokens = rb_gc_location(ast->node_buffer->tokens);
|
rb_gc_mark_and_move(&ast->node_buffer->tokens);
|
||||||
|
|
||||||
node_buffer_t *nb = ast->node_buffer;
|
node_buffer_t *nb = ast->node_buffer;
|
||||||
iterate_node_values(ast, &nb->markable, update_ast_value, NULL);
|
iterate_node_values(ast, &nb->markable, mark_and_move_ast_value, NULL);
|
||||||
|
|
||||||
if (ast->body.script_lines) ast->body.script_lines = rb_gc_location(ast->body.script_lines);
|
if (ast->body.script_lines) rb_gc_mark_and_move(&ast->body.script_lines);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rb_ast_mark(rb_ast_t *ast)
|
|
||||||
{
|
|
||||||
if (ast->node_buffer) {
|
|
||||||
rb_gc_mark_movable(ast->node_buffer->tokens);
|
|
||||||
|
|
||||||
node_buffer_t *nb = ast->node_buffer;
|
|
||||||
iterate_node_values(ast, &nb->markable, mark_ast_value, NULL);
|
|
||||||
|
|
||||||
if (ast->body.script_lines) rb_gc_mark_movable(ast->body.script_lines);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
node.h
2
node.h
@ -62,7 +62,7 @@ void rb_ast_node_type_change(NODE *n, enum node_type type);
|
|||||||
const char *ruby_node_name(int node);
|
const char *ruby_node_name(int node);
|
||||||
void rb_node_init(NODE *n, enum node_type type);
|
void rb_node_init(NODE *n, enum node_type type);
|
||||||
|
|
||||||
void rb_ast_mark(rb_ast_t*);
|
void rb_ast_mark_and_move(rb_ast_t *ast, bool reference_updating);
|
||||||
void rb_ast_update_references(rb_ast_t*);
|
void rb_ast_update_references(rb_ast_t*);
|
||||||
void rb_ast_free(rb_ast_t*);
|
void rb_ast_free(rb_ast_t*);
|
||||||
void rb_ast_set_tokens(rb_ast_t*, VALUE);
|
void rb_ast_set_tokens(rb_ast_t*, VALUE);
|
||||||
|
@ -640,7 +640,7 @@ static const rb_parser_config_t rb_global_parser_config = {
|
|||||||
.gc_register_mark_object = rb_gc_register_mark_object,
|
.gc_register_mark_object = rb_gc_register_mark_object,
|
||||||
.gc_guard = gc_guard,
|
.gc_guard = gc_guard,
|
||||||
.gc_mark = rb_gc_mark,
|
.gc_mark = rb_gc_mark,
|
||||||
.gc_mark_movable = rb_gc_mark_movable,
|
.gc_mark_and_move = rb_gc_mark_and_move,
|
||||||
.gc_location = rb_gc_location,
|
.gc_location = rb_gc_location,
|
||||||
|
|
||||||
.reg_compile = rb_reg_compile,
|
.reg_compile = rb_reg_compile,
|
||||||
|
@ -1366,7 +1366,7 @@ typedef struct rb_parser_config_struct {
|
|||||||
void (*gc_register_mark_object)(VALUE object);
|
void (*gc_register_mark_object)(VALUE object);
|
||||||
void (*gc_guard)(VALUE);
|
void (*gc_guard)(VALUE);
|
||||||
void (*gc_mark)(VALUE);
|
void (*gc_mark)(VALUE);
|
||||||
void (*gc_mark_movable)(VALUE ptr);
|
void (*gc_mark_and_move)(VALUE *ptr);
|
||||||
VALUE (*gc_location)(VALUE value);
|
VALUE (*gc_location)(VALUE value);
|
||||||
|
|
||||||
/* Re */
|
/* Re */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user