summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--iseq.c19
-rw-r--r--test/fiber/test_scheduler.rb13
-rw-r--r--version.h2
-rw-r--r--vm.c26
-rw-r--r--vm_insnhelper.c13
5 files changed, 47 insertions, 26 deletions
diff --git a/iseq.c b/iseq.c
index 672bbccd98..3bdb1c0af5 100644
--- a/iseq.c
+++ b/iseq.c
@@ -533,6 +533,19 @@ rb_iseq_pathobj_set(const rb_iseq_t *iseq, VALUE path, VALUE realpath)
rb_iseq_pathobj_new(path, realpath));
}
+// Make a dummy iseq for a dummy frame that exposes a path for profilers to inspect
+rb_iseq_t *
+rb_iseq_alloc_with_dummy_path(VALUE fname)
+{
+ rb_iseq_t *dummy_iseq = iseq_alloc();
+
+ ISEQ_BODY(dummy_iseq)->type = ISEQ_TYPE_TOP;
+ RB_OBJ_WRITE(dummy_iseq, &ISEQ_BODY(dummy_iseq)->location.pathobj, fname);
+ RB_OBJ_WRITE(dummy_iseq, &ISEQ_BODY(dummy_iseq)->location.label, fname);
+
+ return dummy_iseq;
+}
+
static rb_iseq_location_t *
iseq_location_setup(rb_iseq_t *iseq, VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_code_location_t *code_location, const int node_id)
{
@@ -1672,7 +1685,11 @@ rb_iseqw_to_iseq(VALUE iseqw)
static VALUE
iseqw_eval(VALUE self)
{
- return rb_iseq_eval(iseqw_check(self));
+ const rb_iseq_t *iseq = iseqw_check(self);
+ if (0 == ISEQ_BODY(iseq)->iseq_size) {
+ rb_raise(rb_eTypeError, "attempt to evaluate dummy InstructionSequence");
+ }
+ return rb_iseq_eval(iseq);
}
/*
diff --git a/test/fiber/test_scheduler.rb b/test/fiber/test_scheduler.rb
index 62424fc489..81d4581bea 100644
--- a/test/fiber/test_scheduler.rb
+++ b/test/fiber/test_scheduler.rb
@@ -139,6 +139,19 @@ class TestFiberScheduler < Test::Unit::TestCase
end
end
+ def test_iseq_compile_under_gc_stress_bug_21180
+ Thread.new do
+ scheduler = Scheduler.new
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ EnvUtil.under_gc_stress do
+ RubyVM::InstructionSequence.compile_file(File::NULL)
+ end
+ end
+ end.join
+ end
+
def test_deadlock
mutex = Thread::Mutex.new
condition = Thread::ConditionVariable.new
diff --git a/version.h b/version.h
index a83aa1824d..4b21ab9908 100644
--- a/version.h
+++ b/version.h
@@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 7
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 133
+#define RUBY_PATCHLEVEL 134
#include "ruby/version.h"
#include "ruby/internal/abi.h"
diff --git a/vm.c b/vm.c
index 62ea5be53b..9fb7cb017f 100644
--- a/vm.c
+++ b/vm.c
@@ -3327,21 +3327,19 @@ rb_execution_context_mark(const rb_execution_context_t *ec)
const VALUE *ep = cfp->ep;
VM_ASSERT(!!VM_ENV_FLAGS(ep, VM_ENV_FLAG_ESCAPED) == vm_ep_in_heap_p_(ec, ep));
- if (VM_FRAME_TYPE(cfp) != VM_FRAME_MAGIC_DUMMY) {
- rb_gc_mark_movable(cfp->self);
- rb_gc_mark_movable((VALUE)cfp->iseq);
- rb_gc_mark_movable((VALUE)cfp->block_code);
-
- if (!VM_ENV_LOCAL_P(ep)) {
- const VALUE *prev_ep = VM_ENV_PREV_EP(ep);
- if (VM_ENV_FLAGS(prev_ep, VM_ENV_FLAG_ESCAPED)) {
- rb_gc_mark_movable(prev_ep[VM_ENV_DATA_INDEX_ENV]);
- }
+ rb_gc_mark_movable(cfp->self);
+ rb_gc_mark_movable((VALUE)cfp->iseq);
+ rb_gc_mark_movable((VALUE)cfp->block_code);
- if (VM_ENV_FLAGS(ep, VM_ENV_FLAG_ESCAPED)) {
- rb_gc_mark_movable(ep[VM_ENV_DATA_INDEX_ENV]);
- rb_gc_mark(ep[VM_ENV_DATA_INDEX_ME_CREF]);
- }
+ if (!VM_ENV_LOCAL_P(ep)) {
+ const VALUE *prev_ep = VM_ENV_PREV_EP(ep);
+ if (VM_ENV_FLAGS(prev_ep, VM_ENV_FLAG_ESCAPED)) {
+ rb_gc_mark_movable(prev_ep[VM_ENV_DATA_INDEX_ENV]);
+ }
+
+ if (VM_ENV_FLAGS(ep, VM_ENV_FLAG_ESCAPED)) {
+ rb_gc_mark_movable(ep[VM_ENV_DATA_INDEX_ENV]);
+ rb_gc_mark(ep[VM_ENV_DATA_INDEX_ME_CREF]);
}
}
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 7284769854..1af20721a7 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -444,15 +444,8 @@ rb_vm_pop_frame(rb_execution_context_t *ec)
VALUE
rb_vm_push_frame_fname(rb_execution_context_t *ec, VALUE fname)
{
- VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer();
- void *ptr = ruby_xcalloc(sizeof(struct rb_iseq_constant_body) + sizeof(struct rb_iseq_struct), 1);
- rb_imemo_tmpbuf_set_ptr(tmpbuf, ptr);
-
- struct rb_iseq_struct *dmy_iseq = (struct rb_iseq_struct *)ptr;
- struct rb_iseq_constant_body *dmy_body = (struct rb_iseq_constant_body *)&dmy_iseq[1];
- dmy_iseq->body = dmy_body;
- dmy_body->type = ISEQ_TYPE_TOP;
- dmy_body->location.pathobj = fname;
+ rb_iseq_t *rb_iseq_alloc_with_dummy_path(VALUE fname);
+ rb_iseq_t *dmy_iseq = rb_iseq_alloc_with_dummy_path(fname);
vm_push_frame(ec,
dmy_iseq, //const rb_iseq_t *iseq,
@@ -465,7 +458,7 @@ rb_vm_push_frame_fname(rb_execution_context_t *ec, VALUE fname)
0, // int local_size,
0); // int stack_max
- return tmpbuf;
+ return (VALUE)dmy_iseq;
}
/* method dispatch */