* gc.c (gc_mark): explicitly check mark recursion levels, instead

of unreliable stack length.

* file.c (path_check_1): honor sticky bits always.
  [ruby-talk:86273]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5057 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2003-11-28 14:23:33 +00:00
parent daa1423dea
commit 5eaf7e5816
5 changed files with 92 additions and 41 deletions

View File

@ -1,3 +1,8 @@
Fri Nov 28 23:19:34 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* gc.c (gc_mark): explicitly check mark recursion levels, instead
of unreliable stack length.
Fri Nov 28 22:49:56 2003 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp> Fri Nov 28 22:49:56 2003 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp>
* lib/rinda/rinda.rb: fix TupleSpaceProxy#read, read_all. * lib/rinda/rinda.rb: fix TupleSpaceProxy#read, read_all.
@ -108,6 +113,11 @@ Tue Nov 25 21:41:35 2003 NAKAMURA Usaku <usa@ruby-lang.org>
* hash.c (env_has_value, env_index): don't ignore case of value. * hash.c (env_has_value, env_index): don't ignore case of value.
[ruby-dev:22048] [ruby-dev:22048]
Tue Nov 25 21:39:37 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* file.c (path_check_1): honor sticky bits always.
[ruby-talk:86273]
Tue Nov 25 20:02:14 2003 Minero Aoki <aamine@loveruby.net> Tue Nov 25 20:02:14 2003 Minero Aoki <aamine@loveruby.net>
* test/fileutils/test_fileutils.rb: do test in more deep * test/fileutils/test_fileutils.rb: do test in more deep

2
file.c
View File

