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

ruby-changes:58186

From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Thu, 10 Oct 2019 12:10:30 +0900 (JST)
Subject: [ruby-changes:58186] 9c3153e0da (master): allow rb_raise from outside of GVL

https://git.ruby-lang.org/ruby.git/commit/?id=9c3153e0da

From 9c3153e0da991e1a7df9b4cf91d6830effc79b22 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?=
 <shyouhei@r...>
Date: Thu, 10 Oct 2019 11:55:43 +0900
Subject: allow rb_raise from outside of GVL

Now that allocation routines like ALLOC_N() can raise exceptions
on integer overflows.  This is a problem when the calling thread
has no GVL.  Memory allocations has been allowed without it, but
can still fail.

Let's just relax rb_raise's restriction so that we can call it
with or without GVL.  With GVL the behaviour is unchanged.  With
no GVL, wait for it.

Also, integer overflows can theoretically occur during GC when
we expand the object space.  We cannot do so much then.  Call
rb_memerror and let that routine abort the process.

diff --git a/common.mk b/common.mk
index ff56a0c..236d40e 100644
--- a/common.mk
+++ b/common.mk
@@ -1942,6 +1942,7 @@ error.$(OBJEXT): $(CCAN_DIR)/list/list.h https://github.com/ruby/ruby/blob/trunk/common.mk#L1942
 error.$(OBJEXT): $(CCAN_DIR)/str/str.h
 error.$(OBJEXT): $(hdrdir)/ruby.h
 error.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+error.$(OBJEXT): $(hdrdir)/ruby/thread.h
 error.$(OBJEXT): {$(VPATH)}assert.h
 error.$(OBJEXT): {$(VPATH)}config.h
 error.$(OBJEXT): {$(VPATH)}defines.h
diff --git a/error.c b/error.c
index e29910a..3a63a5f 100644
--- a/error.c
+++ b/error.c
@@ -11,6 +11,7 @@ https://github.com/ruby/ruby/blob/trunk/error.c#L11
 
 #include "ruby/encoding.h"
 #include "ruby/st.h"
+#include "ruby/thread.h"
 #include "internal.h"
 #include "ruby_assert.h"
 #include "vm_core.h"
@@ -2604,16 +2605,46 @@ rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...) https://github.com/ruby/ruby/blob/trunk/error.c#L2605
     rb_exc_raise(rb_exc_new3(exc, mesg));
 }
 
+struct rb_raise_tag {
+    VALUE exc;
+    const char *fmt;
+    va_list *args;
+};
+
+static void *
+rb_vraise(void *ptr)
+{
+    struct rb_raise_tag *argv = ptr;
+    VALUE msg = rb_vsprintf(argv->fmt, *argv->args);
+    VALUE exc = rb_exc_new3(argv->exc, msg);
+    rb_exc_raise(exc);
+    UNREACHABLE_RETURN(NULL);
+}
+
 void
 rb_raise(VALUE exc, const char *fmt, ...)
 {
     va_list args;
-    VALUE mesg;
-
     va_start(args, fmt);
-    mesg = rb_vsprintf(fmt, args);
+    struct rb_raise_tag argv = {
+        exc, fmt, &args,
+    };
+
+    if (ruby_thread_has_gvl_p()) {
+        rb_vraise(&argv);
+        UNREACHABLE;
+    }
+    else if (ruby_native_thread_p()) {
+        rb_thread_call_with_gvl(rb_vraise, &argv);
+        UNREACHABLE;
+    }
+    else {
+        /* Not in a ruby thread */
+        vfprintf(stderr, fmt, args);
+        abort();
+    }
+
     va_end(args);
-    rb_exc_raise(rb_exc_new3(exc, mesg));
 }
 
 NORETURN(static void raise_loaderror(VALUE path, VALUE mesg));
diff --git a/gc.c b/gc.c
index f429237..cc4ea12 100644
--- a/gc.c
+++ b/gc.c
@@ -172,6 +172,9 @@ size_mul_or_raise(size_t x, size_t y, VALUE exc) https://github.com/ruby/ruby/blob/trunk/gc.c#L172
     if (LIKELY(!t.left)) {
         return t.right;
     }
+    else if (rb_during_gc()) {
+        rb_memerror();          /* or...? */
+    }
     else {
         rb_raise(
             exc,
@@ -195,6 +198,9 @@ size_mul_add_or_raise(size_t x, size_t y, size_t z, VALUE exc) https://github.com/ruby/ruby/blob/trunk/gc.c#L198
     if (LIKELY(!t.left)) {
         return t.right;
     }
+    else if (rb_during_gc()) {
+        rb_memerror();          /* or...? */
+    }
     else {
         rb_raise(
             exc,
@@ -219,6 +225,9 @@ size_mul_add_mul_or_raise(size_t x, size_t y, size_t z, size_t w, VALUE exc) https://github.com/ruby/ruby/blob/trunk/gc.c#L225
     if (LIKELY(!t.left)) {
         return t.right;
     }
+    else if (rb_during_gc()) {
+        rb_memerror();          /* or...? */
+    }
     else {
         rb_raise(
             exc,
@@ -9590,28 +9599,10 @@ objspace_reachable_objects_from_root(rb_objspace_t *objspace, void (func)(const https://github.com/ruby/ruby/blob/trunk/gc.c#L9599
 
 static void objspace_xfree(rb_objspace_t *objspace, void *ptr, size_t size);
 
-static void *
-negative_size_allocation_error_with_gvl(void *ptr)
-{
-    rb_raise(rb_eNoMemError, "%s", (const char *)ptr);
-    return 0; /* should not be reached */
-}
-
 static void
 negative_size_allocation_error(const char *msg)
 {
-    if (ruby_thread_has_gvl_p()) {
-	rb_raise(rb_eNoMemError, "%s", msg);
-    }
-    else {
-	if (ruby_native_thread_p()) {
-	    rb_thread_call_with_gvl(negative_size_allocation_error_with_gvl, (void *)msg);
-	}
-	else {
-	    fprintf(stderr, "[FATAL] %s\n", msg);
-	    exit(EXIT_FAILURE);
-	}
-    }
+    rb_raise(rb_eNoMemError, "%s", msg);
 }
 
 static void *
-- 
cgit v0.10.2


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

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