Add compaction support for more types.
This commit adds compaction support for: * Fibers * Continuations * Autoload Constants
This commit is contained in:
parent
c4cbaef216
commit
6db2d6d852
42
cont.c
42
cont.c
@ -339,13 +339,22 @@ cont_thread_value(const rb_context_t *cont)
|
|||||||
return cont->saved_ec.thread_ptr->self;
|
return cont->saved_ec.thread_ptr->self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cont_compact(void *ptr)
|
||||||
|
{
|
||||||
|
rb_context_t *cont = ptr;
|
||||||
|
|
||||||
|
cont->value = rb_gc_location(cont->value);
|
||||||
|
rb_execution_context_update(&cont->saved_ec);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cont_mark(void *ptr)
|
cont_mark(void *ptr)
|
||||||
{
|
{
|
||||||
rb_context_t *cont = ptr;
|
rb_context_t *cont = ptr;
|
||||||
|
|
||||||
RUBY_MARK_ENTER("cont");
|
RUBY_MARK_ENTER("cont");
|
||||||
rb_gc_mark(cont->value);
|
rb_gc_mark_no_pin(cont->value);
|
||||||
|
|
||||||
rb_execution_context_mark(&cont->saved_ec);
|
rb_execution_context_mark(&cont->saved_ec);
|
||||||
rb_gc_mark(cont_thread_value(cont));
|
rb_gc_mark(cont_thread_value(cont));
|
||||||
@ -480,24 +489,47 @@ cont_memsize(const void *ptr)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_fiber_update_self(rb_fiber_t *fib)
|
||||||
|
{
|
||||||
|
if (fib->cont.self) {
|
||||||
|
fib->cont.self = rb_gc_location(fib->cont.self);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rb_execution_context_update(&fib->cont.saved_ec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_fiber_mark_self(const rb_fiber_t *fib)
|
rb_fiber_mark_self(const rb_fiber_t *fib)
|
||||||
{
|
{
|
||||||
if (fib->cont.self) {
|
if (fib->cont.self) {
|
||||||
rb_gc_mark(fib->cont.self);
|
rb_gc_mark_no_pin(fib->cont.self);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rb_execution_context_mark(&fib->cont.saved_ec);
|
rb_execution_context_mark(&fib->cont.saved_ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fiber_compact(void *ptr)
|
||||||
|
{
|
||||||
|
rb_fiber_t *fib = ptr;
|
||||||
|
fib->first_proc = rb_gc_location(fib->first_proc);
|
||||||
|
|
||||||
|
if (fib->prev) rb_fiber_update_self(fib->prev);
|
||||||
|
|
||||||
|
cont_compact(&fib->cont);
|
||||||
|
fiber_verify(fib);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fiber_mark(void *ptr)
|
fiber_mark(void *ptr)
|
||||||
{
|
{
|
||||||
rb_fiber_t *fib = ptr;
|
rb_fiber_t *fib = ptr;
|
||||||
RUBY_MARK_ENTER("cont");
|
RUBY_MARK_ENTER("cont");
|
||||||
fiber_verify(fib);
|
fiber_verify(fib);
|
||||||
rb_gc_mark(fib->first_proc);
|
rb_gc_mark_no_pin(fib->first_proc);
|
||||||
if (fib->prev) rb_fiber_mark_self(fib->prev);
|
if (fib->prev) rb_fiber_mark_self(fib->prev);
|
||||||
|
|
||||||
#if !FIBER_USE_NATIVE
|
#if !FIBER_USE_NATIVE
|
||||||
@ -602,7 +634,7 @@ cont_save_machine_stack(rb_thread_t *th, rb_context_t *cont)
|
|||||||
|
|
||||||
static const rb_data_type_t cont_data_type = {
|
static const rb_data_type_t cont_data_type = {
|
||||||
"continuation",
|
"continuation",
|
||||||
{cont_mark, cont_free, cont_memsize,},
|
{cont_mark, cont_free, cont_memsize, cont_compact},
|
||||||
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1424,7 +1456,7 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval)
|
|||||||
|
|
||||||
static const rb_data_type_t fiber_data_type = {
|
static const rb_data_type_t fiber_data_type = {
|
||||||
"fiber",
|
"fiber",
|
||||||
{fiber_mark, fiber_free, fiber_memsize,},
|
{fiber_mark, fiber_free, fiber_memsize, fiber_compact,},
|
||||||
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
5
proc.c
5
proc.c
@ -64,7 +64,7 @@ block_mark(const struct rb_block *block)
|
|||||||
RUBY_MARK_NO_PIN_UNLESS_NULL(captured->self);
|
RUBY_MARK_NO_PIN_UNLESS_NULL(captured->self);
|
||||||
RUBY_MARK_NO_PIN_UNLESS_NULL((VALUE)captured->code.val);
|
RUBY_MARK_NO_PIN_UNLESS_NULL((VALUE)captured->code.val);
|
||||||
if (captured->ep && captured->ep[VM_ENV_DATA_INDEX_ENV] != Qundef /* cfunc_proc_t */) {
|
if (captured->ep && captured->ep[VM_ENV_DATA_INDEX_ENV] != Qundef /* cfunc_proc_t */) {
|
||||||
RUBY_MARK_UNLESS_NULL(VM_ENV_ENVVAL(captured->ep));
|
RUBY_MARK_NO_PIN_UNLESS_NULL(VM_ENV_ENVVAL(captured->ep));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -87,6 +87,9 @@ block_compact(struct rb_block *block)
|
|||||||
struct rb_captured_block *captured = &block->as.captured;
|
struct rb_captured_block *captured = &block->as.captured;
|
||||||
captured->self = rb_gc_location(captured->self);
|
captured->self = rb_gc_location(captured->self);
|
||||||
captured->code.val = rb_gc_location(captured->code.val);
|
captured->code.val = rb_gc_location(captured->code.val);
|
||||||
|
if (captured->ep && captured->ep[VM_ENV_DATA_INDEX_ENV] != Qundef /* cfunc_proc_t */) {
|
||||||
|
UPDATE_REFERENCE(captured->ep[VM_ENV_DATA_INDEX_ENV]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case block_type_symbol:
|
case block_type_symbol:
|
||||||
|
18
variable.c
18
variable.c
@ -1912,14 +1912,24 @@ static const rb_data_type_t autoload_data_i_type = {
|
|||||||
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
autoload_c_compact(void *ptr)
|
||||||
|
{
|
||||||
|
struct autoload_const *ac = ptr;
|
||||||
|
|
||||||
|
ac->mod = rb_gc_location(ac->mod);
|
||||||
|
ac->ad = rb_gc_location(ac->ad);
|
||||||
|
ac->value = rb_gc_location(ac->value);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
autoload_c_mark(void *ptr)
|
autoload_c_mark(void *ptr)
|
||||||
{
|
{
|
||||||
struct autoload_const *ac = ptr;
|
struct autoload_const *ac = ptr;
|
||||||
|
|
||||||
rb_gc_mark(ac->mod);
|
rb_gc_mark_no_pin(ac->mod);
|
||||||
rb_gc_mark(ac->ad);
|
rb_gc_mark_no_pin(ac->ad);
|
||||||
rb_gc_mark(ac->value);
|
rb_gc_mark_no_pin(ac->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1938,7 +1948,7 @@ autoload_c_memsize(const void *ptr)
|
|||||||
|
|
||||||
static const rb_data_type_t autoload_const_type = {
|
static const rb_data_type_t autoload_const_type = {
|
||||||
"autoload_const",
|
"autoload_const",
|
||||||
{autoload_c_mark, autoload_c_free, autoload_c_memsize,},
|
{autoload_c_mark, autoload_c_free, autoload_c_memsize, autoload_c_compact,},
|
||||||
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
51
vm.c
51
vm.c
@ -2475,6 +2475,36 @@ rb_thread_recycle_stack_release(VALUE *stack)
|
|||||||
ruby_xfree(stack);
|
ruby_xfree(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_execution_context_update(const rb_execution_context_t *ec)
|
||||||
|
{
|
||||||
|
/* update VM stack */
|
||||||
|
if (ec->vm_stack) {
|
||||||
|
rb_control_frame_t *cfp = ec->cfp;
|
||||||
|
rb_control_frame_t *limit_cfp = (void *)(ec->vm_stack + ec->vm_stack_size);
|
||||||
|
|
||||||
|
while (cfp != limit_cfp) {
|
||||||
|
const VALUE *ep = cfp->ep;
|
||||||
|
cfp->self = rb_gc_location(cfp->self);
|
||||||
|
cfp->iseq = (rb_iseq_t *)rb_gc_location((VALUE)cfp->iseq);
|
||||||
|
cfp->block_code = (void *)rb_gc_location((VALUE)cfp->block_code);
|
||||||
|
|
||||||
|
if (!VM_ENV_LOCAL_P(ep)) {
|
||||||
|
VALUE *prev_ep = (VALUE *)VM_ENV_PREV_EP(ep);
|
||||||
|
if (VM_ENV_FLAGS(prev_ep, VM_ENV_FLAG_ESCAPED)) {
|
||||||
|
prev_ep[VM_ENV_DATA_INDEX_ENV] = rb_gc_location(prev_ep[VM_ENV_DATA_INDEX_ENV]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if VM_CHECK_MODE > 0
|
||||||
|
void rb_ec_verify(const rb_execution_context_t *ec); /* cont.c */
|
||||||
|
rb_ec_verify(ec);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_execution_context_mark(const rb_execution_context_t *ec)
|
rb_execution_context_mark(const rb_execution_context_t *ec)
|
||||||
{
|
{
|
||||||
@ -2495,14 +2525,14 @@ rb_execution_context_mark(const rb_execution_context_t *ec)
|
|||||||
while (cfp != limit_cfp) {
|
while (cfp != limit_cfp) {
|
||||||
const VALUE *ep = cfp->ep;
|
const VALUE *ep = cfp->ep;
|
||||||
VM_ASSERT(!!VM_ENV_FLAGS(ep, VM_ENV_FLAG_ESCAPED) == vm_ep_in_heap_p_(ec, ep));
|
VM_ASSERT(!!VM_ENV_FLAGS(ep, VM_ENV_FLAG_ESCAPED) == vm_ep_in_heap_p_(ec, ep));
|
||||||
rb_gc_mark(cfp->self);
|
rb_gc_mark_no_pin(cfp->self);
|
||||||
rb_gc_mark((VALUE)cfp->iseq);
|
rb_gc_mark_no_pin((VALUE)cfp->iseq);
|
||||||
rb_gc_mark((VALUE)cfp->block_code);
|
rb_gc_mark_no_pin((VALUE)cfp->block_code);
|
||||||
|
|
||||||
if (!VM_ENV_LOCAL_P(ep)) {
|
if (!VM_ENV_LOCAL_P(ep)) {
|
||||||
const VALUE *prev_ep = VM_ENV_PREV_EP(ep);
|
const VALUE *prev_ep = VM_ENV_PREV_EP(ep);
|
||||||
if (VM_ENV_FLAGS(prev_ep, VM_ENV_FLAG_ESCAPED)) {
|
if (VM_ENV_FLAGS(prev_ep, VM_ENV_FLAG_ESCAPED)) {
|
||||||
rb_gc_mark(prev_ep[VM_ENV_DATA_INDEX_ENV]);
|
rb_gc_mark_no_pin(prev_ep[VM_ENV_DATA_INDEX_ENV]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2529,9 +2559,21 @@ rb_execution_context_mark(const rb_execution_context_t *ec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void rb_fiber_mark_self(rb_fiber_t *fib);
|
void rb_fiber_mark_self(rb_fiber_t *fib);
|
||||||
|
void rb_fiber_update_self(rb_fiber_t *fib);
|
||||||
void rb_threadptr_root_fiber_setup(rb_thread_t *th);
|
void rb_threadptr_root_fiber_setup(rb_thread_t *th);
|
||||||
void rb_threadptr_root_fiber_release(rb_thread_t *th);
|
void rb_threadptr_root_fiber_release(rb_thread_t *th);
|
||||||
|
|
||||||
|
static void
|
||||||
|
thread_compact(void *ptr)
|
||||||
|
{
|
||||||
|
rb_thread_t *th = ptr;
|
||||||
|
rb_fiber_update_self(th->ec->fiber_ptr);
|
||||||
|
|
||||||
|
if (th->root_fiber) rb_fiber_update_self(th->root_fiber);
|
||||||
|
|
||||||
|
rb_execution_context_update(th->ec);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
thread_mark(void *ptr)
|
thread_mark(void *ptr)
|
||||||
{
|
{
|
||||||
@ -2617,6 +2659,7 @@ const rb_data_type_t ruby_threadptr_data_type = {
|
|||||||
thread_mark,
|
thread_mark,
|
||||||
thread_free,
|
thread_free,
|
||||||
thread_memsize,
|
thread_memsize,
|
||||||
|
thread_compact,
|
||||||
},
|
},
|
||||||
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
||||||
};
|
};
|
||||||
|
@ -1815,6 +1815,7 @@ void rb_threadptr_unlock_all_locking_mutexes(rb_thread_t *th);
|
|||||||
void rb_threadptr_pending_interrupt_clear(rb_thread_t *th);
|
void rb_threadptr_pending_interrupt_clear(rb_thread_t *th);
|
||||||
void rb_threadptr_pending_interrupt_enque(rb_thread_t *th, VALUE v);
|
void rb_threadptr_pending_interrupt_enque(rb_thread_t *th, VALUE v);
|
||||||
void rb_ec_error_print(rb_execution_context_t * volatile ec, volatile VALUE errinfo);
|
void rb_ec_error_print(rb_execution_context_t * volatile ec, volatile VALUE errinfo);
|
||||||
|
void rb_execution_context_update(const rb_execution_context_t *ec);
|
||||||
void rb_execution_context_mark(const rb_execution_context_t *ec);
|
void rb_execution_context_mark(const rb_execution_context_t *ec);
|
||||||
void rb_fiber_close(rb_fiber_t *fib);
|
void rb_fiber_close(rb_fiber_t *fib);
|
||||||
void Init_native_thread(rb_thread_t *th);
|
void Init_native_thread(rb_thread_t *th);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user