diff options
-rw-r--r-- | ChangeLog | 30 | ||||
-rw-r--r-- | cont.c | 150 | ||||
-rw-r--r-- | gc.c | 18 | ||||
-rw-r--r-- | test/ruby/test_exception.rb | 11 | ||||
-rw-r--r-- | thread.c | 14 | ||||
-rw-r--r-- | thread_pthread.c | 87 | ||||
-rw-r--r-- | thread_win32.c | 6 | ||||
-rw-r--r-- | version.h | 8 | ||||
-rw-r--r-- | vm.c | 8 | ||||
-rw-r--r-- | vm_core.h | 16 |
10 files changed, 210 insertions, 138 deletions
@@ -1,3 +1,33 @@ +Thu Jul 3 13:23:31 2014 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * thread_pthread.c (ruby_init_stack, ruby_stack_overflowed_p): + place get_stack above others to get stack boundary information. + [ruby-core:60113] [Bug #9454] + +Thu Jul 3 13:23:31 2014 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * thread_pthread.c (ruby_init_stack, ruby_stack_overflowed_p): + place get_stack above others to get stack boundary information. + [ruby-core:60113] [Bug #9454] + +Thu Jul 3 13:23:31 2014 NARUSE, Yui <naruse@ruby-lang.org> + + * thread_pthread.c: rlimit is only available on Linux. + At least r44712 breaks FreeBSD. + [ruby-core:60113] [Bug #9454] + +Thu Jul 3 13:23:31 2014 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * thread_pthread.c: get current main thread stack size, which may + be expanded than allocated size at initialization, by rlimit(). + [ruby-core:60113] [Bug #9454] + +Thu Jul 3 13:23:31 2014 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * thread_pthread.c: get current main thread stack size, which may + be expanded than allocated size at initialization, by rlimit(). + [ruby-core:60113] [Bug #9454] + Fri Jun 27 17:57:16 2014 Nobuyoshi Nakada <nobu@ruby-lang.org> * string.c (rb_str_substr): need to reset code range for shared @@ -97,16 +97,18 @@ typedef struct rb_context_struct { size_t vm_stack_slen; /* length of stack (head of th->stack) */ size_t vm_stack_clen; /* length of control frames (tail of th->stack) */ #endif - VALUE *machine_stack; - VALUE *machine_stack_src; + struct { + VALUE *stack; + VALUE *stack_src; + size_t stack_size; #ifdef __ia64 - VALUE *machine_register_stack; - VALUE *machine_register_stack_src; - int machine_register_stack_size; + VALUE *register_stack; + VALUE *register_stack_src; + int register_stack_size; #endif + } machine; rb_thread_t saved_thread; rb_jmpbuf_t jmpbuf; - size_t machine_stack_size; } rb_context_t; enum fiber_status { @@ -186,11 +188,11 @@ cont_mark(void *ptr) #endif } - if (cont->machine_stack) { + if (cont->machine.stack) { if (cont->type == CONTINUATION_CONTEXT) { /* cont */ - rb_gc_mark_locations(cont->machine_stack, - cont->machine_stack + cont->machine_stack_size); + rb_gc_mark_locations(cont->machine.stack, + cont->machine.stack + cont->machine.stack_size); } else { /* fiber */ @@ -198,15 +200,15 @@ cont_mark(void *ptr) rb_fiber_t *fib = (rb_fiber_t*)cont; GetThreadPtr(cont->saved_thread.self, th); if ((th->fiber != cont->self) && fib->status == RUNNING) { - rb_gc_mark_locations(cont->machine_stack, - cont->machine_stack + cont->machine_stack_size); + rb_gc_mark_locations(cont->machine.stack, + cont->machine.stack + cont->machine.stack_size); } } } #ifdef __ia64 - if (cont->machine_register_stack) { - rb_gc_mark_locations(cont->machine_register_stack, - cont->machine_register_stack + cont->machine_register_stack_size); + if (cont->machine.register_stack) { + rb_gc_mark_locations(cont->machine.register_stack, + cont->machine.register_stack + cont->machine.register_stack_size); } #endif } @@ -223,7 +225,7 @@ cont_free(void *ptr) #if FIBER_USE_NATIVE if (cont->type == CONTINUATION_CONTEXT) { /* cont */ - RUBY_FREE_UNLESS_NULL(cont->machine_stack); + RUBY_FREE_UNLESS_NULL(cont->machine.stack); } else { /* fiber */ @@ -253,10 +255,10 @@ cont_free(void *ptr) #endif } #else /* not FIBER_USE_NATIVE */ - RUBY_FREE_UNLESS_NULL(cont->machine_stack); + RUBY_FREE_UNLESS_NULL(cont->machine.stack); #endif #ifdef __ia64 - RUBY_FREE_UNLESS_NULL(cont->machine_register_stack); + RUBY_FREE_UNLESS_NULL(cont->machine.register_stack); #endif RUBY_FREE_UNLESS_NULL(cont->vm_stack); @@ -282,12 +284,12 @@ cont_memsize(const void *ptr) size += n * sizeof(*cont->vm_stack); } - if (cont->machine_stack) { - size += cont->machine_stack_size * sizeof(*cont->machine_stack); + if (cont->machine.stack) { + size += cont->machine.stack_size * sizeof(*cont->machine.stack); } #ifdef __ia64 - if (cont->machine_register_stack) { - size += cont->machine_register_stack_size * sizeof(*cont->machine_register_stack); + if (cont->machine.register_stack) { + size += cont->machine.register_stack_size * sizeof(*cont->machine.register_stack); } #endif } @@ -375,42 +377,42 @@ cont_save_machine_stack(rb_thread_t *th, rb_context_t *cont) { size_t size; - SET_MACHINE_STACK_END(&th->machine_stack_end); + SET_MACHINE_STACK_END(&th->machine.stack_end); #ifdef __ia64 - th->machine_register_stack_end = rb_ia64_bsp(); + 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->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; } 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->machine.stack_end - th->machine.stack_start; + cont->machine.stack_src = th->machine.stack_start; } - if (cont->machine_stack) { - REALLOC_N(cont->machine_stack, VALUE, size); + if (cont->machine.stack) { + REALLOC_N(cont->machine.stack, VALUE, size); } else { - cont->machine_stack = ALLOC_N(VALUE, size); + cont->machine.stack = ALLOC_N(VALUE, size); } FLUSH_REGISTER_WINDOWS; - MEMCPY(cont->machine_stack, cont->machine_stack_src, VALUE, size); + MEMCPY(cont->machine.stack, cont->machine.stack_src, VALUE, size); #ifdef __ia64 rb_ia64_flushrs(); - size = cont->machine_register_stack_size = th->machine_register_stack_end - th->machine_register_stack_start; - cont->machine_register_stack_src = th->machine_register_stack_start; - if (cont->machine_register_stack) { - REALLOC_N(cont->machine_register_stack, VALUE, size); + size = cont->machine.register_stack_size = th->machine.register_stack_end - th->machine.register_stack_start; + cont->machine.register_stack_src = th->machine.register_stack_start; + if (cont->machine.register_stack) { + REALLOC_N(cont->machine.register_stack, VALUE, size); } else { - cont->machine_register_stack = ALLOC_N(VALUE, size); + cont->machine.register_stack = ALLOC_N(VALUE, size); } - MEMCPY(cont->machine_register_stack, cont->machine_register_stack_src, VALUE, size); + MEMCPY(cont->machine.register_stack, cont->machine.register_stack_src, VALUE, size); #endif } @@ -424,13 +426,13 @@ cont_save_thread(rb_context_t *cont, rb_thread_t *th) { /* save thread context */ cont->saved_thread = *th; - /* saved_thread->machine_stack_(start|end) should be NULL */ + /* saved_thread->machine.stack_(start|end) should be NULL */ /* because it may happen GC afterward */ - cont->saved_thread.machine_stack_start = 0; - cont->saved_thread.machine_stack_end = 0; + cont->saved_thread.machine.stack_start = 0; + cont->saved_thread.machine.stack_end = 0; #ifdef __ia64 - cont->saved_thread.machine_register_stack_start = 0; - cont->saved_thread.machine_register_stack_end = 0; + cont->saved_thread.machine.register_stack_start = 0; + cont->saved_thread.machine.register_stack_end = 0; #endif } @@ -555,7 +557,7 @@ fiber_set_stack_location(void) 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->machine.stack_start = (void*)(((VALUE)ptr & RB_PAGE_MASK) + STACK_UPPER((void *)&ptr, 0, RB_PAGE_SIZE)); } static VOID CALLBACK @@ -629,7 +631,7 @@ fiber_initialize_machine_stack_context(rb_fiber_t *fib, size_t size) rb_raise(rb_eFiberError, "can't create fiber"); } } - sth->machine_stack_maxsize = size; + sth->machine.stack_maxsize = size; #else /* not WIN32 */ ucontext_t *context = &fib->context; char *ptr; @@ -641,11 +643,11 @@ fiber_initialize_machine_stack_context(rb_fiber_t *fib, size_t size) context->uc_stack.ss_sp = ptr; context->uc_stack.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->machine.stack_start = (VALUE*)(ptr + STACK_DIR_UPPER(0, size)); + sth->machine.stack_maxsize = size - RB_PAGE_SIZE; #endif #ifdef __ia64 - sth->machine_register_stack_maxsize = sth->machine_stack_maxsize; + sth->machine.register_stack_maxsize = sth->machine.stack_maxsize; #endif } @@ -662,29 +664,29 @@ fiber_setcontext(rb_fiber_t *newfib, rb_fiber_t *oldfib) /* restore thread context */ cont_restore_thread(&newfib->cont); - 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"); + 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"); } /* save oldfib's machine stack */ if (oldfib->status != TERMINATED) { STACK_GROW_DIR_DETECTION; - SET_MACHINE_STACK_END(&th->machine_stack_end); + SET_MACHINE_STACK_END(&th->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->machine.stack_start - th->machine.stack_end; + oldfib->cont.machine.stack = th->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->machine.stack_end - th->machine.stack_start; + oldfib->cont.machine.stack = th->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->machine_stack_end should be NULL */ - oldfib->cont.saved_thread.machine_stack_end = 0; + oldfib->cont.saved_thread.machine.stack_start = th->machine.stack_start; + th->machine.stack_start = sth->machine.stack_start; + /* oldfib->machine.stack_end should be NULL */ + oldfib->cont.saved_thread.machine.stack_end = 0; #ifndef _WIN32 if (!newfib->context.uc_stack.ss_sp && th->root_fiber != newfib->cont.self) { rb_bug("non_root_fiber->context.uc_stac.ss_sp should not be NULL"); @@ -717,16 +719,16 @@ cont_restore_1(rb_context_t *cont) ((_JUMP_BUFFER*)(&buf))->Frame; } #endif - if (cont->machine_stack_src) { + if (cont->machine.stack_src) { FLUSH_REGISTER_WINDOWS; - MEMCPY(cont->machine_stack_src, cont->machine_stack, - VALUE, cont->machine_stack_size); + MEMCPY(cont->machine.stack_src, cont->machine.stack, + VALUE, cont->machine.stack_size); } #ifdef __ia64 - if (cont->machine_register_stack_src) { - MEMCPY(cont->machine_register_stack_src, cont->machine_register_stack, - VALUE, cont->machine_register_stack_size); + if (cont->machine.register_stack_src) { + MEMCPY(cont->machine.register_stack_src, cont->machine.register_stack, + VALUE, cont->machine.register_stack_size); } #endif @@ -761,7 +763,7 @@ register_stack_extend(rb_context_t *cont, VALUE *vp, VALUE *curr_bsp) E(k) = E(l) = E(m) = E(n) = E(o) = E(p) = E(q) = E(r) = E(s) = E(t) = 0; } - if (curr_bsp < cont->machine_register_stack_src+cont->machine_register_stack_size) { + if (curr_bsp < cont->machine.register_stack_src+cont->machine.register_stack_size) { register_stack_extend(cont, vp, (VALUE*)rb_ia64_bsp()); } cont_restore_0(cont, vp); @@ -773,7 +775,7 @@ register_stack_extend(rb_context_t *cont, VALUE *vp, VALUE *curr_bsp) static void cont_restore_0(rb_context_t *cont, VALUE *addr_in_prev_frame) { - if (cont->machine_stack_src) { + if (cont->machine.stack_src) { #ifdef HAVE_ALLOCA #define STACK_PAD_SIZE 1 #else @@ -786,7 +788,7 @@ cont_restore_0(rb_context_t *cont, VALUE *addr_in_prev_frame) /* Stack grows downward */ #endif #if STACK_GROW_DIRECTION <= 0 - volatile VALUE *const end = cont->machine_stack_src; + volatile VALUE *const end = cont->machine.stack_src; if (&space[0] > end) { # ifdef HAVE_ALLOCA volatile VALUE *sp = ALLOCA_N(VALUE, &space[0] - end); @@ -802,7 +804,7 @@ cont_restore_0(rb_context_t *cont, VALUE *addr_in_prev_frame) /* Stack grows upward */ #endif #if STACK_GROW_DIRECTION >= 0 - volatile VALUE *const end = cont->machine_stack_src + cont->machine_stack_size; + volatile VALUE *const end = cont->machine.stack_src + cont->machine.stack_size; if (&space[STACK_PAD_SIZE] < end) { # ifdef HAVE_ALLOCA volatile VALUE *sp = ALLOCA_N(VALUE, end - &space[STACK_PAD_SIZE]); @@ -1157,8 +1159,8 @@ rb_fiber_terminate(rb_fiber_t *fib) terminated_machine_stack.ptr = fib->context.uc_stack.ss_sp; terminated_machine_stack.size = fib->context.uc_stack.ss_size / sizeof(VALUE); fib->context.uc_stack.ss_sp = NULL; - fib->cont.machine_stack = NULL; - fib->cont.machine_stack_size = 0; + fib->cont.machine.stack = NULL; + fib->cont.machine.stack_size = 0; #endif rb_fiber_transfer(return_fiber(), 1, &value); } @@ -1269,7 +1271,7 @@ fiber_store(rb_fiber_t *next_fib) machine_stack_cache_index++; } else { - if (terminated_machine_stack.ptr != fib->cont.machine_stack) { + if (terminated_machine_stack.ptr != fib->cont.machine.stack) { munmap((void*)terminated_machine_stack.ptr, terminated_machine_stack.size * sizeof(VALUE)); } else { @@ -1559,7 +1561,7 @@ Init_Cont(void) #else /* not WIN32 */ pagesize = sysconf(_SC_PAGESIZE); #endif - SET_MACHINE_STACK_END(&th->machine_stack_end); + SET_MACHINE_STACK_END(&th->machine.stack_end); #endif rb_cFiber = rb_define_class("Fiber", rb_cObject); @@ -2246,14 +2246,14 @@ init_mark_stack(mark_stack_t *stack) #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(&th->machine.stack_end), th->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(&th->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 (th->machine.stack_start) +#define STACK_END (th->machine.stack_end) +#define STACK_LEVEL_MAX (th->machine.stack_maxsize/sizeof(VALUE)) #if STACK_GROW_DIRECTION < 0 # define STACK_LENGTH (size_t)(STACK_START - STACK_END) @@ -2295,8 +2295,8 @@ stack_check(int water_mark) 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() - th->machine.register_stack_start > + th->machine.register_stack_maxsize/sizeof(VALUE) - water_mark; } #endif return ret; @@ -2518,7 +2518,7 @@ mark_current_machine_context(rb_objspace_t *objspace, rb_thread_t *th) rb_gc_mark_locations(stack_start, stack_end); #ifdef __ia64 - rb_gc_mark_locations(th->machine_register_stack_start, th->machine_register_stack_end); + rb_gc_mark_locations(th->machine.register_stack_start, th->machine.register_stack_end); #endif #if defined(__mc68000__) mark_locations_array(objspace, (VALUE*)((char*)STACK_END + 2), @@ -2535,7 +2535,7 @@ rb_gc_mark_machine_stack(rb_thread_t *th) GET_STACK_BOUNDS(stack_start, stack_end, 0); rb_gc_mark_locations(stack_start, stack_end); #ifdef __ia64 - rb_gc_mark_locations(th->machine_register_stack_start, th->machine_register_stack_end); + rb_gc_mark_locations(th->machine.register_stack_start, th->machine.register_stack_end); #endif } diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb index ea733b3add..4aacc4b512 100644 --- a/test/ruby/test_exception.rb +++ b/test/ruby/test_exception.rb @@ -568,4 +568,15 @@ end.join assert_equal("Ruby", favorite_lang) end + + def test_machine_stackoverflow_by_define_method + bug9454 = '[ruby-core:60113] [Bug #9454]' + assert_separately([], <<-SRC) + assert_raise(SystemStackError, #{bug9454.dump}) { + define_method(:foo) {self.foo} + self.foo + } + SRC + rescue SystemStackError + end end @@ -122,7 +122,7 @@ static inline void blocking_region_end(rb_thread_t *th, struct rb_blocking_regio #ifdef __ia64 #define RB_GC_SAVE_MACHINE_REGISTER_STACK(th) \ - do{(th)->machine_register_stack_end = rb_ia64_bsp();}while(0) + do{(th)->machine.register_stack_end = rb_ia64_bsp();}while(0) #else #define RB_GC_SAVE_MACHINE_REGISTER_STACK(th) #endif @@ -130,8 +130,8 @@ static inline void blocking_region_end(rb_thread_t *th, struct rb_blocking_regio 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)->machine.regs); \ + SET_MACHINE_STACK_END(&(th)->machine.stack_end); \ } while (0) #define GVL_UNLOCK_BEGIN() do { \ @@ -444,9 +444,9 @@ thread_cleanup_func_before_exec(void *th_ptr) { rb_thread_t *th = th_ptr; th->status = THREAD_KILLED; - th->machine_stack_start = th->machine_stack_end = 0; + th->machine.stack_start = th->machine.stack_end = 0; #ifdef __ia64 - th->machine_register_stack_start = th->machine_register_stack_end = 0; + th->machine.register_stack_start = th->machine.register_stack_end = 0; #endif } @@ -498,9 +498,9 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s ruby_thread_set_native(th); - th->machine_stack_start = stack_start; + th->machine.stack_start = stack_start; #ifdef __ia64 - th->machine_register_stack_start = register_stack_start; + th->machine.register_stack_start = register_stack_start; #endif thread_debug("thread start: %p\n", (void *)th); diff --git a/thread_pthread.c b/thread_pthread.c index 55e2856e43..11b665fda4 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -633,6 +633,18 @@ ruby_init_stack(volatile VALUE *addr ) { native_main_thread.id = pthread_self(); +#if MAINSTACKADDR_AVAILABLE + if (native_main_thread.stack_maxsize) return; + { + void* stackaddr; + size_t size; + if (get_main_stack(&stackaddr, &size) == 0) { + native_main_thread.stack_maxsize = size; + native_main_thread.stack_start = stackaddr; + return; + } + } +#endif #ifdef STACK_END_ADDRESS native_main_thread.stack_start = STACK_END_ADDRESS; #else @@ -650,6 +662,7 @@ ruby_init_stack(volatile VALUE *addr } #endif { +#if defined(HAVE_GETRLIMIT) #if defined(PTHREAD_STACK_DEFAULT) # if PTHREAD_STACK_DEFAULT < RUBY_STACK_SPACE*5 # error "PTHREAD_STACK_DEFAULT is too small" @@ -658,15 +671,7 @@ ruby_init_stack(volatile VALUE *addr #else size_t size = RUBY_VM_THREAD_VM_STACK_SIZE; #endif - size_t space = space_size(size); -#if MAINSTACKADDR_AVAILABLE - void* stackaddr; - STACK_GROW_DIR_DETECTION; - if (get_stack(&stackaddr, &size) == 0) { - space = STACK_DIR_UPPER((char *)addr - (char *)stackaddr, (char *)stackaddr - (char *)addr); - } - native_main_thread.stack_maxsize = size - space; -#elif defined(HAVE_GETRLIMIT) + size_t space; int pagesize = getpagesize(); struct rlimit rlim; STACK_GROW_DIR_DETECTION; @@ -716,8 +721,8 @@ native_thread_init_stack(rb_thread_t *th) rb_thread_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->machine.stack_start = native_main_thread.stack_start; + th->machine.stack_maxsize = native_main_thread.stack_maxsize; } else { #ifdef STACKADDR_AVAILABLE @@ -725,17 +730,22 @@ native_thread_init_stack(rb_thread_t *th) size_t size; if (get_stack(&start, &size) == 0) { - th->machine_stack_start = start; - th->machine_stack_maxsize = size; + th->machine.stack_start = start; + th->machine.stack_maxsize = size; + } +#elif defined get_stack_of + if (!th->machine.stack_maxsize) { + native_mutex_lock(&th->interrupt_lock); + native_mutex_unlock(&th->interrupt_lock); } #else rb_raise(rb_eNotImpError, "ruby engine can initialize only in the main thread"); #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->machine.register_stack_start = native_main_thread.register_stack_start; + th->machine.stack_maxsize /= 2; + th->machine.register_stack_maxsize = th->machine.stack_maxsize; #endif return 0; } @@ -762,7 +772,7 @@ thread_start_func_1(void *th_ptr) 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->machine.stack_start, rb_ia64_bsp()); #else thread_start_func_2(th, &stack_start, rb_ia64_bsp()); #endif @@ -886,10 +896,10 @@ native_thread_create(rb_thread_t *th) 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->machine.stack_maxsize = stack_size - space; #ifdef __ia64 - th->machine_stack_maxsize /= 2; - th->machine_register_stack_maxsize = th->machine_stack_maxsize; + th->machine.stack_maxsize /= 2; + th->machine.register_stack_maxsize = th->machine.stack_maxsize; #endif #ifdef HAVE_PTHREAD_ATTR_INIT @@ -904,10 +914,18 @@ native_thread_create(rb_thread_t *th) CHECK_ERR(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED)); # endif CHECK_ERR(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)); - - err = pthread_create(&th->thread_id, &attr, thread_start_func_1, th); -#else - err = pthread_create(&th->thread_id, NULL, thread_start_func_1, th); +#endif +#ifdef get_stack_of + native_mutex_lock(&th->interrupt_lock); +#endif + err = pthread_create(&th->thread_id, attrp, thread_start_func_1, th); +#ifdef get_stack_of + if (!err) { + get_stack_of(th->thread_id, + &th->machine.stack_start, + &th->machine.stack_maxsize); + } + native_mutex_unlock(&th->interrupt_lock); #endif thread_debug("create: %p (%d)\n", (void *)th, err); #ifdef HAVE_PTHREAD_ATTR_INIT @@ -1501,15 +1519,24 @@ ruby_stack_overflowed_p(const rb_thread_t *th, const void *addr) const size_t water_mark = 1024 * 1024; STACK_GROW_DIR_DETECTION; - if (th) { - size = th->machine_stack_maxsize; - base = (char *)th->machine_stack_start - STACK_DIR_UPPER(0, size); - } #ifdef STACKADDR_AVAILABLE - else if (get_stack(&base, &size) == 0) { - STACK_DIR_UPPER((void)(base = (char *)base + size), (void)0); + if (get_stack(&base, &size) == 0) { +# ifdef __APPLE__ + if (pthread_equal(th->thread_id, native_main_thread.id)) { + struct rlimit rlim; + if (getrlimit(RLIMIT_STACK, &rlim) == 0 && rlim.rlim_cur > size) { + size = (size_t)rlim.rlim_cur; + } + } +# endif + base = (char *)base + STACK_DIR_UPPER(+size, -size); } + else #endif + if (th) { + size = th->machine.stack_maxsize; + base = (char *)th->machine.stack_start - STACK_DIR_UPPER(0, size); + } else { return 0; } diff --git a/thread_win32.c b/thread_win32.c index 2bb56d0646..a8bd59baf7 100644 --- a/thread_win32.c +++ b/thread_win32.c @@ -589,8 +589,8 @@ native_thread_init_stack(rb_thread_t *th) 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->machine.stack_start = (VALUE *)end - 1; + th->machine.stack_maxsize = size - space; } #ifndef InterlockedExchangePointer @@ -618,7 +618,7 @@ thread_start_func_1(void *th_ptr) 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->machine.stack_start, rb_ia64_bsp()); w32_close_handle(thread_id); thread_debug("thread deleted (th: %p)\n", th); @@ -1,10 +1,10 @@ #define RUBY_VERSION "2.0.0" -#define RUBY_RELEASE_DATE "2014-06-28" -#define RUBY_PATCHLEVEL 510 +#define RUBY_RELEASE_DATE "2014-07-03" +#define RUBY_PATCHLEVEL 511 #define RUBY_RELEASE_YEAR 2014 -#define RUBY_RELEASE_MONTH 6 -#define RUBY_RELEASE_DAY 28 +#define RUBY_RELEASE_MONTH 7 +#define RUBY_RELEASE_DAY 3 #include "ruby/version.h" @@ -1840,11 +1840,11 @@ rb_thread_mark(void *ptr) rb_mark_tbl(th->local_storage); - if (GET_THREAD() != th && th->machine_stack_start && th->machine_stack_end) { + 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)); + rb_gc_mark_locations((VALUE *)&th->machine.regs, + (VALUE *)(&th->machine.regs) + + sizeof(th->machine.regs) / sizeof(VALUE)); } vm_trace_mark_event_hooks(&th->event_hooks); @@ -585,15 +585,17 @@ typedef struct rb_thread_struct { VALUE (*first_func)(ANYARGS); /* for GC */ - VALUE *machine_stack_start; - VALUE *machine_stack_end; - size_t machine_stack_maxsize; + struct { + VALUE *stack_start; + VALUE *stack_end; + size_t stack_maxsize; #ifdef __ia64 - VALUE *machine_register_stack_start; - VALUE *machine_register_stack_end; - size_t machine_register_stack_maxsize; + VALUE *register_stack_start; + VALUE *register_stack_end; + size_t register_stack_maxsize; #endif - jmp_buf machine_regs; + jmp_buf regs; + } machine; int mark_stack_len; /* statistics data for profiler */ |