ruby-changes:47709
From: ko1 <ko1@a...>
Date: Mon, 11 Sep 2017 00:49:51 +0900 (JST)
Subject: [ruby-changes:47709] ko1:r59825 (trunk): move th->machine to ec->machine.
ko1 2017-09-11 00:49:45 +0900 (Mon, 11 Sep 2017) New Revision: 59825 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59825 Log: move th->machine to ec->machine. * vm_core.h: move rb_thread_t::machine to rb_execution_context_t::machine. * vm_core.h, gc.c (rb_gc_mark_machine_stack): accept ec instead of th. it enables to call this func from rb_execution_context_mark() in vm.c. * cont.c (fiber_setcontext): catch up this fix. fiber_restore_thread() restores machine stack information too. * gc.c: catch up structure layout changes. * thread.c: ditto. * thread_pthread.c: ditto. * thread_win32.c: ditto. Modified files: trunk/cont.c trunk/gc.c trunk/thread.c trunk/thread_pthread.c trunk/thread_win32.c trunk/vm.c trunk/vm_core.h Index: thread_win32.c =================================================================== --- thread_win32.c (revision 59824) +++ thread_win32.c (revision 59825) @@ -546,8 +546,8 @@ native_thread_init_stack(rb_thread_t *th https://github.com/ruby/ruby/blob/trunk/thread_win32.c#L546 size = end - base; space = size / 5; if (space > 1024*1024) space = 1024*1024; - th->machine.stack_start = (VALUE *)end - 1; - th->machine.stack_maxsize = size - space; + th->ec.machine.stack_start = (VALUE *)end - 1; + th->ec.machine.stack_maxsize = size - space; } #ifndef InterlockedExchangePointer @@ -575,7 +575,7 @@ thread_start_func_1(void *th_ptr) https://github.com/ruby/ruby/blob/trunk/thread_win32.c#L575 thread_debug("thread created (th: %p, thid: %p, event: %p)\n", th, th->thread_id, th->native_thread_data.interrupt_event); - thread_start_func_2(th, th->machine.stack_start, rb_ia64_bsp()); + thread_start_func_2(th, th->ec.machine.stack_start, rb_ia64_bsp()); w32_close_handle(thread_id); thread_debug("thread deleted (th: %p)\n", th); Index: thread_pthread.c =================================================================== --- thread_pthread.c (revision 59824) +++ thread_pthread.c (revision 59825) @@ -832,8 +832,8 @@ native_thread_init_stack(rb_thread_t *th https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L832 rb_nativethread_id_t curr = pthread_self(); if (pthread_equal(curr, native_main_thread.id)) { - th->machine.stack_start = native_main_thread.stack_start; - th->machine.stack_maxsize = native_main_thread.stack_maxsize; + th->ec.machine.stack_start = native_main_thread.stack_start; + th->ec.machine.stack_maxsize = native_main_thread.stack_maxsize; } else { #ifdef STACKADDR_AVAILABLE @@ -841,11 +841,11 @@ native_thread_init_stack(rb_thread_t *th https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L841 size_t size; if (get_stack(&start, &size) == 0) { - th->machine.stack_start = start; - th->machine.stack_maxsize = size; + th->ec.machine.stack_start = start; + th->ec.machine.stack_maxsize = size; } #elif defined get_stack_of - if (!th->machine.stack_maxsize) { + if (!th->ec.machine.stack_maxsize) { native_mutex_lock(&th->interrupt_lock); native_mutex_unlock(&th->interrupt_lock); } @@ -854,9 +854,9 @@ native_thread_init_stack(rb_thread_t *th https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L854 #endif } #ifdef __ia64 - th->machine.register_stack_start = native_main_thread.register_stack_start; - th->machine.stack_maxsize /= 2; - th->machine.register_stack_maxsize = th->machine.stack_maxsize; + th->ec.machine.register_stack_start = native_main_thread.register_stack_start; + th->ec.machine.stack_maxsize /= 2; + th->ec.machine.register_stack_maxsize = th->ec.machine.stack_maxsize; #endif return 0; } @@ -884,7 +884,7 @@ thread_start_func_1(void *th_ptr) https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L884 native_thread_init(th); /* run */ #if defined USE_NATIVE_THREAD_INIT - thread_start_func_2(th, th->machine.stack_start, rb_ia64_bsp()); + thread_start_func_2(th, th->ec.machine.stack_start, rb_ia64_bsp()); #else thread_start_func_2(th, &stack_start, rb_ia64_bsp()); #endif @@ -1006,10 +1006,10 @@ native_thread_create(rb_thread_t *th) https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L1006 const size_t stack_size = th->vm->default_params.thread_machine_stack_size; const size_t space = space_size(stack_size); - th->machine.stack_maxsize = stack_size - space; + th->ec.machine.stack_maxsize = stack_size - space; #ifdef __ia64 - th->machine.stack_maxsize /= 2; - th->machine.register_stack_maxsize = th->machine.stack_maxsize; + th->ec.machine.stack_maxsize /= 2; + th->ec.machine.register_stack_maxsize = th->ec.machine.stack_maxsize; #endif #ifdef HAVE_PTHREAD_ATTR_INIT @@ -1032,8 +1032,8 @@ native_thread_create(rb_thread_t *th) https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L1032 #ifdef get_stack_of if (!err) { get_stack_of(th->thread_id, - &th->machine.stack_start, - &th->machine.stack_maxsize); + &th->ec.machine.stack_start, + &th->ec.machine.stack_maxsize); } native_mutex_unlock(&th->interrupt_lock); #endif @@ -1745,8 +1745,8 @@ ruby_stack_overflowed_p(const rb_thread_ https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L1745 else #endif if (th) { - size = th->machine.stack_maxsize; - base = (char *)th->machine.stack_start - STACK_DIR_UPPER(0, size); + size = th->ec.machine.stack_maxsize; + base = (char *)th->ec.machine.stack_start - STACK_DIR_UPPER(0, size); } else { return 0; Index: vm_core.h =================================================================== --- vm_core.h (revision 59824) +++ vm_core.h (revision 59825) @@ -767,6 +767,19 @@ typedef struct rb_execution_context_stru https://github.com/ruby/ruby/blob/trunk/vm_core.h#L767 rb_ensure_list_t *ensure_list; rb_fiber_t *fiber; + + /* for GC */ + struct { + VALUE *stack_start; + VALUE *stack_end; + size_t stack_maxsize; +#ifdef __ia64 + VALUE *register_stack_start; + VALUE *register_stack_end; + size_t register_stack_maxsize; +#endif + jmp_buf regs; + } machine; } rb_execution_context_t; typedef struct rb_thread_struct { @@ -829,19 +842,6 @@ typedef struct rb_thread_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L842 VALUE first_args; VALUE (*first_func)(ANYARGS); - /* for GC */ - struct { - VALUE *stack_start; - VALUE *stack_end; - size_t stack_maxsize; -#ifdef __ia64 - VALUE *register_stack_start; - VALUE *register_stack_end; - size_t register_stack_maxsize; -#endif - jmp_buf regs; - } machine; - /* statistics data for profiler */ VALUE stat_insn_usage; @@ -1543,7 +1543,7 @@ void rb_vm_register_special_exception_st https://github.com/ruby/ruby/blob/trunk/vm_core.h#L1543 #define rb_vm_register_special_exception(sp, e, m) \ rb_vm_register_special_exception_str(sp, e, rb_usascii_str_new_static((m), (long)rb_strlen_lit(m))) -void rb_gc_mark_machine_stack(rb_thread_t *th); +void rb_gc_mark_machine_stack(const rb_execution_context_t *ec); int rb_autoloading_value(VALUE mod, ID id, VALUE* value); Index: thread.c =================================================================== --- thread.c (revision 59824) +++ thread.c (revision 59825) @@ -138,8 +138,8 @@ static inline void blocking_region_end(r https://github.com/ruby/ruby/blob/trunk/thread.c#L138 do { \ FLUSH_REGISTER_WINDOWS; \ RB_GC_SAVE_MACHINE_REGISTER_STACK(th); \ - setjmp((th)->machine.regs); \ - SET_MACHINE_STACK_END(&(th)->machine.stack_end); \ + setjmp((th)->ec.machine.regs); \ + SET_MACHINE_STACK_END(&(th)->ec.machine.stack_end); \ } while (0) #define GVL_UNLOCK_BEGIN() do { \ @@ -525,9 +525,9 @@ thread_cleanup_func_before_exec(void *th https://github.com/ruby/ruby/blob/trunk/thread.c#L525 { rb_thread_t *th = th_ptr; th->status = THREAD_KILLED; - th->machine.stack_start = th->machine.stack_end = 0; + th->ec.machine.stack_start = th->ec.machine.stack_end = NULL; #ifdef __ia64 - th->machine.register_stack_start = th->machine.register_stack_end = 0; + th->ec.machine.register_stack_start = th->ec.machine.register_stack_end = NULL; #endif } @@ -613,9 +613,9 @@ thread_start_func_2(rb_thread_t *th, VAL https://github.com/ruby/ruby/blob/trunk/thread.c#L613 ruby_thread_set_native(th); - th->machine.stack_start = stack_start; + th->ec.machine.stack_start = stack_start; #ifdef __ia64 - th->machine.register_stack_start = register_stack_start; + th->ec.machine.register_stack_start = register_stack_start; #endif thread_debug("thread start: %p\n", (void *)th); Index: gc.c =================================================================== --- gc.c (revision 59824) +++ gc.c (revision 59825) @@ -3967,14 +3967,14 @@ init_mark_stack(mark_stack_t *stack) https://github.com/ruby/ruby/blob/trunk/gc.c#L3967 /* Marking */ #ifdef __ia64 -#define SET_STACK_END (SET_MACHINE_STACK_END(&th->machine.stack_end), th->machine.register_stack_end = rb_ia64_bsp()) +#define SET_STACK_END (SET_MACHINE_STACK_END(&ec->machine.stack_end), ec->machine.register_stack_end = rb_ia64_bsp()) #else -#define SET_STACK_END SET_MACHINE_STACK_END(&th->machine.stack_end) +#define SET_STACK_END SET_MACHINE_STACK_END(&ec->machine.stack_end) #endif -#define STACK_START (th->machine.stack_start) -#define STACK_END (th->machine.stack_end) -#define STACK_LEVEL_MAX (th->machine.stack_maxsize/sizeof(VALUE)) +#define STACK_START (ec->machine.stack_start) +#define STACK_END (ec->machine.stack_end) +#define STACK_LEVEL_MAX (ec->machine.stack_maxsize/sizeof(VALUE)) #if STACK_GROW_DIRECTION < 0 # define STACK_LENGTH (size_t)(STACK_START - STACK_END) @@ -4000,7 +4000,7 @@ ruby_get_stack_grow_direction(volatile V https://github.com/ruby/ruby/blob/trunk/gc.c#L4000 size_t ruby_stack_length(VALUE **p) { - rb_thread_t *th = GET_THREAD(); + rb_execution_context_t *ec = &GET_THREAD()->ec; SET_STACK_END; if (p) *p = STACK_UPPER(STACK_END, STACK_START, STACK_END); return STACK_LENGTH; @@ -4018,13 +4018,14 @@ ruby_stack_length(VALUE **p) https://github.com/ruby/ruby/blob/trunk/gc.c#L4018 static int stack_check(rb_thread_t *th, int water_mark) { + rb_execution_context_t *ec = &th->ec; int ret; SET_STACK_END; ret = STACK_LENGTH > STACK_LEVEL_MAX - water_mark; #ifdef __ia64 if (!ret) { - ret = (VALUE*)rb_ia64_bsp() - th->machine.register_stack_start > - th->machine.register_stack_maxsize/sizeof(VALUE) - water_mark; + ret = (VALUE*)rb_ia64_bsp() - ec->machine.register_stack_start > + ec->machine.register_stack_maxsize/sizeof(VALUE) - water_mark; } #endif return ret; @@ -4235,11 +4236,11 @@ mark_const_tbl(rb_objspace_t *objspace, https://github.com/ruby/ruby/blob/trunk/gc.c#L4236 ((start) = STACK_END, (end) = STACK_START) : ((start) = STACK_START, (end) = STACK_END+(appendix))) #endif -static void mark_stack_locations(rb_objspace_t *objspace, rb_thread_t *th, +static void mark_stack_locations(rb_objspace_t *objspace, const rb_execution_context_t *ec, const VALUE *stack_start, const VALUE *stack_end); static void -mark_current_machine_context(rb_objspace_t *objspace, rb_thread_t *th) +mark_current_machine_context(rb_objspace_t *objspace, rb_execution_context_t *ec) { union { rb_jmp_buf j; @@ -4259,29 +4260,29 @@ mark_current_machine_context(rb_objspace https://github.com/ruby/ruby/blob/trunk/gc.c#L4260 mark_locations_array(objspace, save_regs_gc_mark.v, numberof(save_regs_gc_mark.v)); - mark_stack_locations(objspace, th, stack_start, stack_end); + mark_stack_locations(objspace, ec, stack_start, stack_end); } void -rb_gc_mark_machine_stack(rb_thread_t *th) +rb_gc_mark_machine_stack(const rb_execution_context_t *ec) { - rb_objspace_t *objspace = rb_objspace_of(th->vm); + rb_objspace_t *objspace = &rb_objspace; VALUE *stack_start, *stack_end; GET_STACK_BOUNDS(stack_start, stack_end, 0); - mark_stack_locations(objspace, th, stack_start, stack_end); + mark_stack_locations(objspace, ec, stack_start, stack_end); } static void -mark_stack_locations(rb_objspace_t *objspace, rb_thread_t *th, +mark_stack_locations(rb_objspace_t *objspace, const rb_execution_context_t *ec, const VALUE *stack_start, const VALUE *stack_end) { gc_mark_locations(objspace, stack_start, stack_end); #ifdef __ia64 gc_mark_locations(objspace, - th->machine.register_stack_start, - th->machine.register_stack_end); + ec->machine.register_stack_start, + ec->machine.register_stack_end); #endif #if defined(__mc68000__) gc_mark_locations(objspace, @@ -4774,6 +4775,7 @@ gc_mark_roots(rb_objspace_t *objspace, c https://github.com/ruby/ruby/blob/trunk/gc.c#L4775 { struct gc_list *list; rb_thread_t *th = GET_THREAD(); + rb_execution_context_t *ec = &th->ec; #if PRINT_ROOT_TICKS tick_t start_tick = tick(); @@ -4820,7 +4822,7 @@ gc_mark_roots(rb_objspace_t *objspace, c https://github.com/ruby/ruby/blob/trunk/gc.c#L4822 mark_tbl(objspace, finalizer_table); MARK_CHECKPOINT("machine_context"); - mark_current_machine_context(objspace, th); + mark_current_machine_context(objspace, &th->ec); MARK_CHECKPOINT("encodings"); rb_gc_mark_encodings(); Index: cont.c =================================================================== --- cont.c (revision 59824) +++ cont.c (revision 59825) @@ -430,18 +430,18 @@ cont_save_machine_stack(rb_thread_t *th, https://github.com/ruby/ruby/blob/trunk/cont.c#L430 { size_t size; - SET_MACHINE_STACK_END(&th->machine.stack_end); + SET_MACHINE_STACK_END(&th->ec.machine.stack_end); #ifdef __ia64 th->machine.register_stack_end = rb_ia64_bsp(); #endif - if (th->machine.stack_start > th->machine.stack_end) { - size = cont->machine.stack_size = th->machine.stack_start - th->machine.stack_end; - cont->machine.stack_src = th->machine.stack_end; + if (th->ec.machine.stack_start > th->ec.machine.stack_end) { + size = cont->machine.stack_size = th->ec.machine.stack_start - th->ec.machine.stack_end; + cont->machine.stack_src = th->ec.machine.stack_end; } else { - size = cont->machine.stack_size = th->machine.stack_end - th->machine.stack_start; - cont->machine.stack_src = th->machine.stack_start; + size = cont->machine.stack_size = th->ec.machine.stack_end - th->ec.machine.stack_start; + cont->machine.stack_src = th->ec.machine.stack_start; } if (cont->machine.stack) { @@ -485,13 +485,15 @@ cont_save_thread(rb_context_t *cont, rb_ https://github.com/ruby/ruby/blob/trunk/cont.c#L485 /* save thread context */ sth->ec = th->ec; +#if FIBER_USE_NATIVE /* saved_thread->machine.stack_(start|end) should be NULL */ /* because it may happen GC afterward */ - sth->machine.stack_start = 0; - sth->machine.stack_end = 0; + sth->ec.machine.stack_start = NULL; + sth->ec.machine.stack_end = NULL; #ifdef __ia64 - sth->machine.register_stack_start = 0; - sth->machine.register_stack_end = 0; + sth->ec.machine.register_stack_start = NULL; + sth->ec.machine.register_stack_end = NULL; +#endif #endif } @@ -501,7 +503,6 @@ cont_init(rb_context_t *cont, rb_thread_ https://github.com/ruby/ruby/blob/trunk/cont.c#L503 /* save thread context */ cont_save_thread(cont, th); cont->saved_thread.self = th->self; - cont->saved_thread.machine.stack_maxsize = th->machine.stack_maxsize; cont->saved_thread.ec.local_storage = NULL; cont->saved_thread.ec.local_storage_recursive_hash = Qnil; @@ -651,7 +652,7 @@ fiber_set_stack_location(void) https://github.com/ruby/ruby/blob/trunk/cont.c#L652 VALUE *ptr; SET_MACHINE_STACK_END(&ptr); - th->machine.stack_start = (void*)(((VALUE)ptr & RB_PAGE_MASK) + STACK_UPPER((void *)&ptr, 0, RB_PAGE_SIZE)); + th->ec.machine.stack_start = (void*)(((VALUE)ptr & RB_PAGE_MASK) + STACK_UPPER((void *)&ptr, 0, RB_PAGE_SIZE)); } static VOID CALLBACK @@ -730,7 +731,7 @@ fiber_initialize_machine_stack_context(r https://github.com/ruby/ruby/blob/trunk/cont.c#L731 rb_raise(rb_eFiberError, "can't create fiber"); } } - sth->machine.stack_maxsize = size; + sth->ec.machine.stack_maxsize = size; #else /* not WIN32 */ ucontext_t *context = &fib->context; char *ptr; @@ -744,8 +745,8 @@ fiber_initialize_machine_stack_context(r https://github.com/ruby/ruby/blob/trunk/cont.c#L745 fib->ss_sp = ptr; fib->ss_size = size; makecontext(context, rb_fiber_start, 0); - sth->machine.stack_start = (VALUE*)(ptr + STACK_DIR_UPPER(0, size)); - sth->machine.stack_maxsize = size - RB_PAGE_SIZE; + sth->ec.machine.stack_start = (VALUE*)(ptr + STACK_DIR_UPPER(0, size)); + sth->ec.machine.stack_maxsize = size - RB_PAGE_SIZE; #endif #ifdef __ia64 sth->machine.register_stack_maxsize = sth->machine.stack_maxsize; @@ -757,33 +758,31 @@ NOINLINE(static void fiber_setcontext(rb https://github.com/ruby/ruby/blob/trunk/cont.c#L758 static void fiber_setcontext(rb_fiber_t *newfib, rb_fiber_t *oldfib) { - rb_thread_t *th = GET_THREAD(), *sth = &newfib->cont.saved_thread; - - /* restore thread context */ - fiber_restore_thread(th, newfib); - th->machine.stack_maxsize = sth->machine.stack_maxsize; - if (sth->machine.stack_end && (newfib != oldfib)) { - rb_bug("fiber_setcontext: sth->machine.stack_end has non zero value"); - } + rb_thread_t *th = GET_THREAD(); - /* save oldfib's machine stack */ + /* save oldfib's machine stack / TODO: is it needd? */ if (!FIBER_TERMINATED_P(oldfib)) { STACK_GROW_DIR_DETECTION; - SET_MACHINE_STACK_END(&th->machine.stack_end); + SET_MACHINE_STACK_END(&th->ec.machine.stack_end); if (STACK_DIR_UPPER(0, 1)) { - oldfib->cont.machine.stack_size = th->machine.stack_start - th->machine.stack_end; - oldfib->cont.machine.stack = th->machine.stack_end; + oldfib->cont.machine.stack_size = th->ec.machine.stack_start - th->ec.machine.stack_end; + oldfib->cont.machine.stack = th->ec.machine.stack_end; } else { - oldfib->cont.machine.stack_size = th->machine.stack_end - th->machine.stack_start; - oldfib->cont.machine.stack = th->machine.stack_start; + oldfib->cont.machine.stack_size = th->ec.machine.stack_end - th->ec.machine.stack_start; + oldfib->cont.machine.stack = th->ec.machine.stack_start; } } + /* exchange machine_stack_start between oldfib and newfib */ - oldfib->cont.saved_thread.machine.stack_start = th->machine.stack_start; - th->machine.stack_start = sth->machine.stack_start; + oldfib->cont.saved_thread.ec.machine.stack_start = th->ec.machine.stack_start; + /* oldfib->machine.stack_end should be NULL */ - oldfib->cont.saved_thread.machine.stack_end = 0; + oldfib->cont.saved_thread.ec.machine.stack_end = NULL; + + /* restore thread context */ + fiber_restore_thread(th, newfib); + #ifndef _WIN32 if (!newfib->context.uc_stack.ss_sp && th->root_fiber != newfib) { rb_bug("non_root_fiber->context.uc_stac.ss_sp should not be NULL"); @@ -1791,7 +1790,7 @@ Init_Cont(void) https://github.com/ruby/ruby/blob/trunk/cont.c#L1790 #else /* not WIN32 */ pagesize = sysconf(_SC_PAGESIZE); #endif - SET_MACHINE_STACK_END(&th->machine.stack_end); + SET_MACHINE_STACK_END(&th->ec.machine.stack_end); #endif rb_cFiber = rb_define_class("Fiber", rb_cObject); Index: vm.c =================================================================== --- vm.c (revision 59824) +++ vm.c (revision 59825) @@ -2390,6 +2390,15 @@ rb_execution_context_mark(const rb_execu https://github.com/ruby/ruby/blob/trunk/vm.c#L2390 } } + /* mark machine stack */ + if (&GET_THREAD()->ec != ec && + ec->machine.stack_start && ec->machine.stack_end) { + rb_gc_mark_machine_stack(ec); + rb_gc_mark_locations((VALUE *)&ec->machine.regs, + (VALUE *)(&ec->machine.regs) + + sizeof(ec->machine.regs) / sizeof(VALUE)); + } + RUBY_MARK_UNLESS_NULL(ec->errinfo); RUBY_MARK_UNLESS_NULL(ec->root_svar); rb_mark_tbl(ec->local_storage); @@ -2406,14 +2415,6 @@ rb_thread_mark(void *ptr) https://github.com/ruby/ruby/blob/trunk/vm.c#L2415 rb_execution_context_mark(&th->ec); - /* mark machine stack */ - if (GET_THREAD() != th && th->machine.stack_start && th->machine.stack_end) { - rb_gc_mark_machine_stack(th); - rb_gc_mark_locations((VALUE *)&th->machine.regs, - (VALUE *)(&th->machine.regs) + - sizeof(th->machine.regs) / sizeof(VALUE)); - } - /* mark ruby objects */ RUBY_MARK_UNLESS_NULL(th->first_proc); if (th->first_proc) RUBY_MARK_UNLE (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/