[前][次][番号順一覧][スレッド一覧]

ruby-changes:6414

From: shyouhei <ko1@a...>
Date: Mon, 7 Jul 2008 15:19:18 +0900 (JST)
Subject: [ruby-changes:6414] Ruby:r17930 (ruby_1_8_7): merge revision(s) 17832:

shyouhei	2008-07-07 15:17:24 +0900 (Mon, 07 Jul 2008)

  New Revision: 17930

  Modified files:
    branches/ruby_1_8_7/ChangeLog
    branches/ruby_1_8_7/eval.c
    branches/ruby_1_8_7/gc.c
    branches/ruby_1_8_7/node.h
    branches/ruby_1_8_7/version.h

  Log:
    merge revision(s) 17832:
    * eval.c (rb_longjmp): duplicate the thrown exception to set backtrace
      if it was frozen.  clear all raised flags.
    * eval.c (stack_check): leave clearing flag to rb_longjmp.
    * eval.c (rb_thread_set_raised, rb_thread_reset_raised): use generic
      flags.
    * eval.c (Init_Proc), gc.c (Init_GC): freeze preallocated special exceptions.
    * gc.c (rb_memerror): use thread raised flag instead of static flag,
      and raise nomem_error without backtrace if failed to make backtrace.
      [ruby-dev:34724]
    * gc.c (ruby_xmalloc): increase malloc_increase only if malloc
      succeeds.  failed malloc size can be huge.  it may increase
      malloc_limit too big which cause less GC and memory full.
      (ruby_xrealloc): ditto.


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=17930

Index: ruby_1_8_7/ChangeLog
===================================================================
--- ruby_1_8_7/ChangeLog	(revision 17929)
+++ ruby_1_8_7/ChangeLog	(revision 17930)
@@ -1,3 +1,24 @@
+Mon Jul  7 15:02:13 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* eval.c (rb_longjmp): duplicate the thrown exception to set backtrace
+	  if it was frozen.  clear all raised flags.
+
+	* eval.c (stack_check): leave clearing flag to rb_longjmp.
+
+	* eval.c (rb_thread_set_raised, rb_thread_reset_raised): use generic
+	  flags.
+
+	* eval.c (Init_Proc), gc.c (Init_GC): freeze preallocated special exceptions.
+
+	* gc.c (rb_memerror): use thread raised flag instead of static flag,
+	  and raise nomem_error without backtrace if failed to make backtrace.
+	  [ruby-dev:34724]
+
+	* gc.c (ruby_xmalloc): increase malloc_increase only if malloc
+	  succeeds.  failed malloc size can be huge.  it may increase
+	  malloc_limit too big which cause less GC and memory full.
+	  (ruby_xrealloc): ditto.
+
 Mon Jul  7 12:23:05 2008  Masaki Suketa  <masaki.suketa@n...>
 
 	* ext/win32ole/win32ole.c: avoid creating Ruby object during
Index: ruby_1_8_7/version.h
===================================================================
--- ruby_1_8_7/version.h	(revision 17929)
+++ ruby_1_8_7/version.h	(revision 17930)
@@ -2,7 +2,7 @@
 #define RUBY_RELEASE_DATE "2008-07-07"
 #define RUBY_VERSION_CODE 187
 #define RUBY_RELEASE_CODE 20080707
-#define RUBY_PATCHLEVEL 48
+#define RUBY_PATCHLEVEL 49
 
 #define RUBY_VERSION_MAJOR 1
 #define RUBY_VERSION_MINOR 8
Index: ruby_1_8_7/eval.c
===================================================================
--- ruby_1_8_7/eval.c	(revision 17929)
+++ ruby_1_8_7/eval.c	(revision 17930)
@@ -1441,9 +1441,6 @@
 static void rb_thread_cleanup _((void));
 static void rb_thread_wait_other_threads _((void));
 
-static int thread_set_raised();
-static int thread_reset_raised();
-
 static int thread_no_ensure _((void));
 
 static VALUE exception_error;
@@ -1462,8 +1459,10 @@
     int ex;
 {
     int status = EXIT_FAILURE;
+    rb_thread_t th = curr_thread;
 
-    if (thread_set_raised()) return EXIT_FAILURE;
+    if (rb_thread_set_raised(th))
+	return EXIT_FAILURE;
     switch (ex & TAG_MASK) {
       case 0:
 	status = EXIT_SUCCESS;
@@ -1516,7 +1515,7 @@
 	rb_bug("Unknown longjmp status %d", ex);
 	break;
     }
-    thread_reset_raised();
+    rb_thread_reset_raised(th);
     return status;
 }
 
@@ -2709,6 +2708,7 @@
     NODE *node_save;
     VALUE srcfile;
     const char *event_name;
+    rb_thread_t th = curr_thread;
 
     if (!trace_func) return;
     if (tracing) return;
@@ -2740,7 +2740,7 @@
 	}
     }
     PUSH_TAG(PROT_NONE);
