1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* 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.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32438 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nari 2011-07-07 14:59:09 +00:00
parent 68a0d412dd
commit 17bb77fd77
3 changed files with 76 additions and 8 deletions

View file

@ -1,3 +1,13 @@
Thu Jul 7 23:35:31 2011 Narihiro Nakamura <authornari@gmail.com>
* 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@ruby-lang.org>
* test/testunit/test_parallel.rb (TestParallelWorker#teardown): wait

View file

@ -1230,6 +1230,63 @@ if test $rb_cv_stack_end_address != no; then
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

17
gc.c
View file

@ -1277,7 +1277,8 @@ ruby_get_stack_grow_direction(volatile VALUE *addr)
}
#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 @@ ruby_stack_length(VALUE **p)
}
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 @@ rb_gc_mark_maybe(VALUE obj)
}
}
#define GC_LEVEL_MAX 250
static void
gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
{
@ -1614,7 +1615,7 @@ gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
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;