mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* 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
This commit is contained in:
		
							parent
							
								
									baf0ba4588
								
							
						
					
					
						commit
						f59bd226b3
					
				
					 10 changed files with 262 additions and 158 deletions
				
			
		
							
								
								
									
										40
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										40
									
								
								ChangeLog
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,43 @@
 | 
			
		|||
Tue Dec 27 14:17:55 2005  Tanaka Akira  <akr@m17n.org>
 | 
			
		||||
 | 
			
		||||
	* 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  <aamine@loveruby.net>
 | 
			
		||||
 | 
			
		||||
	* process.c: new method Process.exec. [ruby-dev:28107]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										24
									
								
								configure.in
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								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.h>
 | 
			
		||||
],[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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										183
									
								
								eval.c
									
										
									
									
									
								
							
							
						
						
									
										183
									
								
								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 <unwind.h>
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										107
									
								
								gc.c
									
										
									
									
									
								
							
							
						
						
									
										107
									
								
								gc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -30,24 +30,6 @@
 | 
			
		|||
#include <sys/resource.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __ia64__
 | 
			
		||||
#include <ucontext.h>
 | 
			
		||||
#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 <unwind.h>
 | 
			
		||||
#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 <windows.h>
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										34
									
								
								ia64.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								ia64.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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)"
 | 
			
		||||
							
								
								
									
										9
									
								
								main.c
									
										
									
									
									
								
							
							
						
						
									
										9
									
								
								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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								ruby.h
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								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));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue