summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-06-28 03:29:00 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-06-28 03:29:00 +0000
commite5a9dcb9d8863fc2ad44c4f85a10a95329e3c154 (patch)
treee3fcc29316c79f8df372319c472d4875271d0f8e
parent057dcc0495e9f6e85c322bf294dd03dde3899de7 (diff)
* configure.in (rb_cv_stack_grow_dir): check stack growing direction.
* eval.c (rb_thread_restore_context): prior configuration macro. * gc.c (ruby_stack_length): always return the address of lower edge. * gc.c (rb_gc_mark_locations): remove margin. [ruby-dev:20462] * gc.c (rb_gc, Init_stack): prior configuration macro. * gc.c (Init_stack): add safety margin. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4012 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog14
-rw-r--r--configure.in24
-rw-r--r--eval.c9
-rw-r--r--gc.c61
4 files changed, 82 insertions, 26 deletions
diff --git a/ChangeLog b/ChangeLog
index b5479975ff..8636a10d7b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Sat Jun 28 12:28:54 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
+
+ * configure.in (rb_cv_stack_grow_dir): check stack growing direction.
+
+ * eval.c (rb_thread_restore_context): prior configuration macro.
+
+ * gc.c (ruby_stack_length): always return the address of lower edge.
+
+ * gc.c (rb_gc_mark_locations): remove margin. [ruby-dev:20462]
+
+ * gc.c (rb_gc, Init_stack): prior configuration macro.
+
+ * gc.c (Init_stack): add safety margin.
+
Fri Jun 27 14:41:22 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* string.c (rb_str_split_m): remove white spaces on the head of
diff --git a/configure.in b/configure.in
index ec6abaef71..cebfc766b0 100644
--- a/configure.in
+++ b/configure.in
@@ -616,6 +616,30 @@ if test "$rb_cv_need_io_flush_before_seek" = yes; then
AC_DEFINE(NEED_IO_FLUSH_BEFORE_SEEK, 1)
fi
+case "$target_cpu" in
+m68*|i?86|sparc) rb_cv_stack_grow_dir=-1;;
+esac
+AC_CACHE_CHECK(stack growing direction, rb_cv_stack_grow_dir,
+ [AC_TRY_RUN([
+/* recurse to get rid of inlining */
+static int
+stack_growup_p(addr, n)
+ volatile int *addr, n;
+{
+ volatile int end;
+ if (n > 0)
+ return *addr = stack_growup_p(addr, n - 1);
+ else
+ return (&end > addr);
+}
+int main()
+{
+ int x;
+ return stack_growup_p(&x, 10);
+}
+], rb_cv_stack_grow_dir=-1, rb_cv_stack_grow_dir=+1, rb_cv_stack_grow_dir=0)])
+AC_DEFINE_UNQUOTED(STACK_GROW_DIRECTION, $rb_cv_stack_grow_dir)
+
dnl default value for $KANJI
DEFAULT_KCODE="KCODE_NONE"
diff --git a/eval.c b/eval.c
index 0468d37dc9..272d2f74f5 100644
--- a/eval.c
+++ b/eval.c
@@ -8112,8 +8112,7 @@ rb_thread_save_context(th)
len = ruby_stack_length(&pos);
th->stk_len = 0;
- th->stk_pos = (rb_gc_stack_start<pos)?rb_gc_stack_start
- :rb_gc_stack_start - len;
+ th->stk_pos = pos;
if (len > th->stk_max) {
REALLOC_N(th->stk_ptr, VALUE, len);
th->stk_max = len;
@@ -8211,6 +8210,11 @@ rb_thread_restore_context(th, exit)
if (!th->stk_ptr) rb_bug("unsaved context");
+#if STACK_GROW_DIRECTION < 0
+ if (&v > th->stk_pos) stack_extend(th, exit);
+#elif STACK_GROW_DIRECTION > 0
+ if (&v < th->stk_pos + th->stk_len) stack_extend(th, exit);
+#else
if (&v < rb_gc_stack_start) {
/* Stack grows downward */
if (&v > th->stk_pos) stack_extend(th, exit);
@@ -8219,6 +8223,7 @@ rb_thread_restore_context(th, exit)
/* Stack grows upward */
if (&v < th->stk_pos + th->stk_len) stack_extend(th, exit);
}
+#endif
rb_trap_immediate = 0; /* inhibit interrupts from here */
ruby_frame = th->frame;
diff --git a/gc.c b/gc.c
index 3c06bfc5da..9c8ac774f2 100644
--- a/gc.c
+++ b/gc.c
@@ -376,10 +376,30 @@ static unsigned int STACK_LEVEL_MAX = 655300;
#endif
#if defined(sparc) || defined(__sparc__)
# define STACK_LENGTH (rb_gc_stack_start - STACK_END + 0x80)
+#elif STACK_GROW_DIRECTION < 0
+# define STACK_LENGTH (rb_gc_stack_start - STACK_END)
+#elif STACK_GROW_DIRECTION > 0
+# define STACK_LENGTH (STACK_END - rb_gc_stack_start)
#else
# define STACK_LENGTH ((STACK_END < rb_gc_stack_start) ? rb_gc_stack_start - STACK_END\
: STACK_END - rb_gc_stack_start)
#endif
+#if STACK_GROW_DIRECTION > 0
+# define STACK_UPPER(x, a, b) a
+#elif STACK_GROW_DIRECTION < 0
+# define STACK_UPPER(x, a, b) b
+#else
+static int
+stack_growup_p(addr)
+ VALUE *addr;
+{
+ SET_STACK_END;
+
+ if (STACK_END > addr) return Qtrue;
+ return Qfalse;
+}
+# define STACK_UPPER(x, a, b) (stack_growup_p(x) ? a : b)
+#endif
#define GC_WARTER_MARK 512
@@ -393,7 +413,7 @@ ruby_stack_length(p)
VALUE **p;
{
SET_STACK_END;
- if (p) *p = STACK_END;
+ if (p) *p = STACK_UPPER(STACK_END, rb_gc_stack_start, STACK_END);
return STACK_LENGTH;
}
@@ -544,7 +564,7 @@ rb_gc_mark_locations(start, end)
start = end;
end = tmp;
}
- n = end - start + 1;
+ n = end - start;
mark_locations_array(start,n);
}
@@ -1227,10 +1247,19 @@ rb_gc()
/* This assumes that all registers are saved into the jmp_buf */
setjmp(save_regs_gc_mark);
mark_locations_array((VALUE*)save_regs_gc_mark, sizeof(save_regs_gc_mark) / sizeof(VALUE *));
+#if STACK_GROW_DIRECTION < 0
+ rb_gc_mark_locations((VALUE*)STACK_END, rb_gc_stack_start);
+#elif STACK_GROW_DIRECTION > 0
rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END);
+#else
+ if ((VALUE*)STACK_END < rb_gc_stack_start)
+ rb_gc_mark_locations((VALUE*)STACK_END, rb_gc_stack_start);
+ else
+ rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END);
+#endif
#if defined(__human68k__) || defined(__mc68000__)
- rb_gc_mark_locations((VALUE*)((char*)rb_gc_stack_start + 2),
- (VALUE*)((char*)STACK_END + 2));
+ rb_gc_mark_locations((VALUE*)((char*)STACK_END + 2),
+ (VALUE*)((char*)rb_gc_stack_start + 2));
#endif
rb_gc_mark_threads();
@@ -1268,18 +1297,6 @@ rb_gc_start()
return Qnil;
}
-#if !defined(__human68k__)
-static int
-stack_growup_p(addr)
- VALUE *addr;
-{
- SET_STACK_END;
-
- if (STACK_END > addr) return Qtrue;
- return Qfalse;
-}
-#endif
-
void
Init_stack(addr)
VALUE *addr;
@@ -1290,14 +1307,10 @@ Init_stack(addr)
#else
if (!addr) addr = (VALUE *)&addr;
if (rb_gc_stack_start) {
- if (stack_growup_p(addr)) {
- if (rb_gc_stack_start > addr)
- rb_gc_stack_start = addr;
- }
- else {
- if (rb_gc_stack_start < addr)
- rb_gc_stack_start = addr;
- }
+ if (STACK_UPPER(&addr,
+ rb_gc_stack_start > --addr,
+ rb_gc_stack_start < ++addr))
+ rb_gc_stack_start = addr;
return;
}
rb_gc_stack_start = addr;