@ -2653,7 +2653,7 @@ path_check_1(path)
#endif #endif
if (stat(p0, &st) == 0 && S_ISDIR(st.st_mode) && (st.st_mode & S_IWOTH) if (stat(p0, &st) == 0 && S_ISDIR(st.st_mode) && (st.st_mode & S_IWOTH)
#ifdef S_ISVTX #ifdef S_ISVTX
&& (!p || !(st.st_mode & S_ISVTX)) && !(st.st_mode & S_ISVTX)
#endif #endif
) { ) {
rb_warn("Insecure world writable dir %s, mode 0%o", p0, st.st_mode); rb_warn("Insecure world writable dir %s, mode 0%o", p0, st.st_mode);

109
gc.c
View File

@ -504,7 +504,8 @@ sweep_source_filename(key, value)
} }
} }
static void rb_gc_mark_children _((VALUE ptr)); static void gc_mark _((VALUE ptr, int lev));
static void gc_mark_children _((VALUE ptr, int lev));
static void static void
gc_mark_all() gc_mark_all()
@ -518,7 +519,7 @@ gc_mark_all()
while (p < pend) { while (p < pend) {
if ((p->as.basic.flags & FL_MARK) && if ((p->as.basic.flags & FL_MARK) &&
(p->as.basic.flags != FL_MARK)) { (p->as.basic.flags != FL_MARK)) {
rb_gc_mark_children((VALUE)p); gc_mark_children((VALUE)p, 0);
} }
p++; p++;
} }
@ -537,7 +538,7 @@ gc_mark_rest()
init_mark_stack(); init_mark_stack();
while(p != tmp_arry){ while(p != tmp_arry){
p--; p--;
rb_gc_mark_children(*p); gc_mark_children(*p, 0);
} }
} }
@ -568,7 +569,7 @@ mark_locations_array(x, n)
{ {
while (n--) { while (n--) {
if (is_pointer_to_heap((void *)*x)) { if (is_pointer_to_heap((void *)*x)) {
rb_gc_mark(*x); gc_mark(*x, 0);
} }
x++; x++;
} }
@ -586,38 +587,56 @@ rb_gc_mark_locations(start, end)
} }
static int static int
mark_entry(key, value) mark_entry(key, value, lev)
ID key; ID key;
VALUE value; VALUE value;
int lev;
{ {
rb_gc_mark(value); gc_mark(value, lev);
return ST_CONTINUE; return ST_CONTINUE;
} }
void
mark_tbl(tbl, lev)
st_table *tbl;
int lev;
{
if (!tbl) return;
st_foreach(tbl, mark_entry, lev+1);
}
void void
rb_mark_tbl(tbl) rb_mark_tbl(tbl)
st_table *tbl; st_table *tbl;
{ {
if (!tbl) return; mark_tbl(tbl, 0);
st_foreach(tbl, mark_entry, 0);
} }
static int static int
mark_keyvalue(key, value) mark_keyvalue(key, value, lev)
VALUE key; VALUE key;
VALUE value; VALUE value;
int lev;
{ {
rb_gc_mark(key); gc_mark(key, lev);
rb_gc_mark(value); gc_mark(value, lev);
return ST_CONTINUE; return ST_CONTINUE;
} }
void
mark_hash(tbl, lev)
st_table *tbl;
int lev;
{
if (!tbl) return;
st_foreach(tbl, mark_keyvalue, lev+1);
}
void void
rb_mark_hash(tbl) rb_mark_hash(tbl)
st_table *tbl; st_table *tbl;
{ {
if (!tbl) return; mark_hash(tbl, 0);
st_foreach(tbl, mark_keyvalue, 0);
} }
void void
@ -625,13 +644,16 @@ rb_gc_mark_maybe(obj)
VALUE obj; VALUE obj;
{ {
if (is_pointer_to_heap((void *)obj)) { if (is_pointer_to_heap((void *)obj)) {
rb_gc_mark(obj); gc_mark(obj, 0);
} }
} }
#define GC_LEVEL_MAX 250
void void
rb_gc_mark(ptr) gc_mark(ptr, lev)
VALUE ptr; VALUE ptr;
int lev;
{ {
int ret; int ret;
register RVALUE *obj; register RVALUE *obj;
@ -642,8 +664,7 @@ rb_gc_mark(ptr)
if (obj->as.basic.flags & FL_MARK) return; /* already marked */ if (obj->as.basic.flags & FL_MARK) return; /* already marked */
obj->as.basic.flags |= FL_MARK; obj->as.basic.flags |= FL_MARK;
CHECK_STACK(ret); if (lev > GC_LEVEL_MAX) {
if (ret) {
if (!mark_stack_overflow) { if (!mark_stack_overflow) {
if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) {
*mark_stack_ptr = ptr; *mark_stack_ptr = ptr;
@ -655,12 +676,20 @@ rb_gc_mark(ptr)
} }
return; return;
} }
rb_gc_mark_children(ptr); gc_mark_children(ptr, lev);
}
void
rb_gc_mark(ptr)
VALUE ptr;
{
gc_mark(ptr, 0);
} }
static void static void
rb_gc_mark_children(ptr) gc_mark_children(ptr, lev)
VALUE ptr; VALUE ptr;
int lev;
{ {
register RVALUE *obj = RANY(ptr); register RVALUE *obj = RANY(ptr);
@ -696,7 +725,7 @@ rb_gc_mark_children(ptr)
case NODE_RESCUE: case NODE_RESCUE:
case NODE_RESBODY: case NODE_RESBODY:
case NODE_CLASS: case NODE_CLASS:
rb_gc_mark((VALUE)obj->as.node.u2.node); gc_mark((VALUE)obj->as.node.u2.node, lev);
/* fall through */ /* fall through */
case NODE_BLOCK: /* 1,3 */ case NODE_BLOCK: /* 1,3 */
case NODE_ARRAY: case NODE_ARRAY:
@ -709,7 +738,7 @@ rb_gc_mark_children(ptr)
case NODE_CALL: case NODE_CALL:
case NODE_DEFS: case NODE_DEFS:
case NODE_OP_ASGN1: case NODE_OP_ASGN1:
rb_gc_mark((VALUE)obj->as.node.u1.node); gc_mark((VALUE)obj->as.node.u1.node, lev);
/* fall through */ /* fall through */
case NODE_SUPER: /* 3 */ case NODE_SUPER: /* 3 */
case NODE_FCALL: case NODE_FCALL:
@ -733,7 +762,7 @@ rb_gc_mark_children(ptr)
case NODE_OP_ASGN_OR: case NODE_OP_ASGN_OR:
case NODE_OP_ASGN_AND: case NODE_OP_ASGN_AND:
case NODE_MODULE: case NODE_MODULE:
rb_gc_mark((VALUE)obj->as.node.u1.node); gc_mark((VALUE)obj->as.node.u1.node, lev);
/* fall through */ /* fall through */
case NODE_METHOD: /* 2 */ case NODE_METHOD: /* 2 */
case NODE_NOT: case NODE_NOT:
@ -771,7 +800,7 @@ rb_gc_mark_children(ptr)
case NODE_SCOPE: /* 2,3 */ case NODE_SCOPE: /* 2,3 */
case NODE_BLOCK_PASS: case NODE_BLOCK_PASS:
case NODE_CDECL: case NODE_CDECL:
rb_gc_mark((VALUE)obj->as.node.u3.node); gc_mark((VALUE)obj->as.node.u3.node, lev);
ptr = (VALUE)obj->as.node.u2.node; ptr = (VALUE)obj->as.node.u2.node;
goto again; goto again;
@ -809,25 +838,25 @@ rb_gc_mark_children(ptr)
default: /* unlisted NODE */ default: /* unlisted NODE */
if (is_pointer_to_heap(obj->as.node.u1.node)) { if (is_pointer_to_heap(obj->as.node.u1.node)) {
rb_gc_mark((VALUE)obj->as.node.u1.node); gc_mark((VALUE)obj->as.node.u1.node, lev);
} }
if (is_pointer_to_heap(obj->as.node.u2.node)) { if (is_pointer_to_heap(obj->as.node.u2.node)) {
rb_gc_mark((VALUE)obj->as.node.u2.node); gc_mark((VALUE)obj->as.node.u2.node, lev);
} }
if (is_pointer_to_heap(obj->as.node.u3.node)) { if (is_pointer_to_heap(obj->as.node.u3.node)) {
rb_gc_mark((VALUE)obj->as.node.u3.node); gc_mark((VALUE)obj->as.node.u3.node, lev);
} }
} }
return; /* no need to mark class. */ return; /* no need to mark class. */
} }
rb_gc_mark(obj->as.basic.klass); gc_mark(obj->as.basic.klass, lev);
switch (obj->as.basic.flags & T_MASK) { switch (obj->as.basic.flags & T_MASK) {
case T_ICLASS: case T_ICLASS:
case T_CLASS: case T_CLASS:
case T_MODULE: case T_MODULE:
rb_mark_tbl(obj->as.klass.m_tbl); mark_tbl(obj->as.klass.m_tbl, lev);
rb_mark_tbl(obj->as.klass.iv_tbl); mark_tbl(obj->as.klass.iv_tbl, lev);
ptr = obj->as.klass.super; ptr = obj->as.klass.super;
goto again; goto again;
@ -841,13 +870,13 @@ rb_gc_mark_children(ptr)
VALUE *ptr = obj->as.array.ptr; VALUE *ptr = obj->as.array.ptr;
for (i=0; i < len; i++) { for (i=0; i < len; i++) {
rb_gc_mark(*ptr++); gc_mark(*ptr++, lev);
} }
} }
break; break;
case T_HASH: case T_HASH:
rb_mark_hash(obj->as.hash.tbl); mark_hash(obj->as.hash.tbl, lev);
ptr = obj->as.hash.ifnone; ptr = obj->as.hash.ifnone;
goto again; goto again;
@ -864,7 +893,7 @@ rb_gc_mark_children(ptr)
break; break;
case T_OBJECT: case T_OBJECT:
rb_mark_tbl(obj->as.object.iv_tbl); mark_tbl(obj->as.object.iv_tbl, lev);
break; break;
case T_FILE: case T_FILE:
@ -882,7 +911,7 @@ rb_gc_mark_children(ptr)
break; break;
case T_VARMAP: case T_VARMAP:
rb_gc_mark(obj->as.varmap.val); gc_mark(obj->as.varmap.val, lev);
ptr = (VALUE)obj->as.varmap.next; ptr = (VALUE)obj->as.varmap.next;
goto again; goto again;
@ -892,7 +921,7 @@ rb_gc_mark_children(ptr)
VALUE *vars = &obj->as.scope.local_vars[-1]; VALUE *vars = &obj->as.scope.local_vars[-1];
while (n--) { while (n--) {
rb_gc_mark(*vars++); gc_mark(*vars++, lev);
} }
} }
break; break;
@ -903,7 +932,7 @@ rb_gc_mark_children(ptr)
VALUE *ptr = obj->as.rstruct.ptr; VALUE *ptr = obj->as.rstruct.ptr;
while (len--) { while (len--) {
rb_gc_mark(*ptr++); gc_mark(*ptr++, lev);
} }
} }
break; break;
@ -932,7 +961,7 @@ gc_sweep()
p = heaps[i].slot; pend = p + heaps[i].limit; p = heaps[i].slot; pend = p + heaps[i].limit;
while (p < pend) { 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); gc_mark((VALUE)p, 0);
p++; p++;
} }
} }
@ -1175,7 +1204,7 @@ rb_gc_mark_frame(frame)
struct FRAME *frame; struct FRAME *frame;
{ {
mark_locations_array(frame->argv, frame->argc); mark_locations_array(frame->argv, frame->argc);
rb_gc_mark((VALUE)frame->node); gc_mark((VALUE)frame->node, 0);
} }
#ifdef __GNUC__ #ifdef __GNUC__
@ -1251,10 +1280,10 @@ rb_gc()
} }
} }
} }
rb_gc_mark((VALUE)ruby_scope); gc_mark((VALUE)ruby_scope, 0);
rb_gc_mark((VALUE)ruby_dyna_vars); gc_mark((VALUE)ruby_dyna_vars, 0);
if (finalizer_table) { if (finalizer_table) {
rb_mark_tbl(finalizer_table); mark_tbl(finalizer_table, 0);
} }
FLUSH_REGISTER_WINDOWS; FLUSH_REGISTER_WINDOWS;

