ruby-changes:56084
From: Aaron <ko1@a...>
Date: Wed, 12 Jun 2019 01:16:45 +0900 (JST)
Subject: [ruby-changes:56084] Aaron Patterson: 6db2d6d852 (trunk): Add compaction support for more types.
https://git.ruby-lang.org/ruby.git/commit/?id=6db2d6d852 From 6db2d6d8520f88e25d97af77495eb6c879f90b21 Mon Sep 17 00:00:00 2001 From: Aaron Patterson <tenderlove@r...> Date: Fri, 31 May 2019 13:25:24 -0700 Subject: Add compaction support for more types. This commit adds compaction support for: * Fibers * Continuations * Autoload Constants diff --git a/cont.c b/cont.c index 516a847..0d091b9 100644 --- a/cont.c +++ b/cont.c @@ -340,12 +340,21 @@ cont_thread_value(const rb_context_t *cont) https://github.com/ruby/ruby/blob/trunk/cont.c#L340 } 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 cont_mark(void *ptr) { rb_context_t *cont = ptr; RUBY_MARK_ENTER("cont"); - rb_gc_mark(cont->value); + rb_gc_mark_no_pin(cont->value); rb_execution_context_mark(&cont->saved_ec); rb_gc_mark(cont_thread_value(cont)); @@ -481,10 +490,21 @@ cont_memsize(const void *ptr) https://github.com/ruby/ruby/blob/trunk/cont.c#L490 } 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 rb_fiber_mark_self(const rb_fiber_t *fib) { if (fib->cont.self) { - rb_gc_mark(fib->cont.self); + rb_gc_mark_no_pin(fib->cont.self); } else { rb_execution_context_mark(&fib->cont.saved_ec); @@ -492,12 +512,24 @@ rb_fiber_mark_self(const rb_fiber_t *fib) https://github.com/ruby/ruby/blob/trunk/cont.c#L512 } 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 fiber_mark(void *ptr) { rb_fiber_t *fib = ptr; RUBY_MARK_ENTER("cont"); 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 !FIBER_USE_NATIVE @@ -602,7 +634,7 @@ cont_save_machine_stack(rb_thread_t *th, rb_context_t *cont) https://github.com/ruby/ruby/blob/trunk/cont.c#L634 static const rb_data_type_t cont_data_type = { "continuation", - {cont_mark, cont_free, cont_memsize,}, + {cont_mark, cont_free, cont_memsize, cont_compact}, 0, 0, RUBY_TYPED_FREE_IMMEDIATELY }; @@ -1424,7 +1456,7 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval) https://github.com/ruby/ruby/blob/trunk/cont.c#L1456 static const rb_data_type_t fiber_data_type = { "fiber", - {fiber_mark, fiber_free, fiber_memsize,}, + {fiber_mark, fiber_free, fiber_memsize, fiber_compact,}, 0, 0, RUBY_TYPED_FREE_IMMEDIATELY }; diff --git a/proc.c b/proc.c index de60a8c..8372979 100644 --- a/proc.c +++ b/proc.c @@ -64,7 +64,7 @@ block_mark(const struct rb_block *block) https://github.com/ruby/ruby/blob/trunk/proc.c#L64 RUBY_MARK_NO_PIN_UNLESS_NULL(captured->self); RUBY_MARK_NO_PIN_UNLESS_NULL((VALUE)captured->code.val); 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; @@ -87,6 +87,9 @@ block_compact(struct rb_block *block) https://github.com/ruby/ruby/blob/trunk/proc.c#L87 struct rb_captured_block *captured = &block->as.captured; captured->self = rb_gc_location(captured->self); 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; case block_type_symbol: diff --git a/variable.c b/variable.c index ebfdf0d..be0eee1 100644 --- a/variable.c +++ b/variable.c @@ -1913,13 +1913,23 @@ static const rb_data_type_t autoload_data_i_type = { https://github.com/ruby/ruby/blob/trunk/variable.c#L1913 }; 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 autoload_c_mark(void *ptr) { struct autoload_const *ac = ptr; - rb_gc_mark(ac->mod); - rb_gc_mark(ac->ad); - rb_gc_mark(ac->value); + rb_gc_mark_no_pin(ac->mod); + rb_gc_mark_no_pin(ac->ad); + rb_gc_mark_no_pin(ac->value); } static void @@ -1938,7 +1948,7 @@ autoload_c_memsize(const void *ptr) https://github.com/ruby/ruby/blob/trunk/variable.c#L1948 static const rb_data_type_t autoload_const_type = { "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 }; diff --git a/vm.c b/vm.c index 70ec231..ce8853b 100644 --- a/vm.c +++ b/vm.c @@ -2476,6 +2476,36 @@ rb_thread_recycle_stack_release(VALUE *stack) https://github.com/ruby/ruby/blob/trunk/vm.c#L2476 } 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 rb_execution_context_mark(const rb_execution_context_t *ec) { #if VM_CHECK_MODE > 0 @@ -2495,14 +2525,14 @@ rb_execution_context_mark(const rb_execution_context_t *ec) https://github.com/ruby/ruby/blob/trunk/vm.c#L2525 while (cfp != limit_cfp) { const VALUE *ep = cfp->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((VALUE)cfp->iseq); - rb_gc_mark((VALUE)cfp->block_code); + rb_gc_mark_no_pin(cfp->self); + rb_gc_mark_no_pin((VALUE)cfp->iseq); + rb_gc_mark_no_pin((VALUE)cfp->block_code); if (!VM_ENV_LOCAL_P(ep)) { const VALUE *prev_ep = VM_ENV_PREV_EP(ep); 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,10 +2559,22 @@ rb_execution_context_mark(const rb_execution_context_t *ec) https://github.com/ruby/ruby/blob/trunk/vm.c#L2559 } 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_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 thread_mark(void *ptr) { rb_thread_t *th = ptr; @@ -2617,6 +2659,7 @@ const rb_data_type_t ruby_threadptr_data_type = { https://github.com/ruby/ruby/blob/trunk/vm.c#L2659 thread_mark, thread_free, thread_memsize, + thread_compact, }, 0, 0, RUBY_TYPED_FREE_IMMEDIATELY }; diff --git a/vm_core.h b/vm_core.h index 95cd2d8..a0f9388 100644 --- a/vm_core.h +++ b/vm_core.h @@ -1815,6 +1815,7 @@ void rb_threadptr_unlock_all_locking_mutexes(rb_thread_t *th); https://github.com/ruby/ruby/blob/trunk/vm_core.h#L1815 void rb_threadptr_pending_interrupt_clear(rb_thread_t *th); 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_execution_context_update(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 Init_native_thread(rb_thread_t *th); -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/