diff options
author | Aaron Patterson <tenderlove@ruby-lang.org> | 2019-05-31 13:25:24 -0700 |
---|---|---|
committer | Aaron Patterson <tenderlove@ruby-lang.org> | 2019-06-11 09:16:14 -0700 |
commit | 6db2d6d8520f88e25d97af77495eb6c879f90b21 (patch) | |
tree | 25c42ae8e1a14a019a37401d65ad32f10aa506c6 /vm.c | |
parent | c4cbaef216ffcc9bda70cc328a805ad679ccaa8c (diff) | |
download | ruby-6db2d6d8520f88e25d97af77495eb6c879f90b21.tar.gz |
Add compaction support for more types.
This commit adds compaction support for:
* Fibers
* Continuations
* Autoload Constants
Diffstat (limited to 'vm.c')
-rw-r--r-- | vm.c | 51 |
1 files changed, 47 insertions, 4 deletions
@@ -2476,6 +2476,36 @@ rb_thread_recycle_stack_release(VALUE *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 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) 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) } 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 = { thread_mark, thread_free, thread_memsize, + thread_compact, }, 0, 0, RUBY_TYPED_FREE_IMMEDIATELY }; |