-    raised = thread_reset_raised();
+    raised = rb_thread_reset_raised(th);
     if ((state = EXEC_TAG()) == 0) {
 	srcfile = rb_str_new2(ruby_sourcefile?ruby_sourcefile:"(ruby)");
 	event_name = get_event_name(event);
@@ -2752,7 +2752,7 @@
 					    klass),
 		    Qundef, 0);
     }
-    if (raised) thread_set_raised();
+    if (raised) rb_thread_set_raised(th);
     POP_TAG();
     POP_FRAME();
 
@@ -4571,8 +4571,9 @@
     VALUE mesg;
 {
     VALUE at;
+    rb_thread_t th = curr_thread;
 
-    if (thread_set_raised()) {
+    if (rb_thread_set_raised(th)) {
 	ruby_errinfo = exception_error;
 	JUMP_TAG(TAG_FATAL);
     }
@@ -4586,6 +4587,9 @@
 	at = get_backtrace(mesg);
 	if (NIL_P(at)) {
 	    at = make_backtrace();
+	    if (OBJ_FROZEN(mesg)) {
+		mesg = rb_obj_dup(mesg);
+	    }
 	    set_backtrace(mesg, at);
 	}
     }
@@ -4611,7 +4615,7 @@
 	    ruby_errinfo = mesg;
 	}
 	else if (status) {
-	    thread_reset_raised();
+	    rb_thread_reset_raised(th);
 	    JUMP_TAG(status);
 	}
     }
@@ -4626,11 +4630,20 @@
     if (!prot_tag) {
 	error_print();
     }
-    thread_reset_raised();
+    rb_thread_raised_clear(th);
     JUMP_TAG(tag);
 }
 
 void
+rb_exc_jump(mesg)
+    VALUE mesg;
+{
+    rb_thread_raised_clear(rb_curr_thread);
+    ruby_errinfo = mesg;
+    JUMP_TAG(TAG_RAISE);
+}
+
+void
 rb_exc_raise(mesg)
     VALUE mesg;
 {
@@ -5578,18 +5591,11 @@
 static void
 stack_check()
 {
-    static int overflowing = 0;
+    rb_thread_t th = rb_curr_thread;
 
-    if (!overflowing && ruby_stack_check()) {
-	int state;
-	overflowing = 1;
-	PUSH_TAG(PROT_NONE);
-	if ((state = EXEC_TAG()) == 0) {
-	    rb_exc_raise(sysstack_error);
-	}
-	POP_TAG();
-	overflowing = 0;
-	JUMP_TAG(state);
+    if (!rb_thread_raised_p(th, RAISED_STACKOVERFLOW) && ruby_stack_check()) {
+	rb_thread_raised_set(th, RAISED_STACKOVERFLOW);
+	rb_exc_raise(sysstack_error);
     }
 }
 
@@ -9987,11 +9993,14 @@
 
     rb_global_variable(&exception_error);
     exception_error = rb_exc_new2(rb_eFatal, "exception reentered");
+    OBJ_TAINT(exception_error);
+    OBJ_FREEZE(exception_error);
 
     rb_eSysStackError = rb_define_class("SystemStackError", rb_eStandardError);
     rb_global_variable(&sysstack_error);
     sysstack_error = rb_exc_new2(rb_eSysStackError, "stack level too deep");
     OBJ_TAINT(sysstack_error);
+    OBJ_FREEZE(sysstack_error);
 
     rb_cProc = rb_define_class("Proc", rb_cObject);
     rb_undef_alloc_func(rb_cProc);
@@ -10169,10 +10178,9 @@
 # endif
 #endif
 
-#define THREAD_RAISED 0x200	 /* temporary flag */
 #define THREAD_TERMINATING 0x400 /* persistent flag */
-#define THREAD_NO_ENSURE 0x800   /* persistent flag */
-#define THREAD_FLAGS_MASK  0xc00 /* mask for persistent flags */
+#define THREAD_NO_ENSURE   0x800 /* persistent flag */
+#define THREAD_FLAGS_MASK 0xfc00 /* mask for persistent flags */
 
 #define FOREACH_THREAD_FROM(f,x) x = f; do { x = x->next;
 #define END_FOREACH_FROM(f,x) } while (x != f)
@@ -10224,19 +10232,25 @@
     (dst)->join = (src)->join,			\
     0)
 
-static int
-thread_set_raised()
+int
+rb_thread_set_raised(th)
+    rb_thread_t th;
 {
-    if (curr_thread->flags & THREAD_RAISED) return 1;
-    curr_thread->flags |= THREAD_RAISED;
+    if (th->flags & RAISED_EXCEPTION) {
+	return 1;
+    }
+    th->flags |= RAISED_EXCEPTION;
     return 0;
 }
 
-static int
-thread_reset_raised()
+int
+rb_thread_reset_raised(th)
+    rb_thread_t th;
 {
-    if (!(curr_thread->flags & THREAD_RAISED)) return 0;
-    curr_thread->flags &= ~THREAD_RAISED;
+    if (!(th->flags & RAISED_EXCEPTION)) {
+	return 0;
+    }
+    th->flags &= ~RAISED_EXCEPTION;
     return 1;
 }
 
@@ -11374,7 +11388,7 @@
 	if (!rb_thread_dead(th)) return Qfalse;
     }
 
