ruby-changes:20390
From: nari <ko1@a...>
Date: Thu, 7 Jul 2011 23:59:25 +0900 (JST)
Subject: [ruby-changes:20390] nari:r32438 (trunk): * gc.c: change water_mark value value that may call
nari 2011-07-07 23:59:09 +0900 (Thu, 07 Jul 2011) New Revision: 32438 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=32438 Log: * gc.c: change water_mark value value that may call gc_mark(lev <= GC_LEVEL_MAX) in gc_mark(). In ruby_stack_check(), water_mark is a value that may call some C function. Fixes Bug #3781 * configure.in: define GC_MARK_STACKFRAME_WORD that approximate size of gc_mark() and gc_mark_children() stackframes. Modified files: trunk/ChangeLog trunk/configure.in trunk/gc.c Index: configure.in =================================================================== --- configure.in (revision 32437) +++ configure.in (revision 32438) @@ -1230,6 +1230,63 @@ AC_DEFINE_UNQUOTED(STACK_END_ADDRESS, $rb_cv_stack_end_address) fi +AC_CACHE_CHECK(for gc_mark and gc_children stack frame approximate size(word), rb_cv_gc_mark_stackframe_word, +[save_CFLAGS="$CFLAGS" +CFLAGS="-O0" +AC_TRY_RUN([ +int word; +void *stack_start; + +void +set_stackframe_word() +{ + int dumy = 42; + int diff; + + if (stack_start < (void *)&dumy) { + diff = (int)((void *)&dumy - stack_start); + } + else { + diff = (int)(stack_start - (void *)&dumy); + } + word = (diff/sizeof(void *)); + if ((diff % sizeof(void *)) != 0) { + word++; + } +} + +void +gc_mark_children(void *p1, void *p2, int lev) +{ + void *obj = p2; + + set_stackframe_word(p1,p2,lev); +} + +void +gc_mark(void *p1, void *p2, int lev) +{ + void *obj = p2; + + gc_mark_children(p1,p2,lev++); +} + +int +main() { + int dumy = 42; + + stack_start = (void *)&dumy; + gc_mark(0, 0, 255); + return word; +} +], + [rb_cv_gc_mark_stackframe_word="$?"], + [rb_cv_gc_mark_stackframe_word="$?"], + [rb_cv_gc_mark_stackframe_word="30"]) +CFLAGS="$save_CFLAGS"]) +AC_DEFINE_UNQUOTED(GC_MARK_STACKFRAME_WORD, $rb_cv_gc_mark_stackframe_word) + + dnl Checks for library functions. AC_TYPE_GETGROUPS AC_TYPE_SIGNAL Index: ChangeLog =================================================================== --- ChangeLog (revision 32437) +++ ChangeLog (revision 32438) @@ -1,3 +1,13 @@ +Thu Jul 7 23:35:31 2011 Narihiro Nakamura <authornari@g...> + + * gc.c: change water_mark value value that may call + gc_mark(lev <= GC_LEVEL_MAX) in gc_mark(). + In ruby_stack_check(), water_mark is a value that may call some + C function. Fixes Bug #3781 + + * configure.in: define GC_MARK_STACKFRAME_WORD that approximate + size of gc_mark() and gc_mark_children() stackframes. + Thu Jul 7 17:55:05 2011 NAKAMURA Usaku <usa@r...> * test/testunit/test_parallel.rb (TestParallelWorker#teardown): wait Index: gc.c =================================================================== --- gc.c (revision 32437) +++ gc.c (revision 32438) @@ -1277,7 +1277,8 @@ } #endif -#define GC_WATER_MARK 512 +#define GC_LEVEL_MAX 250 +#define STACKFRAME_FOR_GC_MARK (GC_LEVEL_MAX * GC_MARK_STACKFRAME_WORD) size_t ruby_stack_length(VALUE **p) @@ -1289,28 +1290,30 @@ } static int -stack_check(void) +stack_check(int water_mark) { int ret; rb_thread_t *th = GET_THREAD(); SET_STACK_END; - ret = STACK_LENGTH > STACK_LEVEL_MAX - GC_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) - GC_WATER_MARK; + th->machine_register_stack_maxsize/sizeof(VALUE) - water_mark; } #endif return ret; } +#define STACKFRAME_FOR_CALL_CFUNC 512 + int ruby_stack_check(void) { #if defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK) return 0; #else - return stack_check(); + return stack_check(STACKFRAME_FOR_CALL_CFUNC); #endif } @@ -1600,8 +1603,6 @@ } } -#define GC_LEVEL_MAX 250 - static void gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev) { @@ -1614,7 +1615,7 @@ obj->as.basic.flags |= FL_MARK; objspace->heap.live_num++; - if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) { + if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check(STACKFRAME_FOR_GC_MARK))) { if (!mark_stack_overflow) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { *mark_stack_ptr = ptr; -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/