View File

@ -272,6 +272,7 @@ class Context
while prompt and input = readline("(rdb:%d) "%thnum(), true) while prompt and input = readline("(rdb:%d) "%thnum(), true)
catch(:debug_error) do catch(:debug_error) do
if input == "" if input == ""
next unless DEBUG_LAST_CMD[0]
input = DEBUG_LAST_CMD[0] input = DEBUG_LAST_CMD[0]
stdout.print input, "\n" stdout.print input, "\n"
else else

11
time.c
View File

@ -1009,6 +1009,16 @@ time_minus(time1, time2)
return time2; return time2;
} }
static VALUE
time_succ(time)
VALUE time;
{
struct time_object *tobj;
GetTimeval(time, tobj);
return rb_time_new(tobj->tv.tv_sec + 1, tobj->tv.tv_usec);
}
static VALUE static VALUE
time_sec(time) time_sec(time)
VALUE time; VALUE time;
@ -1471,6 +1481,7 @@ Init_Time()
rb_define_method(rb_cTime, "+", time_plus, 1); rb_define_method(rb_cTime, "+", time_plus, 1);
rb_define_method(rb_cTime, "-", time_minus, 1); rb_define_method(rb_cTime, "-", time_minus, 1);
rb_define_method(rb_cTime, "succ", time_succ, 0);
rb_define_method(rb_cTime, "sec", time_sec, 0); rb_define_method(rb_cTime, "sec", time_sec, 0);
rb_define_method(rb_cTime, "min", time_min, 0); rb_define_method(rb_cTime, "min", time_min, 0);
rb_define_method(rb_cTime, "hour", time_hour, 0); rb_define_method(rb_cTime, "hour", time_hour, 0);