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:
parent
68a0d412dd
commit
17bb77fd77
3 changed files with 76 additions and 8 deletions
10
ChangeLog
10
ChangeLog
|
@ -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
|
||||
|
|
57
configure.in
57
configure.in
|
@ -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
17
gc.c
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue