mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* eval.c (POP_VARS): should not set DVAR_DONT_RECYCLE if _old
ruby_vars is already force_recycled. * gc.c (rb_gc): handles mark stack overflow. * gc.c (PUSH_MARK): use static mark stack, no more recursion. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1807 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									4c9362b74f
								
							
						
					
					
						commit
						c0fe73989d
					
				
					 6 changed files with 167 additions and 65 deletions
				
			
		
							
								
								
									
										11
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								ChangeLog
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,14 @@
 | 
			
		|||
Wed Oct 31 15:09:28 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* eval.c (POP_VARS): should not set DVAR_DONT_RECYCLE if _old
 | 
			
		||||
	  ruby_vars is already force_recycled.
 | 
			
		||||
 | 
			
		||||
Wed Oct 31 10:28:49 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* gc.c (rb_gc): handles mark stack overflow.
 | 
			
		||||
 | 
			
		||||
	* gc.c (PUSH_MARK): use static mark stack, no more recursion.
 | 
			
		||||
 | 
			
		||||
Wed Oct 31 02:44:06 2001  Wakou Aoyama  <wakou@fsinet.or.jp>
 | 
			
		||||
 | 
			
		||||
	* lib/cgi.rb: CGI::Cookie::parse(): Ignore duplicate keys caused by
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								config.sub
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								config.sub
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -117,7 +117,7 @@ esac
 | 
			
		|||
# Here we must recognize all the valid KERNEL-OS combinations.
 | 
			
		||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 | 
			
		||||
case $maybe_os in
 | 
			
		||||
  nto-qnx* | linux-gnu* | storm-chaos* | os2-emx*)
 | 
			
		||||
  nto-qnx* | linux-gnu* | linux-libc1 | storm-chaos* | os2-emx*)
 | 
			
		||||
    os=-$maybe_os
 | 
			
		||||
    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
 | 
			
		||||
    ;;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								eval.c
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								eval.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -600,8 +600,10 @@ struct RVarmap *ruby_dyna_vars;
 | 
			
		|||
    ruby_dyna_vars = 0;
 | 
			
		||||
 | 
			
		||||
