diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-11-19 05:03:03 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-11-19 05:03:03 +0000 |
commit | df96f994f1a224070ffaa61eb2bcb969d0109246 (patch) | |
tree | 2e4bd7b58a1bc0a2b8d0e136f79a2997323e54d6 /gc.c | |
parent | d550569264a16e96121d05423f7516ce726d96c9 (diff) |
* parse.y (parse_regx): should raise error on untermitated
expression interpolation.
* pack.c (pack_unpack): should give length to utf8_to_uv().
* pack.c (utf8_to_uv): add length check.
* massages: replace "wrong #" by "wrong number".
* marshal.c (w_float): output Infinity and NaN explicitly.
* marshal.c (r_object): support new explicit float format.
* eval.c (rb_thread_wait_for): select may cause ERESTART on
Solaris.
* eval.c (rb_thread_select): ditto.
* array.c (rb_ary_join): dumped core if sep is not T_STRING nor T_NIL.
* array.c (rb_ary_join): buffer size calculattion was wrong.
* array.c (rb_ary_to_s): if rb_output_fs is nil, insert newlines
between array elements (use rb_default_rs as newline litral)
[experimental].
* gc.c (init_mark_stack): no need to clear mark_stack.
* gc.c (gc_mark_all): need to handle finalizer mark.
* gc.c (gc_mark_rest): use MEMCPY instead of memcpy.
* gc.c (rb_gc_mark): earlier const check to avoid pusing special
constants into mark stack.
* numeric.c (fix_to_s): 'to_s' now takes optional argument to
specify radix. [new]
* bignum.c (rb_big_to_s): ditto. [new]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1842 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r-- | gc.c | 131 |
1 files changed, 88 insertions, 43 deletions
@@ -21,6 +21,10 @@ #include <stdio.h> #include <setjmp.h> +#ifdef HAVE_SYS_RESOURCE_H +#include <sys/resource.h> +#endif + void re_free_registers _((struct re_registers*)); void rb_io_fptr_finalize _((struct OpenFile*)); @@ -345,6 +349,68 @@ rb_data_object_alloc(klass, datap, dmark, dfree) extern st_table *rb_class_tbl; VALUE *rb_gc_stack_start = 0; +#ifdef DJGPP +static unsigned int STACK_LEVEL_MAX = 65535; +#else +#ifdef __human68k__ +extern unsigned int _stacksize; +# define STACK_LEVEL_MAX (_stacksize - 4096) +# undef HAVE_GETRLIMIT +#else +#ifdef HAVE_GETRLIMIT +static unsigned int STACK_LEVEL_MAX = 655300; +#else +# define STACK_LEVEL_MAX 655300 +#endif +#endif +#endif + +#ifdef C_ALLOCA +# define SET_STACK_END VALUE stack_end; alloca(0); +# define STACK_END (&stack_end) +#else +# if defined(__GNUC__) && defined(USE_BUILTIN_FRAME_ADDRESS) +# define SET_STACK_END VALUE *stack_end = __builtin_frame_address(0); +# else +# define SET_STACK_END VALUE *stack_end = alloca(1); +# endif +# define STACK_END (stack_end) +#endif +#ifdef __sparc__ +# define STACK_LENGTH (rb_gc_stack_start - STACK_END + 0x80) +#else +# define STACK_LENGTH ((STACK_END < rb_gc_stack_start) ? rb_gc_stack_start - STACK_END\ + : STACK_END - rb_gc_stack_start) +#endif + +#define CHECK_STACK(ret) do {\ + SET_STACK_END;\ + (ret) = (STACK_LENGTH > STACK_LEVEL_MAX);\ +} while (0)\ + +int +ruby_stack_length(p) + VALUE **p; +{ + int ret; + + SET_STACK_END; + if (p) *p = STACK_END; + return STACK_LENGTH; +} + +static VALUE rb_eSysStackError; + +void +ruby_stack_check() +{ + int ret; + + CHECK_STACK(ret); + if (ret) { + rb_raise(rb_eSysStackError, "stack level too deep"); + } +} #define MARK_STACK_MAX 1024 static VALUE mark_stack[MARK_STACK_MAX]; @@ -356,7 +422,6 @@ init_mark_stack() { mark_stack_overflow = 0; mark_stack_ptr = mark_stack; - memset(mark_stack, 0, MARK_STACK_MAX); } #define MARK_STACK_EMPTY (mark_stack_ptr == mark_stack) @@ -375,8 +440,8 @@ gc_mark_all() for (i = 0; i < heaps_used; i++) { p = heaps[i]; pend = p + heaps_limits[i]; while (p < pend) { - if (!(rb_special_const_p((VALUE)p)) - && p->as.basic.flags&FL_MARK) { + if ((p->as.basic.flags & FL_MARK) && + (p->as.basic.flags != FL_MARK)) { rb_gc_mark_children((VALUE)p); } p++; @@ -392,8 +457,8 @@ gc_mark_rest() VALUE *p; p = (mark_stack_ptr - mark_stack) + tmp_arry; - memcpy(tmp_arry, mark_stack, MARK_STACK_MAX); - + MEMCPY(tmp_arry, mark_stack, VALUE, MARK_STACK_MAX); + init_mark_stack(); while(p != tmp_arry){ @@ -402,39 +467,6 @@ gc_mark_rest() } } -#if defined(DJGPP) -# define STACK_LEVEL_MAX 65535; -#elif defined(__human68k__) -extern unsigned int _stacksize; -# define STACK_LEVEL_MAX (_stacksize - 4096) -#else -# define STACK_LEVEL_MAX 655300 -#endif - -#ifdef C_ALLOCA -# define SET_STACK_END VALUE stack_end; alloca(0); -# define STACK_END (&stack_end) -#else -# if defined(__GNUC__) && defined(USE_BUILTIN_FRAME_ADDRESS) -# define SET_STACK_END VALUE *stack_end = __builtin_frame_address(0); -# else -# define SET_STACK_END VALUE *stack_end = alloca(1); -# endif -# define STACK_END (stack_end) -#endif -#ifdef __sparc__ -# define STACK_LENGTH (rb_gc_stack_start - STACK_END + 0x80) -#else -# define STACK_LENGTH ((STACK_END < rb_gc_stack_start) ? rb_gc_stack_start - STACK_END\ - : STACK_END - rb_gc_stack_start) -#endif - -#define CHECK_STACK(ret) do {\ - SET_STACK_END;\ - ret = (STACK_LENGTH > STACK_LEVEL_MAX);\ -} while (0)\ - - static inline int is_pointer_to_heap(ptr) void *ptr; @@ -534,6 +566,10 @@ rb_gc_mark(ptr) { register RVALUE *obj = RANY(ptr); + if (rb_special_const_p(ptr)) return; /* special const not marked */ + if (obj->as.basic.flags == 0) return; /* free cell */ + if (obj->as.basic.flags & FL_MARK) return; /* already marked */ + if (!mark_stack_overflow){ int ret; CHECK_STACK(ret); @@ -544,15 +580,10 @@ rb_gc_mark(ptr) return; }else{ mark_stack_overflow = 1; - printf("mark_stack_overflow\n"); } } } - if (rb_special_const_p((VALUE)obj)) return; /* special const not marked */ - if (obj->as.basic.flags == 0) return; /* free cell */ - if (obj->as.basic.flags & FL_MARK) return; /* already marked */ - obj->as.basic.flags |= FL_MARK; if (mark_stack_overflow){ @@ -1171,6 +1202,18 @@ Init_stack(addr) if (!addr) addr = &start; rb_gc_stack_start = addr; #endif +#ifdef HAVE_GETRLIMIT + { + struct rlimit rlim; + + if (getrlimit(RLIMIT_STACK, &rlim) == 0) { + double space = (double)rlim.rlim_cur*0.2; + + if (space > 1024*1024) space = 1024*1024; + STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE); + } + } +#endif } void @@ -1474,4 +1517,6 @@ Init_GC() rb_global_variable(&finalizers); rb_gc_unregister_address(&rb_mObSpace); finalizers = rb_ary_new(); + + rb_eSysStackError = rb_define_class("SystemStackError", rb_eStandardError); } |