Project

General

Profile

Feature #15095 ยป 0001-share-VM-stack-between-threads-and-fibers-if-identic.patch

normalperson (Eric Wong), 09/09/2018 07:56 AM

View differences:

cont.c
rb_context_t *cont = &fib->cont;
rb_execution_context_t *sec = &cont->saved_ec;
rb_thread_t *cth = GET_THREAD();
size_t fib_stack_size = cth->vm->default_params.fiber_vm_stack_size / sizeof(VALUE);
rb_vm_t *vm = cth->vm;
size_t fib_stack_bytes = vm->default_params.fiber_vm_stack_size;
size_t thr_stack_bytes = vm->default_params.thread_vm_stack_size;
VALUE *vm_stack;
/* initialize cont */
cont->saved_vm_stack.ptr = NULL;
ec_set_vm_stack(sec, NULL, 0);
ec_set_vm_stack(sec, ALLOC_N(VALUE, fib_stack_size), fib_stack_size);
if (fib_stack_bytes == thr_stack_bytes) {
vm_stack = rb_thread_recycle_stack(fib_stack_bytes / sizeof(VALUE));
}
else {
vm_stack = ruby_xmalloc(fib_stack_bytes);
}
ec_set_vm_stack(sec, vm_stack, fib_stack_bytes / sizeof(VALUE));
sec->cfp = (void *)(sec->vm_stack + sec->vm_stack_size);
rb_vm_push_frame(sec,
......
void
rb_fiber_close(rb_fiber_t *fib)
{
VALUE *vm_stack = fib->cont.saved_ec.vm_stack;
rb_execution_context_t *ec = &fib->cont.saved_ec;
VALUE *vm_stack = ec->vm_stack;
size_t stack_bytes = ec->vm_stack_size * sizeof(VALUE);
fiber_status_set(fib, FIBER_TERMINATED);
if (fib->cont.type == ROOT_FIBER_CONTEXT) {
rb_thread_recycle_stack_release(vm_stack);
if (stack_bytes == rb_ec_vm_ptr(ec)->default_params.thread_vm_stack_size) {
rb_thread_recycle_stack_release(vm_stack);
}
else {
ruby_xfree(vm_stack);
ruby_xfree(vm_stack);
}
ec_set_vm_stack(&fib->cont.saved_ec, NULL, 0);
ec_set_vm_stack(ec, NULL, 0);
#if !FIBER_USE_NATIVE
/* should not mark machine stack any more */
fib->cont.saved_ec.machine.stack_end = NULL;
ec->machine.stack_end = NULL;
#endif
}
internal.h
void Init_vm_objects(void);
PUREFUNC(VALUE rb_vm_top_self(void));
void rb_thread_recycle_stack_release(VALUE *);
VALUE *rb_thread_recycle_stack(size_t);
void rb_vm_change_state(void);
void rb_vm_inc_const_missing_count(void);
const void **rb_vm_get_insns_address_table(void);
vm.c
static VALUE *thread_recycle_stack_slot[RECYCLE_MAX];
static int thread_recycle_stack_count = 0;
static VALUE *
thread_recycle_stack(size_t size)
VALUE *
rb_thread_recycle_stack(size_t size)
{
if (thread_recycle_stack_count > 0) {
/* TODO: check stack size if stack sizes are variable */
......
}
#else
#define thread_recycle_stack(size) ALLOC_N(VALUE, (size))
#define rb_thread_recycle_stack(size) ALLOC_N(VALUE, (size))
#endif
void
......
/* vm_stack_size is word number.
* th->vm->default_params.thread_vm_stack_size is byte size. */
size_t size = th->vm->default_params.thread_vm_stack_size / sizeof(VALUE);
ec_set_vm_stack(th->ec, thread_recycle_stack(size), size);
ec_set_vm_stack(th->ec, rb_thread_recycle_stack(size), size);
}
th->ec->cfp = (void *)(th->ec->vm_stack + th->ec->vm_stack_size);
-
    (1-1/1)