summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author卜部昌平 <shyouhei@ruby-lang.org>2019-10-10 17:04:59 +0900
committer卜部昌平 <shyouhei@ruby-lang.org>2019-10-10 17:10:21 +0900
commitf1ce4897f2eaf9a99c250e4707e3ab6f6bdacb74 (patch)
treeb4aaa154bd492888f2e978805a3b02db4cc097f5
parentd96f04d73a5feb15b9d27bd23af2f7325732bb03 (diff)
make rb_raise a GVL-only function again
Requested by ko1 that ability of calling rb_raise from anywhere outside of GVL is "too much". Give up that part, move the GVL aquisition routine into gc.c, and make our new gc_raise().
-rw-r--r--common.mk2
-rw-r--r--error.c36
-rw-r--r--gc.c51
-rw-r--r--internal.h1
4 files changed, 52 insertions, 38 deletions
diff --git a/common.mk b/common.mk
index ca03038320..ff56a0c93f 100644
--- a/common.mk
+++ b/common.mk
@@ -1942,7 +1942,6 @@ error.$(OBJEXT): $(CCAN_DIR)/list/list.h
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
@@ -1962,7 +1961,6 @@ error.$(OBJEXT): {$(VPATH)}ruby_assert.h
error.$(OBJEXT): {$(VPATH)}ruby_atomic.h
error.$(OBJEXT): {$(VPATH)}st.h
error.$(OBJEXT): {$(VPATH)}subst.h
-error.$(OBJEXT): {$(VPATH)}thread.h
error.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
error.$(OBJEXT): {$(VPATH)}thread_native.h
error.$(OBJEXT): {$(VPATH)}vm_core.h
diff --git a/error.c b/error.c
index 408a163f1f..0c3633c581 100644
--- a/error.c
+++ b/error.c
@@ -2605,20 +2605,10 @@ rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
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)
+void
+rb_vraise(VALUE exc, const char *fmt, va_list ap)
{
- 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);
+ rb_exc_raise(rb_exc_new3(exc, rb_vsprintf(fmt, ap)));
}
void
@@ -2626,25 +2616,7 @@ rb_raise(VALUE exc, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
- 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 */
- fprintf(stderr, "%s", "[FATAL] ");
- vfprintf(stderr, fmt, args);
- abort();
- }
-
+ rb_vraise(exc, fmt, args);
va_end(args);
}
diff --git a/gc.c b/gc.c
index e970ea17bf..8900279d99 100644
--- a/gc.c
+++ b/gc.c
@@ -165,6 +165,8 @@ size_mul_add_mul_overflow(size_t x, size_t y, size_t z, size_t w) /* x * y + z *
return (struct optional) { t.left || u.left || v.left, v.right };
}
+PRINTF_ARGS(NORETURN(static void gc_raise(VALUE, const char*, ...)), 2, 3);
+
static inline size_t
size_mul_or_raise(size_t x, size_t y, VALUE exc)
{
@@ -176,7 +178,7 @@ size_mul_or_raise(size_t x, size_t y, VALUE exc)
rb_memerror(); /* or...? */
}
else {
- rb_raise(
+ gc_raise(
exc,
"integer overflow: %"PRIuSIZE
" * %"PRIuSIZE
@@ -202,7 +204,7 @@ size_mul_add_or_raise(size_t x, size_t y, size_t z, VALUE exc)
rb_memerror(); /* or...? */
}
else {
- rb_raise(
+ gc_raise(
exc,
"integer overflow: %"PRIuSIZE
" * %"PRIuSIZE
@@ -229,7 +231,7 @@ size_mul_add_mul_or_raise(size_t x, size_t y, size_t z, size_t w, VALUE exc)
rb_memerror(); /* or...? */
}
else {
- rb_raise(
+ gc_raise(
exc,
"integer overflow: %"PRIdSIZE
" * %"PRIdSIZE
@@ -9597,12 +9599,53 @@ objspace_reachable_objects_from_root(rb_objspace_t *objspace, void (func)(const
------------------------ Extended allocator ------------------------
*/
+struct gc_raise_tag {
+ VALUE exc;
+ const char *fmt;
+ va_list *ap;
+};
+
+static void *
+gc_vraise(void *ptr)
+{
+ struct gc_raise_tag *argv = ptr;
+ rb_vraise(argv->exc, argv->fmt, *argv->ap);
+ UNREACHABLE_RETURN(NULL);
+}
+
+static void
+gc_raise(VALUE exc, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ struct gc_raise_tag argv = {
+ exc, fmt, &ap,
+ };
+
+ if (ruby_thread_has_gvl_p()) {
+ gc_vraise(&argv);
+ UNREACHABLE;
+ }
+ else if (ruby_native_thread_p()) {
+ rb_thread_call_with_gvl(gc_vraise, &argv);
+ UNREACHABLE;
+ }
+ else {
+ /* Not in a ruby thread */
+ fprintf(stderr, "%s", "[FATAL] ");
+ vfprintf(stderr, fmt, ap);
+ abort();
+ }
+
+ va_end(ap);
+}
+
static void objspace_xfree(rb_objspace_t *objspace, void *ptr, size_t size);
static void
negative_size_allocation_error(const char *msg)
{
- rb_raise(rb_eNoMemError, "%s", msg);
+ gc_raise(rb_eNoMemError, "%s", msg);
}
static void *
diff --git a/internal.h b/internal.h
index 6afd21d571..6d63bcf18d 100644
--- a/internal.h
+++ b/internal.h
@@ -1553,6 +1553,7 @@ NORETURN(void ruby_deprecated_internal_feature(const char *));
(ruby_deprecated_internal_feature(func), UNREACHABLE)
VALUE rb_warning_warn(VALUE mod, VALUE str);
PRINTF_ARGS(VALUE rb_warning_string(const char *fmt, ...), 1, 2);
+NORETURN(void rb_vraise(VALUE, const char *, va_list));
/* eval.c */
VALUE rb_refinement_module_get_refined_class(VALUE module);