diff options
author | Alan Wu <[email protected]> | 2025-03-10 22:37:44 -0400 |
---|---|---|
committer | Alan Wu <[email protected]> | 2025-03-12 15:00:26 -0400 |
commit | 08b3a45bc97c835b4677bf76dbce68fd51d81897 () | |
tree | 6ed517372f764d8cf9da9212b5428307b8471e73 | |
parent | 9b9661883b1e2cc85b1341d804b106885432d2bd (diff) |
Push a real iseq in rb_vm_push_frame_fname()
Previously, vm_make_env_each() (used during proc creation and for the debug inspector C API) picked up the non-GC-allocated iseq that rb_vm_push_frame_fname() creates, which led to a SEGV when the GC tried to mark the non GC object. Put a real iseq imemo instead. Speed should be about the same since the old code also did a imemo allocation and a malloc allocation. Real iseq allows ironing out the special-casing of dummy frames in rb_execution_context_mark() and rb_execution_context_update(). A check is added to RubyVM::ISeq#eval, though, to stop attempts to run dummy iseqs. [Bug #21180] Co-authored-by: Aaron Patterson <[email protected]>
Notes: Merged: https://.com/ruby/ruby/pull/12898
-rw-r--r-- | iseq.c | 19 | ||||
-rw-r--r-- | test/fiber/test_scheduler.rb | 13 | ||||
-rw-r--r-- | vm.c | 52 | ||||
-rw-r--r-- | vm_insnhelper.c | 13 |
4 files changed, 58 insertions, 39 deletions
@@ -531,6 +531,19 @@ rb_iseq_pathobj_set(const rb_iseq_t *iseq, VALUE path, VALUE realpath) rb_iseq_pathobj_new(path, realpath)); } 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) { @@ -1909,7 +1922,11 @@ rb_iseqw_to_iseq(VALUE iseqw) static VALUE iseqw_eval(VALUE self) { - return rb_iseq_eval(iseqw_check(self)); } /* @@ -139,6 +139,19 @@ class TestFiberScheduler < Test::Unit::TestCase end end def test_deadlock mutex = Thread::Mutex.new condition = Thread::ConditionVariable.new @@ -3362,22 +3362,20 @@ rb_execution_context_update(rb_execution_context_t *ec) } while (cfp != limit_cfp) { - if (VM_FRAME_TYPE(cfp) != VM_FRAME_MAGIC_DUMMY) { - const VALUE *ep = cfp->ep; - cfp->self = rb_gc_location(cfp->self); - cfp->iseq = (rb_iseq_t *)rb_gc_location((VALUE)cfp->iseq); - cfp->block_code = (void *)rb_gc_location((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)) { - VM_FORCE_WRITE(&prev_ep[VM_ENV_DATA_INDEX_ENV], rb_gc_location(prev_ep[VM_ENV_DATA_INDEX_ENV])); - } - if (VM_ENV_FLAGS(ep, VM_ENV_FLAG_ESCAPED)) { - VM_FORCE_WRITE(&ep[VM_ENV_DATA_INDEX_ENV], rb_gc_location(ep[VM_ENV_DATA_INDEX_ENV])); - VM_FORCE_WRITE(&ep[VM_ENV_DATA_INDEX_ME_CREF], rb_gc_location(ep[VM_ENV_DATA_INDEX_ME_CREF])); - } } } @@ -3413,21 +3411,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]); - } - 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]); - } } } @@ -469,15 +469,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; vm_push_frame(ec, dmy_iseq, //const rb_iseq_t *iseq, @@ -490,7 +483,7 @@ rb_vm_push_frame_fname(rb_execution_context_t *ec, VALUE fname) 0, // int local_size, 0); // int stack_max - return tmpbuf; } /* method dis */ |