#define POP_VARS() \
 | 
			
		||||
   if (_old && (ruby_scope->flags & SCOPE_DONT_RECYCLE)) \
 | 
			
		||||
   if (_old && (ruby_scope->flags & SCOPE_DONT_RECYCLE)) {\
 | 
			
		||||
       if (RBASIC(_old)->flags) /* unless it's already recycled */ \
 | 
			
		||||
           FL_SET(_old, DVAR_DONT_RECYCLE); \
 | 
			
		||||
    }\
 | 
			
		||||
    ruby_dyna_vars = _old; \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										180
									
								
								gc.c
									
										
									
									
									
								
							
							
						
						
									
										180
									
								
								gc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -135,7 +135,7 @@ ruby_xrealloc(ptr, size)
 | 
			
		|||
	rb_gc();
 | 
			
		||||
	RUBY_CRITICAL(mem = realloc(ptr, size));
 | 
			
		||||
	if (!mem) {
 | 
			
		||||
	    if (size >= 50 * 1024 * 1024) {
 | 
			
		||||
	    if (size >= 10 * 1024 * 1024) {
 | 
			
		||||
		rb_raise(rb_eNoMemError, "tried to re-allocate too big memory");
 | 
			
		||||
	    }
 | 
			
		||||
	    mem_error("failed to allocate memory(realloc)");
 | 
			
		||||
| 
						 | 
				
			
			@ -182,7 +182,7 @@ VALUE rb_mGC;
 | 
			
		|||
static struct gc_list {
 | 
			
		||||
    VALUE *varptr;
 | 
			
		||||
    struct gc_list *next;
 | 
			
		||||
} *Global_List = 0;
 | 
			
		||||
} *global_List = 0;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
rb_gc_register_address(addr)
 | 
			
		||||
| 
						 | 
				
			
			@ -191,19 +191,19 @@ rb_gc_register_address(addr)
 | 
			
		|||
    struct gc_list *tmp;
 | 
			
		||||
 | 
			
		||||
    tmp = ALLOC(struct gc_list);
 | 
			
		||||
    tmp->next = Global_List;
 | 
			
		||||
    tmp->next = global_List;
 | 
			
		||||
    tmp->varptr = addr;
 | 
			
		||||
    Global_List = tmp;
 | 
			
		||||
    global_List = tmp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
rb_gc_unregister_address(addr)
 | 
			
		||||
    VALUE *addr;
 | 
			
		||||
{
 | 
			
		||||
    struct gc_list *tmp = Global_List;
 | 
			
		||||
    struct gc_list *tmp = global_List;
 | 
			
		||||
 | 
			
		||||
    if (tmp->varptr == addr) {
 | 
			
		||||
	Global_List = tmp->next;
 | 
			
		||||
	global_List = tmp->next;
 | 
			
		||||
	RUBY_CRITICAL(free(tmp));
 | 
			
		||||
	return;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -249,6 +249,7 @@ typedef struct RVALUE {
 | 
			
		|||
	struct RVarmap varmap; 
 | 
			
		||||
	struct SCOPE   scope;
 | 
			
		||||
    } as;
 | 
			
		||||
    int type;
 | 
			
		||||
} RVALUE;
 | 
			
		||||
 | 
			
		||||
static RVALUE *freelist = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -301,7 +302,7 @@ add_heap()
 | 
			
		|||
    if (lomem == 0 || lomem > p) lomem = p;
 | 
			
		||||
    if (himem < pend) himem = pend;
 | 
			
		||||
    heaps_used++;
 | 
			
		||||
    heap_slots *= 2;
 | 
			
		||||
    heap_slots *= 1.5;
 | 
			
		||||
 | 
			
		||||
    while (p < pend) {
 | 
			
		||||
	p->as.free.flags = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -364,6 +365,33 @@ is_pointer_to_heap(ptr)
 | 
			
		|||
    return Qfalse;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define MARK_STACK_SIZE 4096
 | 
			
		||||
static VALUE mark_stack_base[MARK_STACK_SIZE];
 | 
			
		||||
static VALUE *mark_stack;
 | 
			
		||||
static int mark_stack_overflow = 0;
 | 
			
		||||
 | 
			
		||||
#define PUSH_MARK(obj) do {\
 | 
			
		||||
    if (!mark_stack_overflow) {\
 | 
			
		||||
	if (mark_stack - mark_stack_base >= MARK_STACK_SIZE) {\
 | 
			
		||||
	    mark_stack_overflow = 1;\
 | 
			
		||||
printf("mark stack overflow\n");\
 | 
			
		||||
	}\
 | 
			
		||||
	else {\
 | 
			
		||||
	    if (   rb_special_const_p(obj) /* special const not marked */\
 | 
			
		||||
		|| RBASIC(obj)->flags == 0 /* free cell */\
 | 
			
		||||
		|| FL_TEST((obj),FL_MARK)) /* already marked */ {\
 | 
			
		||||
	    }\
 | 
			
		||||
	    else {\
 | 
			
		||||
		*mark_stack++ = (obj);\
 | 
			
		||||
	    }\
 | 
			
		||||
	}\
 | 
			
		||||
    }\
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
#define POP_MARK() (*--mark_stack)
 | 
			
		||||
 | 
			
		||||
#define MARK_EMPTY() (mark_stack == mark_stack_base)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
mark_locations_array(x, n)
 | 
			
		||||
    register VALUE *x;
 | 
			
		||||
| 
						 | 
				
			
			@ -437,19 +465,14 @@ rb_gc_mark_maybe(obj)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
rb_gc_mark(ptr)
 | 
			
		||||
static void
 | 
			
		||||
gc_mark_children(ptr)
 | 
			
		||||
    VALUE ptr;
 | 
			
		||||
{
 | 
			
		||||
    register RVALUE *obj = RANY(ptr);
 | 
			
		||||
 | 
			
		||||
  Top:
 | 
			
		||||
    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 (FL_TEST(obj, FL_EXIVAR)) {
 | 
			
		||||
	rb_mark_generic_ivar((VALUE)obj);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -470,7 +493,7 @@ rb_gc_mark(ptr)
 | 
			
		|||
	  case NODE_MASGN:
 | 
			
		||||
	  case NODE_RESCUE:
 | 
			
		||||
	  case NODE_RESBODY:
 | 
			
		||||
	    rb_gc_mark((VALUE)obj->as.node.u2.node);
 | 
			
		||||
	    PUSH_MARK((VALUE)obj->as.node.u2.node);
 | 
			
		||||
	    /* fall through */
 | 
			
		||||
	  case NODE_BLOCK:	/* 1,3 */
 | 
			
		||||
	  case NODE_ARRAY:
 | 
			
		||||
| 
						 | 
				
			
			@ -484,14 +507,14 @@ rb_gc_mark(ptr)
 | 
			
		|||
	  case NODE_CALL:
 | 
			
		||||
	  case NODE_DEFS:
 | 
			
		||||
	  case NODE_OP_ASGN1:
 | 
			
		||||
	    rb_gc_mark((VALUE)obj->as.node.u1.node);
 | 
			
		||||
	    PUSH_MARK((VALUE)obj->as.node.u1.node);
 | 
			
		||||
	    /* fall through */
 | 
			
		||||
	  case NODE_SUPER:	/* 3 */
 | 
			
		||||
	  case NODE_FCALL:
 | 
			
		||||
	  case NODE_DEFN:
 | 
			
		||||
	  case NODE_NEWLINE:
 | 
			
		||||
	    obj = RANY(obj->as.node.u3.node);
 | 
			
		||||
	    goto Top;
 | 
			
		||||
	    goto Again;
 | 
			
		||||
 | 
			
		||||
	  case NODE_WHILE:	/* 1,2 */
 | 
			
		||||
	  case NODE_UNTIL:
 | 
			
		||||
| 
						 | 
				
			
			@ -507,7 +530,7 @@ rb_gc_mark(ptr)
 | 
			
		|||
	  case NODE_MATCH3:
 | 
			
		||||
	  case NODE_OP_ASGN_OR:
 | 
			
		||||
	  case NODE_OP_ASGN_AND:
 | 
			
		||||
	    rb_gc_mark((VALUE)obj->as.node.u1.node);
 | 
			
		||||
	    PUSH_MARK((VALUE)obj->as.node.u1.node);
 | 
			
		||||
	    /* fall through */
 | 
			
		||||
	  case NODE_METHOD:	/* 2 */
 | 
			
		||||
	  case NODE_NOT:
 | 
			
		||||
| 
						 | 
				
			
			@ -523,7 +546,7 @@ rb_gc_mark(ptr)
 | 
			
		|||
	  case NODE_COLON3:
 | 
			
		||||
	  case NODE_OPT_N:
 | 
			
		||||
	    obj = RANY(obj->as.node.u2.node);
 | 
			
		||||
	    goto Top;
 | 
			
		||||
	    goto Again;
 | 
			
		||||
 | 
			
		||||
	  case NODE_HASH:	/* 1 */
 | 
			
		||||
	  case NODE_LIT:
 | 
			
		||||
| 
						 | 
				
			
			@ -538,14 +561,14 @@ rb_gc_mark(ptr)
 | 
			
		|||
	  case NODE_COLON2:
 | 
			
		||||
	  case NODE_ARGS:
 | 
			
		||||
	    obj = RANY(obj->as.node.u1.node);
 | 
			
		||||
	    goto Top;
 | 
			
		||||
	    goto Again;
 | 
			
		||||
 | 
			
		||||
	  case NODE_SCOPE:	/* 2,3 */
 | 
			
		||||
	  case NODE_CLASS:
 | 
			
		||||
	  case NODE_BLOCK_PASS:
 | 
			
		||||
	    rb_gc_mark((VALUE)obj->as.node.u3.node);
 | 
			
		||||
	    PUSH_MARK((VALUE)obj->as.node.u3.node);
 | 
			
		||||
	    obj = RANY(obj->as.node.u2.node);
 | 
			
		||||
	    goto Top;
 | 
			
		||||
	    goto Again;
 | 
			
		||||
 | 
			
		||||
	  case NODE_ZARRAY:	/* - */
 | 
			
		||||
	  case NODE_ZSUPER:
 | 
			
		||||
| 
						 | 
				
			
			@ -577,53 +600,59 @@ rb_gc_mark(ptr)
 | 
			
		|||
	    mark_locations_array((VALUE*)obj->as.node.u1.value,
 | 
			
		||||
				 obj->as.node.u3.cnt);
 | 
			
		||||
	    obj = RANY(obj->as.node.u2.node);
 | 
			
		||||
	    goto Top;
 | 
			
		||||
	    goto Again;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	  default:
 | 
			
		||||
	    if (is_pointer_to_heap(obj->as.node.u1.node)) {
 | 
			
		||||
		rb_gc_mark((VALUE)obj->as.node.u1.node);
 | 
			
		||||
		PUSH_MARK((VALUE)obj->as.node.u1.node);
 | 
			
		||||
	    }
 | 
			
		||||
	    if (is_pointer_to_heap(obj->as.node.u2.node)) {
 | 
			
		||||
		rb_gc_mark((VALUE)obj->as.node.u2.node);
 | 
			
		||||
		PUSH_MARK((VALUE)obj->as.node.u2.node);
 | 
			
		||||
	    }
 | 
			
		||||
	    if (is_pointer_to_heap(obj->as.node.u3.node)) {
 | 
			
		||||
		obj = RANY(obj->as.node.u3.node);
 | 
			
		||||
		goto Top;
 | 
			
		||||
		goto Again;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
	return;			/* no need to mark class. */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rb_gc_mark(obj->as.basic.klass);
 | 
			
		||||
    PUSH_MARK(obj->as.basic.klass);
 | 
			
		||||
    switch (obj->as.basic.flags & T_MASK) {
 | 
			
		||||
      case T_ICLASS:
 | 
			
		||||
      case T_CLASS:
 | 
			
		||||
      case T_MODULE:
 | 
			
		||||
	rb_gc_mark(obj->as.klass.super);
 | 
			
		||||
	PUSH_MARK(obj->as.klass.super);
 | 
			
		||||
	rb_mark_tbl(obj->as.klass.m_tbl);
 | 
			
		||||
	rb_mark_tbl(obj->as.klass.iv_tbl);
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      case T_ARRAY:
 | 
			
		||||
      {
 | 
			
		||||
	    int i, len = obj->as.array.len;
 | 
			
		||||
	  int i, len = obj->as.array.len - 1;
 | 
			
		||||
	  VALUE *ptr = obj->as.array.ptr;
 | 
			
		||||
 | 
			
		||||
	    for (i=0; i < len; i++)
 | 
			
		||||
		rb_gc_mark(*ptr++);
 | 
			
		||||
	  for (i=0; i < len; i++) {
 | 
			
		||||
	      PUSH_MARK(*ptr);
 | 
			
		||||
	      ptr++;
 | 
			
		||||
	  }
 | 
			
		||||
	  if (len >= 0) {
 | 
			
		||||
	      obj = RANY(*ptr);
 | 
			
		||||
	      goto Again;
 | 
			
		||||
	  }
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
      case T_HASH:
 | 
			
		||||
	rb_mark_hash(obj->as.hash.tbl);
 | 
			
		||||
	rb_gc_mark(obj->as.hash.ifnone);
 | 
			
		||||
	PUSH_MARK(obj->as.hash.ifnone);
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      case T_STRING:
 | 
			
		||||
	if (obj->as.string.orig) {
 | 
			
		||||
	    obj = RANY(obj->as.string.orig);
 | 
			
		||||
	    goto Top;
 | 
			
		||||
	    goto Again;
 | 
			
		||||
	}
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -645,14 +674,14 @@ rb_gc_mark(ptr)
 | 
			
		|||
      case T_MATCH:
 | 
			
		||||
	if (obj->as.match.str) {
 | 
			
		||||
	    obj = RANY(obj->as.match.str);
 | 
			
		||||
	    goto Top;
 | 
			
		||||
	    goto Again;
 | 
			
		||||
	}
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      case T_VARMAP:
 | 
			
		||||
	rb_gc_mark(obj->as.varmap.val);
 | 
			
		||||
	PUSH_MARK(obj->as.varmap.val);
 | 
			
		||||
	obj = RANY(obj->as.varmap.next);
 | 
			
		||||
	goto Top;
 | 
			
		||||
	goto Again;
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      case T_SCOPE:
 | 
			
		||||
| 
						 | 
				
			
			@ -661,7 +690,7 @@ rb_gc_mark(ptr)
 | 
			
		|||
	    VALUE *vars = &obj->as.scope.local_vars[-1];
 | 
			
		||||
 | 
			
		||||
	    while (n--) {
 | 
			
		||||
		rb_gc_mark(*vars);
 | 
			
		||||
		PUSH_MARK(*vars);
 | 
			
		||||
		vars++;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -669,11 +698,17 @@ rb_gc_mark(ptr)
 | 
			
		|||
 | 
			
		||||
      case T_STRUCT:
 | 
			
		||||
      {
 | 
			
		||||
	    int i, len = obj->as.rstruct.len;
 | 
			
		||||
	  int i, len = obj->as.rstruct.len - 1;
 | 
			
		||||
	  VALUE *ptr = obj->as.rstruct.ptr;
 | 
			
		||||
 | 
			
		||||
	    for (i=0; i < len; i++)
 | 
			
		||||
		rb_gc_mark(*ptr++);
 | 
			
		||||
	  for (i=0; i < len; i++) {
 | 
			
		||||
	      PUSH_MARK(*ptr);
 | 
			
		||||
	      ptr++;
 | 
			
		||||
	  }
 | 
			
		||||
	  if (len >= 0) {
 | 
			
		||||
	      obj = RANY(ptr);
 | 
			
		||||
	      goto Again;
 | 
			
		||||
	  }
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -682,6 +717,31 @@ rb_gc_mark(ptr)
 | 
			
		|||
	       obj->as.basic.flags & T_MASK, obj,
 | 
			
		||||
	       is_pointer_to_heap(obj)?"corrupted object":"non object");
 | 
			
		||||
    }
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  Again:    
 | 
			
		||||
    if (rb_special_const_p(obj)) return; /* special const not marked */
 | 
			
		||||
    if (RBASIC(obj)->flags == 0) return; /* free cell */
 | 
			
		||||
    if (FL_TEST((obj),FL_MARK)) return;  /* already marked */
 | 
			
		||||
    goto Top;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
rb_gc_mark(ptr)
 | 
			
		||||
    VALUE ptr;
 | 
			
		||||
{
 | 
			
		||||
    if (rb_special_const_p(ptr)) return; /* special const not marked */
 | 
			
		||||
    if (RBASIC(ptr)->flags == 0) return; /* free cell */
 | 
			
		||||
    if (FL_TEST((ptr),FL_MARK)) return;  /* already marked */
 | 
			
		||||
    gc_mark_children(ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
gc_mark()
 | 
			
		||||
{
 | 
			
		||||
    while (!MARK_EMPTY()) {
 | 
			
		||||
	rb_gc_mark(POP_MARK());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void obj_free _((VALUE));
 | 
			
		||||
| 
						 | 
				
			
			@ -691,24 +751,31 @@ gc_sweep()
 | 
			
		|||
{
 | 
			
		||||
    RVALUE *p, *pend, *final_list;
 | 
			
		||||
    int freed = 0;
 | 
			
		||||
    int i, used = heaps_used;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    if (ruby_in_compile) {
 | 
			
		||||
	int marked = 0;
 | 
			
		||||
 | 
			
		||||
	/* should not reclaim nodes during compilation */
 | 
			
		||||
	for (i = 0; i < used; i++) {
 | 
			
		||||
	for (i = 0; i < heaps_used; i++) {
 | 
			
		||||
	    p = heaps[i]; pend = p + heaps_limits[i];
 | 
			
		||||
	    while (p < pend) {
 | 
			
		||||
		if (!(p->as.basic.flags&FL_MARK) && BUILTIN_TYPE(p) == T_NODE)
 | 
			
		||||
		if (!(p->as.basic.flags&FL_MARK) && BUILTIN_TYPE(p) == T_NODE) {
 | 
			
		||||
		    rb_gc_mark((VALUE)p);
 | 
			
		||||
		    marked = 1;
 | 
			
		||||
		}
 | 
			
		||||
		p++;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
	if (marked) {
 | 
			
		||||
	    gc_mark();
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    freelist = 0;
 | 
			
		||||
    final_list = deferred_final_list;
 | 
			
		||||
    deferred_final_list = 0;
 | 
			
		||||
    for (i = 0; i < used; i++) {
 | 
			
		||||
    for (i = 0; i < heaps_used; i++) {
 | 
			
		||||
	int n = 0;
 | 
			
		||||
 | 
			
		||||
	p = heaps[i]; pend = p + heaps_limits[i];
 | 
			
		||||
| 
						 | 
				
			
			@ -768,6 +835,7 @@ void
 | 
			
		|||
rb_gc_force_recycle(p)
 | 
			
		||||
    VALUE p;
 | 
			
		||||
{
 | 
			
		||||
    RANY(p)->type = BUILTIN_TYPE(p);
 | 
			
		||||
    RANY(p)->as.free.flags = 0;
 | 
			
		||||
    RANY(p)->as.free.next = freelist;
 | 
			
		||||
    freelist = RANY(p);
 | 
			
		||||
| 
						 | 
				
			
			@ -897,7 +965,7 @@ obj_free(obj)
 | 
			
		|||
	break;
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
	rb_bug("gc_sweep(): unknown data type %d",
 | 
			
		||||
	rb_bug("gc_sweep(): unknown data type 0x%x(%d)", obj,
 | 
			
		||||
	       RANY(obj)->as.basic.flags & T_MASK);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -980,6 +1048,8 @@ rb_gc()
 | 
			
		|||
    if (during_gc) return;
 | 
			
		||||
    during_gc++;
 | 
			
		||||
 | 
			
		||||
    mark_stack = mark_stack_base;
 | 
			
		||||
    mark_stack_overflow = 0;
 | 
			
		||||
    /* mark frame stack */
 | 
			
		||||
    for (frame = ruby_frame; frame; frame = frame->prev) {
 | 
			
		||||
	rb_gc_mark_frame(frame); 
 | 
			
		||||
| 
						 | 
				
			
			@ -1010,7 +1080,7 @@ rb_gc()
 | 
			
		|||
    rb_gc_mark_threads();
 | 
			
		||||
 | 
			
		||||
    /* mark protected global variables */
 | 
			
		||||
    for (list = Global_List; list; list = list->next) {
 | 
			
		||||
    for (list = global_List; list; list = list->next) {
 | 
			
		||||
	rb_gc_mark(*list->varptr);
 | 
			
		||||
    }
 | 
			
		||||
    rb_mark_end_proc();
 | 
			
		||||
| 
						 | 
				
			
			@ -1022,6 +1092,24 @@ rb_gc()
 | 
			
		|||
    /* mark generic instance variables for special constants */
 | 
			
		||||
    rb_mark_generic_ivar_tbl();
 | 
			
		||||
 | 
			
		||||
    gc_mark();
 | 
			
		||||
    while (mark_stack_overflow) {
 | 
			
		||||
	RVALUE *p, *pend;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	mark_stack_overflow = 0;
 | 
			
		||||
	for (i = 0; i < heaps_used; i++) {
 | 
			
		||||
	    p = heaps[i]; pend = p + heaps_limits[i];
 | 
			
		||||
	    while (p < pend) {
 | 
			
		||||
		if (p->as.basic.flags&FL_MARK) {
 | 
			
		||||
		    gc_mark_children((VALUE)p);
 | 
			
		||||
		}
 | 
			
		||||
		p++;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
	gc_mark();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    gc_sweep();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								string.c
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								string.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1101,7 +1101,8 @@ rb_str_aref(str, indx)
 | 
			
		|||
	return rb_str_subpat(str, indx, 0);
 | 
			
		||||
 | 
			
		||||
      case T_STRING:
 | 
			
		||||
	if (rb_str_index(str, indx, 0) != -1) return indx;
 | 
			
		||||
	if (rb_str_index(str, indx, 0) != -1)
 | 
			
		||||
	    return rb_str_dup(indx);
 | 
			
		||||
	return Qnil;
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
#define RUBY_VERSION "1.7.1"
 | 
			
		||||
#define RUBY_RELEASE_DATE "2001-10-30"
 | 
			
		||||
#define RUBY_RELEASE_DATE "2001-10-31"
 | 
			
		||||
#define RUBY_VERSION_CODE 171
 | 
			
		||||
#define RUBY_RELEASE_CODE 20011030
 | 
			
		||||
#define RUBY_RELEASE_CODE 20011031
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue