diff options
-rw-r--r-- | iseq.c | 19 | ||||
-rw-r--r-- | test/fiber/test_scheduler.rb | 13 | ||||
-rw-r--r-- | version.h | 2 | ||||
-rw-r--r-- | vm.c | 26 | ||||
-rw-r--r-- | vm_insnhelper.c | 13 |
5 files changed, 47 insertions, 26 deletions
@@ -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 @@ -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" @@ -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 */ |