diff --git a/ChangeLog b/ChangeLog
index 1dd75804f7..4b5c52ca6d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Sun Apr 19 14:43:18 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* eval.c (ruby_cleanup): the order of local variables on stack is
+	  undefined.  should use outermost VALUE for ruby_init_stack.
+
+	* gc.c (ruby_get_stack_grow_direction, Init_stack): allows volatile
+	  pointer.
+
+	* thread_*.c (ruby_init_stack): ditto.
+
 Sun Apr 19 13:17:25 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>
 
 	* gem_prelude.rb (Gem::QuickLoader#push_gem_version_on_load_path):
diff --git a/common.mk b/common.mk
index ebbb607ea6..8fa2e13e1c 100644
--- a/common.mk
+++ b/common.mk
@@ -499,7 +499,7 @@ error.$(OBJEXT): {$(VPATH)}error.c {$(VPATH)}known_errors.inc $(RUBY_H_INCLUDES)
   $(VM_CORE_H_INCLUDES) {$(VPATH)}debug.h
 eval.$(OBJEXT): {$(VPATH)}eval.c {$(VPATH)}eval_intern.h \
   $(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES) {$(VPATH)}eval_error.c \
-  {$(VPATH)}eval_jump.c {$(VPATH)}debug.h \
+  {$(VPATH)}eval_jump.c {$(VPATH)}debug.h {$(VPATH)}gc.h \
   {$(VPATH)}iseq.h
 load.$(OBJEXT): {$(VPATH)}load.c {$(VPATH)}eval_intern.h \
   {$(VPATH)}util.h $(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES) \
diff --git a/eval.c b/eval.c
index 2e66acd627..1d5345f0a4 100644
--- a/eval.c
+++ b/eval.c
@@ -13,6 +13,7 @@
 
 #include "eval_intern.h"
 #include "iseq.h"
+#include "gc.h"
 
 VALUE proc_invoke(VALUE, VALUE, VALUE, VALUE);
 VALUE rb_binding_new(void);
@@ -55,7 +56,7 @@ ruby_init(void)
 
     rb_origenviron = environ;
 
-    Init_stack((void *)&state);
+    ruby_init_stack((void *)&state);
     Init_BareVM();
     Init_heap();
 
@@ -79,9 +80,9 @@ void *
 ruby_options(int argc, char **argv)
 {
     int state;
-    void *iseq = 0;
+    void *volatile iseq = 0;
 
-    Init_stack((void *)&state);
+    ruby_init_stack((void *)&iseq);
     PUSH_TAG();
     if ((state = EXEC_TAG()) == 0) {
 	SAVE_ROOT_JMPBUF(GET_THREAD(), iseq = ruby_process_options(argc, argv));
@@ -134,7 +135,7 @@ ruby_cleanup(volatile int ex)
 
     errs[1] = th->errinfo;
     th->safe_level = 0;
-    Init_stack((void *)&state);
+    ruby_init_stack(&errs[STACK_UPPER(errs, 0, 1)]);
 
     PUSH_TAG();
     if ((state = EXEC_TAG()) == 0) {
@@ -228,7 +229,7 @@ ruby_run_node(void *n)
     if (FIXNUM_P(v)) {
 	return FIX2INT(v);
     }
-    Init_stack((void *)&n);
+    ruby_init_stack((void *)&n);
     return ruby_cleanup(ruby_exec_node(n, 0));
 }
 
@@ -629,7 +630,7 @@ rb_rescue(VALUE (* b_proc)(ANYARGS), VALUE data1,
 VALUE
 rb_protect(VALUE (* proc) (VALUE), VALUE data, int * state)
 {
-    VALUE result = Qnil;	/* OK */
+    volatile VALUE result = Qnil;
     int status;
     rb_thread_t *th = GET_THREAD();
     rb_control_frame_t *cfp = th->cfp;
diff --git a/gc.c b/gc.c
index 56215bb6ea..8a4075a0b2 100644
--- a/gc.c
+++ b/gc.c
@@ -653,7 +653,7 @@ vm_xrealloc(rb_objspace_t *objspace, void *ptr, size_t size)
     if (!ptr) return ruby_xmalloc(size);
     if (size == 0) size = 1;
     if (ruby_gc_stress && !ruby_disable_gc_stress)
-      garbage_collect_with_gvl(objspace);
+	garbage_collect_with_gvl(objspace);
 
 #if CALC_EXACT_MALLOC_SIZE
     size += sizeof(size_t);
@@ -1109,7 +1109,7 @@ rb_data_object_alloc(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_F
 #if !STACK_GROW_DIRECTION
 int ruby_stack_grow_direction;
 int
-ruby_get_stack_grow_direction(VALUE *addr)
+ruby_get_stack_grow_direction(volatile VALUE *addr)
 {
     VALUE *end;
     SET_MACHINE_STACK_END(&end);
@@ -2122,7 +2122,7 @@ rb_gc_start(void)
 #undef Init_stack
 
 void
-Init_stack(VALUE *addr)
+Init_stack(volatile VALUE *addr)
 {
     ruby_init_stack(addr);
 }
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index 1e619da33d..7a83887545 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -1021,10 +1021,10 @@ NORETURN(void rb_throw_obj(VALUE,VALUE));
 VALUE rb_require(const char*);
 
 #ifdef __ia64
-void ruby_init_stack(VALUE*, void*);
+void ruby_init_stack(volatile VALUE*, void*);
 #define ruby_init_stack(addr) ruby_init_stack(addr, rb_ia64_bsp())
 #else
-void ruby_init_stack(VALUE*);
+void ruby_init_stack(volatile VALUE*);
 #endif
 #define RUBY_INIT_STACK \
     VALUE variable_in_this_stack_frame; \
diff --git a/thread_pthread.c b/thread_pthread.c
index 11a70d77a3..57a032f679 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -264,7 +264,7 @@ extern void *STACK_END_ADDRESS;
 
 #undef ruby_init_stack
 void
-ruby_init_stack(VALUE *addr
+ruby_init_stack(volatile VALUE *addr
 #ifdef __ia64
     , void *bsp
 #endif
@@ -278,7 +278,7 @@ ruby_init_stack(VALUE *addr
         STACK_UPPER((VALUE *)(void *)&addr,
                     native_main_thread.stack_start > addr,
                     native_main_thread.stack_start < addr)) {
-        native_main_thread.stack_start = addr;
+        native_main_thread.stack_start = (VALUE *)addr;
     }
 #endif
 #ifdef __ia64
diff --git a/thread_win32.c b/thread_win32.c
index 684085fdb0..f404a4f312 100644
--- a/thread_win32.c
+++ b/thread_win32.c
@@ -417,7 +417,7 @@ native_cond_destroy(rb_thread_cond_t *cond)
 }
 
 void
-ruby_init_stack(VALUE *addr)
+ruby_init_stack(volatile VALUE *addr)
 {
 }