From f59bd226b3bb82566d6931723f98efa8060232a9 Mon Sep 17 00:00:00 2001 From: akr Date: Tue, 27 Dec 2005 05:40:04 +0000 Subject: * configure.in: define IA64 for portability. (HP aC++/ANSI C doesn't define __ia64__.) don't check libunwind stuff. check __libc_ia64_register_backing_store_base. * defines.h: declare rb_ia64_bsp and rb_ia64_flushrs. (flush_register_windows): call rb_ia64_flushrs on IA64. * ia64.s: new file for IA64. it is separated from C program files because Intel C++ Compiler for IA64 doesn't support inline assembly. * common.mk (ia64.$(OBJEXT)): new target. * ruby.h (RUBY_INIT_STACK): defined. (ruby_init_stack): declared for RUBY_INIT_STACK. * main.c (main): precedes RUBY_INIT_STACK before ruby_init. * gc.c (rb_gc_register_stack_start): new global variable on IA64. (garbage_collect): simplify register stack marking code. don't use libunwind. (Init_stack): initialize rb_gc_register_stack_start. (ruby_init_stack): new function for RUBY_INIT_STACK. * eval.c (struct thread): add bstr_pos member for original position of register stack. (rb_thread_save_context): simplify register stack saving code. don't use libunwind. (rb_thread_restore_context_0): new function. moved from rb_thread_restore_context except the stack position checking code. don't use libunwind for IA64 register stack. (register_stack_extend): new function. (stack_extend): make it self-recursive with the stack position checking code in old rb_thread_restore_context. (rb_thread_restore_context): just call stack_extend. (flush_register_windows): removed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9745 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 40 +++++++++++++ common.mk | 1 + configure.in | 24 ++++---- defines.h | 7 ++- eval.c | 183 ++++++++++++++++++++++++++++------------------------------- gc.c | 107 ++++++++++++++++++++-------------- ia64.s | 34 +++++++++++ main.c | 9 ++- numeric.c | 4 ++ ruby.h | 11 ++++ 10 files changed, 262 insertions(+), 158 deletions(-) create mode 100644 ia64.s diff --git a/ChangeLog b/ChangeLog index a739bd969d..2f8b2bebdb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,43 @@ +Tue Dec 27 14:17:55 2005 Tanaka Akira + + * configure.in: define IA64 for portability. (HP aC++/ANSI C doesn't + define __ia64__.) + don't check libunwind stuff. + check __libc_ia64_register_backing_store_base. + + * defines.h: declare rb_ia64_bsp and rb_ia64_flushrs. + (flush_register_windows): call rb_ia64_flushrs on IA64. + + * ia64.s: new file for IA64. + it is separated from C program files because + Intel C++ Compiler for IA64 doesn't support inline assembly. + + * common.mk (ia64.$(OBJEXT)): new target. + + * ruby.h (RUBY_INIT_STACK): defined. + (ruby_init_stack): declared for RUBY_INIT_STACK. + + * main.c (main): precedes RUBY_INIT_STACK before ruby_init. + + * gc.c (rb_gc_register_stack_start): new global variable on IA64. + (garbage_collect): simplify register stack marking code. + don't use libunwind. + (Init_stack): initialize rb_gc_register_stack_start. + (ruby_init_stack): new function for RUBY_INIT_STACK. + + * eval.c (struct thread): add bstr_pos member for original position of + register stack. + (rb_thread_save_context): simplify register stack saving code. + don't use libunwind. + (rb_thread_restore_context_0): new function. moved from + rb_thread_restore_context except the stack position checking code. + don't use libunwind for IA64 register stack. + (register_stack_extend): new function. + (stack_extend): make it self-recursive with + the stack position checking code in old rb_thread_restore_context. + (rb_thread_restore_context): just call stack_extend. + (flush_register_windows): removed. + Tue Dec 27 14:09:39 2005 Minero Aoki * process.c: new method Process.exec. [ruby-dev:28107] diff --git a/common.mk b/common.mk index 1ea0f04c6a..b191c2e2b5 100644 --- a/common.mk +++ b/common.mk @@ -196,6 +196,7 @@ nt.$(OBJEXT): {$(VPATH)}nt.c x68.$(OBJEXT): {$(VPATH)}x68.c os2.$(OBJEXT): {$(VPATH)}os2.c dl_os2.$(OBJEXT): {$(VPATH)}dl_os2.c +ia64.$(OBJEXT): {$(VPATH)}ia64.s # when I use -I., there is confliction at "OpenFile" # so, set . into environment varible "include" diff --git a/configure.in b/configure.in index 9ecf1ca6e3..8474411e75 100644 --- a/configure.in +++ b/configure.in @@ -451,7 +451,7 @@ AC_CHECK_HEADERS(stdlib.h string.h unistd.h limits.h sys/file.h sys/ioctl.h sys/ fcntl.h sys/fcntl.h sys/select.h sys/time.h sys/times.h sys/param.h\ syscall.h pwd.h grp.h a.out.h utime.h memory.h direct.h sys/resource.h \ sys/mkdev.h sys/utime.h netinet/in_systm.h float.h ieeefp.h pthread.h \ - ucontext.h intrinsics.h unwind.h) + ucontext.h intrinsics.h) dnl Check additional types. AC_CHECK_SIZEOF(rlim_t, 0, [ @@ -612,18 +612,16 @@ AC_C_INLINE AC_C_VOLATILE if test x"$target_cpu" = xia64; then - if test x"$ac_cv_header_unwind_h" = xyes -a x"$ac_cv_func__UNW_createContextForSelf" = xyes; then - LIBS="-lunwind $LIBS" - else - AC_CACHE_CHECK(IA64 backing store member in mcontext_t, rb_cv_ia64_bspstore, - [rb_cv_ia64_bspstore=no; - for mem in mc_special.bspstore sc_ar_bsp; do - AC_TRY_COMPILE([#include -],[ucontext_t ctx; ctx.uc_mcontext.$mem = 0;], [rb_cv_ia64_bspstore=$mem; break]) - done]) - if test "$rb_cv_ia64_bspstore" != no; then - AC_DEFINE_UNQUOTED(IA64_BSPSTORE, $rb_cv_ia64_bspstore) - fi + AC_LIBOBJ([ia64]) + # use IA64 instead of __ia64__ because + # HP aC++ doesn't define it. (HP aC++ define __ia64.) + AC_DEFINE(IA64) + AC_TRY_LINK( + [extern unsigned long __libc_ia64_register_backing_store_base;], + [unsigned long p = __libc_ia64_register_backing_store_base;], + [rb_cv___libc_ia64_register_backing_store_base=yes; break]) + if test $rb_cv___libc_ia64_register_backing_store_base = yes; then + AC_DEFINE(HAVE___LIBC_IA64_REGISTER_BACKING_STORE_BASE) fi fi diff --git a/defines.h b/defines.h index a28530589c..b3371d4b2f 100644 --- a/defines.h +++ b/defines.h @@ -230,9 +230,10 @@ flush_register_windows(void) ; } # define FLUSH_REGISTER_WINDOWS flush_register_windows() -#elif defined(__ia64__) -NOINLINE(void flush_register_windows(void)); -# define FLUSH_REGISTER_WINDOWS flush_register_windows() +#elif defined(IA64) +void *rb_ia64_bsp(void); +void rb_ia64_flushrs(void); +# define FLUSH_REGISTER_WINDOWS rb_ia64_flushrs() #else # define FLUSH_REGISTER_WINDOWS ((void)0) #endif diff --git a/eval.c b/eval.c index 7fde742b2a..24f5663dec 100644 --- a/eval.c +++ b/eval.c @@ -144,7 +144,7 @@ rb_jump_context(env, val) "%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%o7", \ "%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7", \ "%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%i7"); }) -#elif defined(__ia64__) +#elif defined(IA64) static jmp_buf function_call_may_return_twice_jmp_buf; int function_call_may_return_twice_false = 0; #define FUNCTION_CALL_MAY_RETURN_TWICE \ @@ -9482,23 +9482,6 @@ Init_Binding(void) rb_define_global_function("binding", rb_f_binding, 0); } -#ifdef __ia64__ -#if defined(__FreeBSD__) -/* - * FreeBSD/ia64 currently does not have a way for a process to get the - * base address for the RSE backing store, so hardcode it. - */ -#define __libc_ia64_register_backing_store_base (4ULL<<61) -#else -#if defined(HAVE_UNWIND_H) && defined(HAVE__UNW_CREATECONTEXTFORSELF) -#include -#else -#pragma weak __libc_ia64_register_backing_store_base -extern unsigned long __libc_ia64_register_backing_store_base; -#endif -#endif -#endif - /* Windows SEH refers data on the stack. */ #undef SAVE_WIN32_EXCEPTION_LIST #if defined _WIN32 || defined __CYGWIN__ @@ -9713,7 +9696,8 @@ struct thread { long stk_max; VALUE *stk_ptr; VALUE *stk_pos; -#ifdef __ia64__ +#ifdef IA64 + VALUE *bstr_pos; VALUE *bstr_ptr; long bstr_len; #endif @@ -9965,7 +9949,7 @@ thread_mark(rb_thread_t th) #if defined(THINK_C) || defined(__human68k__) rb_gc_mark_locations(th->stk_ptr+2, th->stk_ptr+th->stk_len+2); #endif -#ifdef __ia64__ +#ifdef IA64 if (th->bstr_ptr) { rb_gc_mark_locations(th->bstr_ptr, th->bstr_ptr+th->bstr_len); } @@ -10023,7 +10007,7 @@ thread_free(rb_thread_t th) { if (th->stk_ptr) free(th->stk_ptr); th->stk_ptr = 0; -#ifdef __ia64__ +#ifdef IA64 if (th->bstr_ptr) free(th->bstr_ptr); th->bstr_ptr = 0; #endif @@ -10065,6 +10049,9 @@ static const char *th_signm; #define RESTORE_EXIT 7 extern VALUE *rb_gc_stack_start; +#ifdef IA64 +extern VALUE *rb_gc_register_stack_start; +#endif static void rb_thread_save_context(rb_thread_t th) @@ -10085,27 +10072,11 @@ rb_thread_save_context(rb_thread_t th) th->stk_len = len; FLUSH_REGISTER_WINDOWS; MEMCPY(th->stk_ptr, th->stk_pos, VALUE, th->stk_len); -#ifdef __ia64__ - { - VALUE *top, *bot; -#if defined(HAVE_UNWIND_H) && defined(HAVE__UNW_CREATECONTEXTFORSELF) - _Unwind_Context *unwctx = _UNW_createContextForSelf(); - - _UNW_currentContext(unwctx); - bot = (VALUE*)(long)_UNW_getAR(unwctx, _UNW_AR_BSP); - top = (VALUE*)(long)_UNW_getAR(unwctx, _UNW_AR_BSPSTORE); - _UNW_destroyContext(unwctx); -#else - ucontext_t ctx; - - getcontext(&ctx); - bot = (VALUE*)__libc_ia64_register_backing_store_base; - top = (VALUE*)ctx.uc_mcontext.IA64_BSPSTORE; -#endif - th->bstr_len = top - bot; - REALLOC_N(th->bstr_ptr, VALUE, th->bstr_len); - MEMCPY(th->bstr_ptr, bot, VALUE, th->bstr_len); - } +#ifdef IA64 + th->bstr_pos = rb_gc_register_stack_start; + th->bstr_len = (VALUE*)rb_ia64_bsp() - th->bstr_pos; + REALLOC_N(th->bstr_ptr, VALUE, th->bstr_len); + MEMCPY(th->bstr_ptr, th->bstr_pos, VALUE, th->bstr_len); #endif #ifdef SAVE_WIN32_EXCEPTION_LIST th->win32_exception_list = win32_get_exception_list(); @@ -10181,42 +10152,17 @@ rb_thread_switch(int n) rb_thread_switch((FLUSH_REGISTER_WINDOWS, ruby_setjmp((th)->context)))) NORETURN(static void rb_thread_restore_context(rb_thread_t,int)); -NOINLINE(static void stack_extend(rb_thread_t, int)); +NORETURN(NOINLINE(static void rb_thread_restore_context_0(rb_thread_t,int,void*))); +NORETURN(NOINLINE(static void stack_extend(rb_thread_t, int, VALUE *))); static void -stack_extend(rb_thread_t th, int exit) +rb_thread_restore_context_0(rb_thread_t th, int exit, void *vp) { - VALUE space[1024]; - - memset(space, 0, 1); /* prevent array from optimization */ - rb_thread_restore_context(th, exit); -} - -static void -rb_thread_restore_context(rb_thread_t th, int exit) -{ - VALUE v; + /* vp prevents tail call */ static rb_thread_t tmp; static int ex; static VALUE tval; - 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); - } - else { - /* 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; ruby_scope = th->scope; @@ -10242,20 +10188,8 @@ rb_thread_restore_context(rb_thread_t th, int exit) ex = exit; FLUSH_REGISTER_WINDOWS; MEMCPY(tmp->stk_pos, tmp->stk_ptr, VALUE, tmp->stk_len); -#ifdef __ia64__ - { - VALUE *base; -#if defined(HAVE_UNWIND_H) && defined(HAVE__UNW_CREATECONTEXTFORSELF) - _Unwind_Context *unwctx = _UNW_createContextForSelf(); - - _UNW_currentContext(unwctx); - base = (VALUE*)(long)_UNW_getAR(unwctx, _UNW_AR_BSP); - _UNW_destroyContext(unwctx); -#else - base = (VALUE*)__libc_ia64_register_backing_store_base; -#endif - MEMCPY(base, tmp->bstr_ptr, VALUE, tmp->bstr_len); - } +#ifdef IA64 + MEMCPY(tmp->bstr_pos, tmp->bstr_ptr, VALUE, tmp->bstr_len); #endif tval = rb_lastline_get(); @@ -10268,6 +10202,73 @@ rb_thread_restore_context(rb_thread_t th, int exit) ruby_longjmp(tmp->context, ex); } +#ifdef IA64 +#define C(a) rse_##a##0, rse_##a##1, rse_##a##2, rse_##a##3, rse_##a##4 +#define E(a) rse_##a##0= rse_##a##1= rse_##a##2= rse_##a##3= rse_##a##4 +static volatile int C(a), C(b), C(c), C(d), C(e); +static volatile int C(f), C(g), C(h), C(i), C(j); +static volatile int C(k), C(l), C(m), C(n), C(o); +static volatile int C(p), C(q), C(r), C(s), C(t); +int rb_dummy_false = 0; +NORETURN(NOINLINE(static void register_stack_extend(rb_thread_t, int, void *, VALUE *))); +static void +register_stack_extend(rb_thread_t th, int exit, void *vp, VALUE *curr_bsp) +{ + if (rb_dummy_false) { + /* use registers as much as possible */ + E(a) = E(b) = E(c) = E(d) = E(e) = + E(f) = E(g) = E(h) = E(i) = E(j) = + E(k) = E(l) = E(m) = E(n) = E(o) = + E(p) = E(q) = E(r) = E(s) = E(t) = 0; + E(a) = E(b) = E(c) = E(d) = E(e) = + E(f) = E(g) = E(h) = E(i) = E(j) = + E(k) = E(l) = E(m) = E(n) = E(o) = + E(p) = E(q) = E(r) = E(s) = E(t) = 0; + } + if (curr_bsp < th->bstr_pos+th->bstr_len) { + register_stack_extend(th, exit, &exit, (VALUE*)rb_ia64_bsp()); + } + rb_thread_restore_context_0(th, exit, &exit); +} +#undef C +#undef E +#endif + +static void +stack_extend(rb_thread_t th, int exit, VALUE *addr_in_prev_frame) +{ +#define STACK_PAD_SIZE 1024 + VALUE space[STACK_PAD_SIZE]; + +#if STACK_GROW_DIRECTION < 0 + if (addr_in_prev_frame > th->stk_pos) stack_extend(th, exit, &space[0]); +#elif STACK_GROW_DIRECTION > 0 + if (addr_in_prev_frame < th->stk_pos + th->stk_len) stack_extend(th, exit, &space[STACK_PAD_SIZE-1]); +#else + if (addr_in_prev_frame < rb_gc_stack_start) { + /* Stack grows downward */ + if (addr_in_prev_frame > th->stk_pos) stack_extend(th, exit, &space[0]); + } + else { + /* Stack grows upward */ + if (addr_in_prev_frame < th->stk_pos + th->stk_len) stack_extend(th, exit, &space[STACK_PAD_SIZE-1]); + } +#endif +#ifdef IA64 + register_stack_extend(th, exit, space, (VALUE*)rb_ia64_bsp()); +#else + rb_thread_restore_context_0(th, exit, space); +#endif +} + +static void +rb_thread_restore_context(rb_thread_t th, int exit) +{ + VALUE v; + if (!th->stk_ptr) rb_bug("unsaved context"); + stack_extend(th, exit, &v); +} + static void rb_thread_ready(rb_thread_t th) { @@ -11453,7 +11454,7 @@ rb_thread_group(VALUE thread) return group; } -#ifdef __ia64__ +#ifdef IA64 # define IA64_INIT(x) x #else # define IA64_INIT(x) @@ -13048,13 +13049,3 @@ rb_exec_recursive(VALUE (*func)(VALUE, VALUE, int), VALUE obj, VALUE arg) return result; } } - -/* flush_register_windows must not be inlined because flushrs doesn't flush - * current frame in register stack. */ -#ifdef __ia64__ -void flush_register_windows(void) -{ - __asm__ ("flushrs"); -} -#endif - diff --git a/gc.c b/gc.c index 016b948fed..19de920505 100644 --- a/gc.c +++ b/gc.c @@ -30,24 +30,6 @@ #include #endif -#ifdef __ia64__ -#include -#if defined(__FreeBSD__) -/* - * FreeBSD/ia64 currently does not have a way for a process to get the - * base address for the RSE backing store, so hardcode it. - */ -#define __libc_ia64_register_backing_store_base (4ULL<<61) -#else -#if defined(HAVE_UNWIND_H) && defined(HAVE__UNW_CREATECONTEXTFORSELF) -#include -#else -#pragma weak __libc_ia64_register_backing_store_base -extern unsigned long __libc_ia64_register_backing_store_base; -#endif -#endif -#endif - #if defined _WIN32 || defined __CYGWIN__ #include #endif @@ -429,6 +411,10 @@ rb_data_object_alloc(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_F extern st_table *rb_class_tbl; VALUE *rb_gc_stack_start = 0; +#ifdef IA64 +VALUE *rb_gc_register_stack_start = 0; +#endif + #ifdef DJGPP /* set stack size (http://www.delorie.com/djgpp/v2faq/faq15_9.html) */ @@ -1327,30 +1313,10 @@ garbage_collect(void) else rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END + 1); #endif -#ifdef __ia64__ - /* mark backing store (flushed register window on the stack) */ +#ifdef IA64 + /* mark backing store (flushed register stack) */ /* the basic idea from guile GC code */ - { - ucontext_t ctx; - VALUE *top, *bot; -#if defined(HAVE_UNWIND_H) && defined(HAVE__UNW_CREATECONTEXTFORSELF) - _Unwind_Context *unwctx = _UNW_createContextForSelf(); -#endif - - getcontext(&ctx); - mark_locations_array((VALUE*)&ctx.uc_mcontext, - ((size_t)(sizeof(VALUE)-1 + sizeof ctx.uc_mcontext)/sizeof(VALUE))); -#if defined(HAVE_UNWIND_H) && defined(HAVE__UNW_CREATECONTEXTFORSELF) - _UNW_currentContext(unwctx); - bot = (VALUE*)(long)_UNW_getAR(unwctx, _UNW_AR_BSP); - top = (VALUE*)(long)_UNW_getAR(unwctx, _UNW_AR_BSPSTORE); - _UNW_destroyContext(unwctx); -#else - bot = (VALUE*)__libc_ia64_register_backing_store_base; - top = (VALUE*)ctx.uc_mcontext.IA64_BSPSTORE; -#endif - rb_gc_mark_locations(bot, top); - } + rb_gc_mark_locations(rb_gc_register_stack_start, (VALUE*)rb_ia64_bsp()); #endif #if defined(__human68k__) || defined(__mc68000__) rb_gc_mark_locations((VALUE*)((char*)STACK_END + 2), @@ -1422,6 +1388,28 @@ ruby_set_stack_size(size_t size) void Init_stack(VALUE *addr) { +#ifdef IA64 + if (rb_gc_register_stack_start == 0) { +# if defined(__FreeBSD__) + /* + * FreeBSD/ia64 currently does not have a way for a process to get the + * base address for the RSE backing store, so hardcode it. + */ + rb_gc_register_stack_start = (4ULL<<61); +# elif defined(HAVE___LIBC_IA64_REGISTER_BACKING_STORE_BASE) +# pragma weak __libc_ia64_register_backing_store_base + extern unsigned long __libc_ia64_register_backing_store_base; + rb_gc_register_stack_start = (VALUE*)__libc_ia64_register_backing_store_base; +# endif + } + { + VALUE *bsp = (VALUE*)rb_ia64_bsp(); + if (rb_gc_register_stack_start == 0 || + bsp < rb_gc_register_stack_start) { + rb_gc_register_stack_start = bsp; + } + } +#endif #if defined(_WIN32) || defined(__CYGWIN__) MEMORY_BASIC_INFORMATION m; memset(&m, 0, sizeof(m)); @@ -1430,8 +1418,10 @@ Init_stack(VALUE *addr) STACK_UPPER((VALUE *)&m, (VALUE *)m.BaseAddress, (VALUE *)((char *)m.BaseAddress + m.RegionSize) - 1); #elif defined(STACK_END_ADDRESS) - extern void *STACK_END_ADDRESS; - rb_gc_stack_start = STACK_END_ADDRESS; + { + extern void *STACK_END_ADDRESS; + rb_gc_stack_start = STACK_END_ADDRESS; + } #else if (!addr) addr = (VALUE *)&addr; STACK_UPPER(&addr, addr, ++addr); @@ -1458,6 +1448,37 @@ Init_stack(VALUE *addr) #endif } +void ruby_init_stack(VALUE *addr +#ifdef IA64 + , void *bsp +#endif + ) +{ + if (!rb_gc_stack_start || + STACK_UPPER(&addr, + rb_gc_stack_start > addr, + rb_gc_stack_start < addr)) { + rb_gc_stack_start = addr; + } +#ifdef IA64 + if (!rb_gc_register_stack_start || + (VALUE*)bsp < rb_gc_register_stack_start) { + rb_gc_register_stack_start = (VALUE*)bsp; + } +#endif +#ifdef HAVE_GETRLIMIT + { + struct rlimit rlim; + + if (getrlimit(RLIMIT_STACK, &rlim) == 0) { + unsigned int space = rlim.rlim_cur/5; + + if (space > 1024*1024) space = 1024*1024; + STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE); + } + } +#endif +} /* * Document-class: ObjectSpace diff --git a/ia64.s b/ia64.s new file mode 100644 index 0000000000..b6e30d851d --- /dev/null +++ b/ia64.s @@ -0,0 +1,34 @@ +// rb_ia64_flushrs and rb_ia64_bsp is written in IA64 assembly language +// because Intel Compiler for IA64 doesn't support inline assembly. +// +// This file is based on following C program compiled by gcc. +// +// void rb_ia64_flushrs(void) { __builtin_ia64_flushrs(); } +// void *rb_ia64_bsp(void) { return __builtin_ia64_bsp(); } +// + .file "ia64.c" + .pred.safe_across_calls p1-p5,p16-p63 + .text + .align 16 + .global rb_ia64_flushrs# + .proc rb_ia64_flushrs# +rb_ia64_flushrs: + .prologue + .body + flushrs + ;; + nop.i 0 + br.ret.sptk.many b0 + .endp rb_ia64_flushrs# + .align 16 + .global rb_ia64_bsp# + .proc rb_ia64_bsp# +rb_ia64_bsp: + .prologue + .body + nop.m 0 + ;; + mov r8 = ar.bsp + br.ret.sptk.many b0 + .endp rb_ia64_bsp# + .ident "GCC: (GNU) 3.3.5 (Debian 1:3.3.5-13)" diff --git a/main.c b/main.c index 35dfc9ece1..4d5f2896e6 100644 --- a/main.c +++ b/main.c @@ -36,8 +36,11 @@ main(int argc, char **argv, char **envp) argc = ccommand(&argv); #endif - ruby_init(); - ruby_options(argc, argv); - ruby_run(); + { + RUBY_INIT_STACK + ruby_init(); + ruby_options(argc, argv); + ruby_run(); + } return 0; } diff --git a/numeric.c b/numeric.c index 91e7dfc1e7..b036d06421 100644 --- a/numeric.c +++ b/numeric.c @@ -1975,6 +1975,10 @@ static VALUE fix_mul(VALUE x, VALUE y) { if (FIXNUM_P(y)) { +#ifdef __HP_cc +/* avoids an optimization bug of HP aC++/ANSI C B3910B A.06.05 [Jul 25 2005] */ + volatile +#endif long a, b, c; VALUE r; diff --git a/ruby.h b/ruby.h index 91a0e619ab..c21661f1d2 100644 --- a/ruby.h +++ b/ruby.h @@ -583,6 +583,17 @@ NORETURN(void rb_throw(const char*,VALUE)); VALUE rb_require(const char*); +#ifdef IA64 +void ruby_init_stack(VALUE*, void*); +#define RUBY_INIT_STACK \ + VALUE variable_in_this_stack_frame; \ + ruby_init_stack(&variable_in_this_stack_frame, rb_ia64_bsp()); +#else +void ruby_init_stack(VALUE*); +#define RUBY_INIT_STACK \ + VALUE variable_in_this_stack_frame; \ + ruby_init_stack(&variable_in_this_stack_frame); +#endif void ruby_init(void); void ruby_options(int, char**); NORETURN(void ruby_run(void)); -- cgit v1.2.3