-    if (!NIL_P(th->errinfo) && (th->flags & THREAD_RAISED)) {
+    if (!NIL_P(th->errinfo) && (th->flags & RAISED_EXCEPTION)) {
 	VALUE oldbt = get_backtrace(th->errinfo);
 	VALUE errat = make_backtrace();
 	VALUE errinfo = rb_obj_dup(th->errinfo);
@@ -12250,7 +12264,7 @@
     }
 
     if (state && status != THREAD_TO_KILL && !NIL_P(ruby_errinfo)) {
-	th->flags |= THREAD_RAISED;
+	th->flags |= RAISED_EXCEPTION;
 	if (state == TAG_FATAL) {
 	    /* fatal error within this thread, need to stop whole script */
 	    main_thread->errinfo = ruby_errinfo;
@@ -12468,7 +12482,7 @@
     rb_thread_t th = rb_thread_check(thread);
 
     if (rb_thread_dead(th)) {
-	if (!NIL_P(th->errinfo) && (th->flags & THREAD_RAISED))
+	if (!NIL_P(th->errinfo) && (th->flags & RAISED_EXCEPTION))
 	    return Qnil;
 	return Qfalse;
     }
Index: ruby_1_8_7/gc.c
===================================================================
--- ruby_1_8_7/gc.c	(revision 17929)
+++ ruby_1_8_7/gc.c	(revision 17930)
@@ -78,16 +78,22 @@
 
 int ruby_gc_stress = 0;
 
+NORETURN(void rb_exc_jump _((VALUE)));
+
 void
 rb_memerror()
 {
-    static int recurse = 0;
+    rb_thread_t th = rb_curr_thread;
 
-    if (!nomem_error || (recurse > 0 && rb_safe_level() < 4)) {
+    if (!nomem_error ||
+	(rb_thread_raised_p(th, RAISED_NOMEMORY) && rb_safe_level() < 4)) {
 	fprintf(stderr, "[FATAL] failed to allocate memory\n");
 	exit(1);
     }
-    recurse++;
+    if (rb_thread_raised_p(th, RAISED_NOMEMORY)) {
+	rb_exc_jump(nomem_error);
+    }
+    rb_thread_raised_set(th, RAISED_NOMEMORY);
     rb_exc_raise(nomem_error);
 }
 
@@ -136,9 +142,8 @@
 	rb_raise(rb_eNoMemError, "negative allocation size (or too big)");
     }
     if (size == 0) size = 1;
-    malloc_increase += size;
 
-    if (ruby_gc_stress || malloc_increase > malloc_limit) {
+    if (ruby_gc_stress || (malloc_increase+size) > malloc_limit) {
 	garbage_collect();
     }
     RUBY_CRITICAL(mem = malloc(size));
@@ -149,6 +154,7 @@
 	    rb_memerror();
 	}
     }
+    malloc_increase += size;
 
     return mem;
 }
@@ -177,7 +183,6 @@
     }
     if (!ptr) return xmalloc(size);
     if (size == 0) size = 1;
-    malloc_increase += size;
     if (ruby_gc_stress) garbage_collect();
     RUBY_CRITICAL(mem = realloc(ptr, size));
     if (!mem) {
@@ -187,6 +192,7 @@
 	    rb_memerror();
         }
     }
+    malloc_increase += size;
 
     return mem;
 }
@@ -2110,6 +2116,8 @@
 
     rb_global_variable(&nomem_error);
     nomem_error = rb_exc_new2(rb_eNoMemError, "failed to allocate memory");
+    OBJ_TAINT(nomem_error);
+    OBJ_FREEZE(nomem_error);
 
     rb_define_method(rb_mKernel, "hash", rb_obj_id, 0);
     rb_define_method(rb_mKernel, "__id__", rb_obj_id, 0);
Index: ruby_1_8_7/node.h
===================================================================
--- ruby_1_8_7/node.h	(revision 17929)
+++ ruby_1_8_7/node.h	(revision 17930)
@@ -468,6 +468,19 @@
 extern rb_thread_t rb_curr_thread;
 extern rb_thread_t rb_main_thread;
 
+enum {
+    RAISED_EXCEPTION     = 0x1000,
+    RAISED_STACKOVERFLOW = 0x2000,
+    RAISED_NOMEMORY      = 0x4000,
+    RAISED_MASK          = 0xf000
+};
+int rb_thread_set_raised(rb_thread_t th);
+int rb_thread_reset_raised(rb_thread_t th);
+#define rb_thread_raised_set(th, f)   ((th)->flags |= (f))
+#define rb_thread_raised_reset(th, f) ((th)->flags &= ~(f))
+#define rb_thread_raised_p(th, f)     (((th)->flags & (f)) != 0)
+#define rb_thread_raised_clear(th)    ((th)->flags = 0)
+
 #if defined(__cplusplus)
 }  /* extern "C" { */
 #endif

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]