ruby-changes:74062
From: Takashi <ko1@a...>
Date: Tue, 18 Oct 2022 01:28:15 +0900 (JST)
Subject: [ruby-changes:74062] e7c71c6c92 (master): Make mjit_cont sharable with YJIT (#6556)
https://git.ruby-lang.org/ruby.git/commit/?id=e7c71c6c92 From e7c71c6c9271b0c29f210769159090e17128e740 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun <takashikkbn@g...> Date: Mon, 17 Oct 2022 09:27:59 -0700 Subject: Make mjit_cont sharable with YJIT (#6556) * Make mjit_cont sharable with YJIT * Update dependencies * Update YJIT binding --- common.mk | 20 +++++++ cont.c | 131 ++++++++++++++++++++++++++++++++++++----- eval.c | 4 +- internal/cont.h | 5 +- iseq.h | 1 + mjit.c | 103 ++------------------------------ mjit.h | 4 -- ruby.c | 7 +++ yjit.c | 6 +- yjit/src/cruby_bindings.inc.rs | 4 +- 10 files changed, 159 insertions(+), 126 deletions(-) diff --git a/common.mk b/common.mk index 464f64cb76..934939ea4d 100644 --- a/common.mk +++ b/common.mk @@ -3564,6 +3564,7 @@ cont.$(OBJEXT): {$(VPATH)}internal/value_type.h https://github.com/ruby/ruby/blob/trunk/common.mk#L3564 cont.$(OBJEXT): {$(VPATH)}internal/variable.h cont.$(OBJEXT): {$(VPATH)}internal/warning_push.h cont.$(OBJEXT): {$(VPATH)}internal/xmalloc.h +cont.$(OBJEXT): {$(VPATH)}iseq.h cont.$(OBJEXT): {$(VPATH)}method.h cont.$(OBJEXT): {$(VPATH)}missing.h cont.$(OBJEXT): {$(VPATH)}mjit.h @@ -3580,6 +3581,8 @@ cont.$(OBJEXT): {$(VPATH)}thread_native.h https://github.com/ruby/ruby/blob/trunk/common.mk#L3581 cont.$(OBJEXT): {$(VPATH)}vm_core.h cont.$(OBJEXT): {$(VPATH)}vm_debug.h cont.$(OBJEXT): {$(VPATH)}vm_opts.h +cont.$(OBJEXT): {$(VPATH)}vm_sync.h +cont.$(OBJEXT): {$(VPATH)}yjit.h debug.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h debug.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h debug.$(OBJEXT): $(CCAN_DIR)/list/list.h @@ -6262,6 +6265,7 @@ eval.$(OBJEXT): $(hdrdir)/ruby/ruby.h https://github.com/ruby/ruby/blob/trunk/common.mk#L6265 eval.$(OBJEXT): $(top_srcdir)/internal/array.h eval.$(OBJEXT): $(top_srcdir)/internal/class.h eval.$(OBJEXT): $(top_srcdir)/internal/compilers.h +eval.$(OBJEXT): $(top_srcdir)/internal/cont.h eval.$(OBJEXT): $(top_srcdir)/internal/error.h eval.$(OBJEXT): $(top_srcdir)/internal/eval.h eval.$(OBJEXT): $(top_srcdir)/internal/gc.h @@ -6902,6 +6906,7 @@ gc.$(OBJEXT): {$(VPATH)}internal/variable.h https://github.com/ruby/ruby/blob/trunk/common.mk#L6906 gc.$(OBJEXT): {$(VPATH)}internal/warning_push.h gc.$(OBJEXT): {$(VPATH)}internal/xmalloc.h gc.$(OBJEXT): {$(VPATH)}io.h +gc.$(OBJEXT): {$(VPATH)}iseq.h gc.$(OBJEXT): {$(VPATH)}method.h gc.$(OBJEXT): {$(VPATH)}missing.h gc.$(OBJEXT): {$(VPATH)}mjit.h @@ -7124,6 +7129,10 @@ goruby.$(OBJEXT): {$(VPATH)}thread_native.h https://github.com/ruby/ruby/blob/trunk/common.mk#L7129 goruby.$(OBJEXT): {$(VPATH)}vm_core.h goruby.$(OBJEXT): {$(VPATH)}vm_debug.h goruby.$(OBJEXT): {$(VPATH)}vm_opts.h +hash.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h +hash.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h +hash.$(OBJEXT): $(CCAN_DIR)/list/list.h +hash.$(OBJEXT): $(CCAN_DIR)/str/str.h hash.$(OBJEXT): $(hdrdir)/ruby/ruby.h hash.$(OBJEXT): $(top_srcdir)/internal/array.h hash.$(OBJEXT): $(top_srcdir)/internal/bignum.h @@ -7134,6 +7143,7 @@ hash.$(OBJEXT): $(top_srcdir)/internal/cont.h https://github.com/ruby/ruby/blob/trunk/common.mk#L7143 hash.$(OBJEXT): $(top_srcdir)/internal/error.h hash.$(OBJEXT): $(top_srcdir)/internal/gc.h hash.$(OBJEXT): $(top_srcdir)/internal/hash.h +hash.$(OBJEXT): $(top_srcdir)/internal/imemo.h hash.$(OBJEXT): $(top_srcdir)/internal/object.h hash.$(OBJEXT): $(top_srcdir)/internal/proc.h hash.$(OBJEXT): $(top_srcdir)/internal/serial.h @@ -7146,6 +7156,7 @@ hash.$(OBJEXT): $(top_srcdir)/internal/variable.h https://github.com/ruby/ruby/blob/trunk/common.mk#L7156 hash.$(OBJEXT): $(top_srcdir)/internal/vm.h hash.$(OBJEXT): $(top_srcdir)/internal/warnings.h hash.$(OBJEXT): {$(VPATH)}assert.h +hash.$(OBJEXT): {$(VPATH)}atomic.h hash.$(OBJEXT): {$(VPATH)}backward/2/assume.h hash.$(OBJEXT): {$(VPATH)}backward/2/attributes.h hash.$(OBJEXT): {$(VPATH)}backward/2/bool.h @@ -7314,21 +7325,28 @@ hash.$(OBJEXT): {$(VPATH)}internal/value_type.h https://github.com/ruby/ruby/blob/trunk/common.mk#L7325 hash.$(OBJEXT): {$(VPATH)}internal/variable.h hash.$(OBJEXT): {$(VPATH)}internal/warning_push.h hash.$(OBJEXT): {$(VPATH)}internal/xmalloc.h +hash.$(OBJEXT): {$(VPATH)}iseq.h +hash.$(OBJEXT): {$(VPATH)}method.h hash.$(OBJEXT): {$(VPATH)}missing.h +hash.$(OBJEXT): {$(VPATH)}node.h hash.$(OBJEXT): {$(VPATH)}onigmo.h hash.$(OBJEXT): {$(VPATH)}oniguruma.h hash.$(OBJEXT): {$(VPATH)}probes.dmyh hash.$(OBJEXT): {$(VPATH)}probes.h hash.$(OBJEXT): {$(VPATH)}ractor.h hash.$(OBJEXT): {$(VPATH)}ruby_assert.h +hash.$(OBJEXT): {$(VPATH)}ruby_atomic.h hash.$(OBJEXT): {$(VPATH)}shape.h hash.$(OBJEXT): {$(VPATH)}st.h hash.$(OBJEXT): {$(VPATH)}subst.h hash.$(OBJEXT): {$(VPATH)}symbol.h +hash.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h hash.$(OBJEXT): {$(VPATH)}thread_native.h hash.$(OBJEXT): {$(VPATH)}transient_heap.h hash.$(OBJEXT): {$(VPATH)}util.h +hash.$(OBJEXT): {$(VPATH)}vm_core.h hash.$(OBJEXT): {$(VPATH)}vm_debug.h +hash.$(OBJEXT): {$(VPATH)}vm_opts.h hash.$(OBJEXT): {$(VPATH)}vm_sync.h inits.$(OBJEXT): $(hdrdir)/ruby.h inits.$(OBJEXT): $(hdrdir)/ruby/ruby.h @@ -13408,6 +13426,7 @@ ruby.$(OBJEXT): $(top_srcdir)/internal/array.h https://github.com/ruby/ruby/blob/trunk/common.mk#L13426 ruby.$(OBJEXT): $(top_srcdir)/internal/class.h ruby.$(OBJEXT): $(top_srcdir)/internal/cmdlineopt.h ruby.$(OBJEXT): $(top_srcdir)/internal/compilers.h +ruby.$(OBJEXT): $(top_srcdir)/internal/cont.h ruby.$(OBJEXT): $(top_srcdir)/internal/error.h ruby.$(OBJEXT): $(top_srcdir)/internal/file.h ruby.$(OBJEXT): $(top_srcdir)/internal/gc.h @@ -13598,6 +13617,7 @@ ruby.$(OBJEXT): {$(VPATH)}internal/variable.h https://github.com/ruby/ruby/blob/trunk/common.mk#L13617 ruby.$(OBJEXT): {$(VPATH)}internal/warning_push.h ruby.$(OBJEXT): {$(VPATH)}internal/xmalloc.h ruby.$(OBJEXT): {$(VPATH)}io.h +ruby.$(OBJEXT): {$(VPATH)}iseq.h ruby.$(OBJEXT): {$(VPATH)}method.h ruby.$(OBJEXT): {$(VPATH)}missing.h ruby.$(OBJEXT): {$(VPATH)}mjit.h diff --git a/cont.c b/cont.c index b6d26d716e..1ce60811d2 100644 --- a/cont.c +++ b/cont.c @@ -34,7 +34,9 @@ extern int madvise(caddr_t, size_t, int); https://github.com/ruby/ruby/blob/trunk/cont.c#L34 #include "internal/warnings.h" #include "ruby/fiber/scheduler.h" #include "mjit.h" +#include "yjit.h" #include "vm_core.h" +#include "vm_sync.h" #include "id_table.h" #include "ractor_core.h" @@ -67,6 +69,8 @@ static VALUE rb_cFiberPool; https://github.com/ruby/ruby/blob/trunk/cont.c#L69 #define FIBER_POOL_ALLOCATION_FREE #endif +#define jit_cont_enabled mjit_enabled // To be used by YJIT later + enum context_type { CONTINUATION_CONTEXT = 0, FIBER_CONTEXT = 1 @@ -195,6 +199,15 @@ struct fiber_pool { https://github.com/ruby/ruby/blob/trunk/cont.c#L199 size_t vm_stack_size; }; +// Continuation contexts used by JITs +struct rb_jit_cont { + rb_execution_context_t *ec; // continuation ec + struct rb_jit_cont *prev, *next; // used to form lists +}; + +// Doubly linked list for enumerating all on-stack ISEQs. +static struct rb_jit_cont *first_jit_cont; + typedef struct rb_context_struct { enum context_type type; int argc; @@ -212,8 +225,7 @@ typedef struct rb_context_struct { https://github.com/ruby/ruby/blob/trunk/cont.c#L225 rb_execution_context_t saved_ec; rb_jmpbuf_t jmpbuf; rb_ensure_entry_t *ensure_array; - /* Pointer to MJIT info about the continuation. */ - struct mjit_cont *mjit_cont; + struct rb_jit_cont *jit_cont; // Continuation contexts for JITs } rb_context_t; @@ -1000,6 +1012,8 @@ fiber_is_root_p(const rb_fiber_t *fiber) https://github.com/ruby/ruby/blob/trunk/cont.c#L1012 } #endif +static void jit_cont_free(struct rb_jit_cont *cont); + static void cont_free(void *ptr) { @@ -1020,9 +1034,9 @@ cont_free(void *ptr) https://github.com/ruby/ruby/blob/trunk/cont.c#L1034 RUBY_FREE_UNLESS_NULL(cont->saved_vm_stack.ptr); - if (mjit_enabled) { - VM_ASSERT(cont->mjit_cont != NULL); - mjit_cont_free(cont->mjit_cont); + if (jit_cont_enabled) { + VM_ASSERT(cont->jit_cont != NULL); + jit_cont_free(cont->jit_cont); } /* free rb_cont_t or rb_fiber_t */ ruby_xfree(ptr); @@ -1187,12 +1201,98 @@ cont_save_thread(rb_context_t *cont, rb_thread_t *th) https://github.com/ruby/ruby/blob/trunk/cont.c#L1201 sec->machine.stack_end = NULL; } +// Register a new continuation with execution context `ec`. Return JIT info about +// the continuation. +static struct rb_jit_cont * +jit_cont_new(rb_execution_context_t *ec) +{ + struct rb_jit_cont *cont; + + // We need to use calloc instead of something like ZALLOC to avoid triggering GC here. + // When this function is called from rb_thread_alloc through rb_threadptr_root_fiber_setup, + // the thread is still being prepared and marking it causes SEGV. + cont = calloc(1, sizeof(struct rb_jit_cont)); + if (cont == NULL) + rb_memerror(); + cont->ec = ec; + + RB_VM_LOCK_ENTER(); + if (first_jit_cont == NULL) { + cont->next = cont->prev = NULL; + } + else { + cont->prev = NULL; + cont->next = first_jit_cont; + first_jit_cont->prev = cont; + } + first_jit_cont = cont; + RB_VM_LOCK_LEAVE(); + + return cont; +} + +// Unregister continuation `cont`. +static void +jit_cont_free(struct rb_jit_cont *cont) +{ + RB_VM_LOCK_ENTER(); + if (cont == first_jit_cont) { + first_jit_cont = cont->next; + if (first_jit_cont != NULL) + first_jit_cont->prev = NULL; + } + else { + cont->prev->next = cont->next; + if (cont->next != NULL) + cont->next->prev = cont->prev; + } + RB_VM_LOCK_LEAVE(); + + free(cont); +} + +// Call a given callback against all on-stack IS (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/