From 0bb709718b023457a490efe222ce19cb2a1dce07 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Thu, 6 Feb 2025 11:35:55 -0500 Subject: [PATCH] Hook ZJIT compilation --- common.mk | 247 ++++++++++++++++++++++++++++++++++++++++++++++++ vm.c | 21 +++- zjit.c | 48 ++++++++++ zjit/src/lib.rs | 14 ++- 4 files changed, 326 insertions(+), 4 deletions(-) diff --git a/common.mk b/common.mk index 9cd4065fa7..770c31ecb4 100644 --- a/common.mk +++ b/common.mk @@ -20927,5 +20927,252 @@ yjit.$(OBJEXT): {$(VPATH)}vm_sync.h yjit.$(OBJEXT): {$(VPATH)}yjit.c yjit.$(OBJEXT): {$(VPATH)}yjit.h yjit.$(OBJEXT): {$(VPATH)}yjit.rbinc +zjit.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h +zjit.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h +zjit.$(OBJEXT): $(CCAN_DIR)/list/list.h +zjit.$(OBJEXT): $(CCAN_DIR)/str/str.h +zjit.$(OBJEXT): $(hdrdir)/ruby/ruby.h +zjit.$(OBJEXT): $(top_srcdir)/internal/array.h +zjit.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h +zjit.$(OBJEXT): $(top_srcdir)/internal/bignum.h +zjit.$(OBJEXT): $(top_srcdir)/internal/bits.h +zjit.$(OBJEXT): $(top_srcdir)/internal/class.h +zjit.$(OBJEXT): $(top_srcdir)/internal/compile.h +zjit.$(OBJEXT): $(top_srcdir)/internal/compilers.h +zjit.$(OBJEXT): $(top_srcdir)/internal/cont.h +zjit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h +zjit.$(OBJEXT): $(top_srcdir)/internal/gc.h +zjit.$(OBJEXT): $(top_srcdir)/internal/hash.h +zjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h +zjit.$(OBJEXT): $(top_srcdir)/internal/numeric.h +zjit.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h +zjit.$(OBJEXT): $(top_srcdir)/internal/serial.h +zjit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h +zjit.$(OBJEXT): $(top_srcdir)/internal/string.h +zjit.$(OBJEXT): $(top_srcdir)/internal/variable.h +zjit.$(OBJEXT): $(top_srcdir)/internal/vm.h +zjit.$(OBJEXT): $(top_srcdir)/internal/warnings.h +zjit.$(OBJEXT): $(top_srcdir)/prism/defines.h +zjit.$(OBJEXT): $(top_srcdir)/prism/encoding.h +zjit.$(OBJEXT): $(top_srcdir)/prism/node.h +zjit.$(OBJEXT): $(top_srcdir)/prism/options.h +zjit.$(OBJEXT): $(top_srcdir)/prism/pack.h +zjit.$(OBJEXT): $(top_srcdir)/prism/parser.h +zjit.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h +zjit.$(OBJEXT): $(top_srcdir)/prism/prism.h +zjit.$(OBJEXT): $(top_srcdir)/prism/regexp.h +zjit.$(OBJEXT): $(top_srcdir)/prism/static_literals.h +zjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h +zjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h +zjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h +zjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h +zjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h +zjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h +zjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h +zjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h +zjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h +zjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h +zjit.$(OBJEXT): {$(VPATH)}assert.h +zjit.$(OBJEXT): {$(VPATH)}atomic.h +zjit.$(OBJEXT): {$(VPATH)}backward/2/assume.h +zjit.$(OBJEXT): {$(VPATH)}backward/2/attributes.h +zjit.$(OBJEXT): {$(VPATH)}backward/2/bool.h +zjit.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h +zjit.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h +zjit.$(OBJEXT): {$(VPATH)}backward/2/limits.h +zjit.$(OBJEXT): {$(VPATH)}backward/2/long_long.h +zjit.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h +zjit.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h +zjit.$(OBJEXT): {$(VPATH)}builtin.h +zjit.$(OBJEXT): {$(VPATH)}config.h +zjit.$(OBJEXT): {$(VPATH)}constant.h +zjit.$(OBJEXT): {$(VPATH)}debug.h +zjit.$(OBJEXT): {$(VPATH)}debug_counter.h +zjit.$(OBJEXT): {$(VPATH)}defines.h +zjit.$(OBJEXT): {$(VPATH)}encoding.h +zjit.$(OBJEXT): {$(VPATH)}id.h +zjit.$(OBJEXT): {$(VPATH)}id_table.h +zjit.$(OBJEXT): {$(VPATH)}insns.def +zjit.$(OBJEXT): {$(VPATH)}insns.inc +zjit.$(OBJEXT): {$(VPATH)}insns_info.inc +zjit.$(OBJEXT): {$(VPATH)}intern.h +zjit.$(OBJEXT): {$(VPATH)}internal.h +zjit.$(OBJEXT): {$(VPATH)}internal/abi.h +zjit.$(OBJEXT): {$(VPATH)}internal/anyargs.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h +zjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h +zjit.$(OBJEXT): {$(VPATH)}internal/assume.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/cold.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/const.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/error.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/format.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/pure.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/warning.h +zjit.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h +zjit.$(OBJEXT): {$(VPATH)}internal/cast.h +zjit.$(OBJEXT): {$(VPATH)}internal/compiler_is.h +zjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h +zjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h +zjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h +zjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h +zjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h +zjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h +zjit.$(OBJEXT): {$(VPATH)}internal/compiler_since.h +zjit.$(OBJEXT): {$(VPATH)}internal/config.h +zjit.$(OBJEXT): {$(VPATH)}internal/constant_p.h +zjit.$(OBJEXT): {$(VPATH)}internal/core.h +zjit.$(OBJEXT): {$(VPATH)}internal/core/rarray.h +zjit.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h +zjit.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h +zjit.$(OBJEXT): {$(VPATH)}internal/core/rclass.h +zjit.$(OBJEXT): {$(VPATH)}internal/core/rdata.h +zjit.$(OBJEXT): {$(VPATH)}internal/core/rfile.h +zjit.$(OBJEXT): {$(VPATH)}internal/core/rhash.h +zjit.$(OBJEXT): {$(VPATH)}internal/core/robject.h +zjit.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h +zjit.$(OBJEXT): {$(VPATH)}internal/core/rstring.h +zjit.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h +zjit.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h +zjit.$(OBJEXT): {$(VPATH)}internal/ctype.h +zjit.$(OBJEXT): {$(VPATH)}internal/dllexport.h +zjit.$(OBJEXT): {$(VPATH)}internal/dosish.h +zjit.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h +zjit.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h +zjit.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h +zjit.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h +zjit.$(OBJEXT): {$(VPATH)}internal/encoding/re.h +zjit.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h +zjit.$(OBJEXT): {$(VPATH)}internal/encoding/string.h +zjit.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h +zjit.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h +zjit.$(OBJEXT): {$(VPATH)}internal/error.h +zjit.$(OBJEXT): {$(VPATH)}internal/eval.h +zjit.$(OBJEXT): {$(VPATH)}internal/event.h +zjit.$(OBJEXT): {$(VPATH)}internal/fl_type.h +zjit.$(OBJEXT): {$(VPATH)}internal/gc.h +zjit.$(OBJEXT): {$(VPATH)}internal/glob.h +zjit.$(OBJEXT): {$(VPATH)}internal/globals.h +zjit.$(OBJEXT): {$(VPATH)}internal/has/attribute.h +zjit.$(OBJEXT): {$(VPATH)}internal/has/builtin.h +zjit.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h +zjit.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h +zjit.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h +zjit.$(OBJEXT): {$(VPATH)}internal/has/extension.h +zjit.$(OBJEXT): {$(VPATH)}internal/has/feature.h +zjit.$(OBJEXT): {$(VPATH)}internal/has/warning.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/array.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/class.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/compar.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/complex.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/cont.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/dir.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/enum.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/error.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/eval.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/file.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/hash.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/io.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/load.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/object.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/parse.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/proc.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/process.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/random.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/range.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/rational.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/re.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/select.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/signal.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/string.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/struct.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/thread.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/time.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/variable.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/vm.h +zjit.$(OBJEXT): {$(VPATH)}internal/interpreter.h +zjit.$(OBJEXT): {$(VPATH)}internal/iterator.h +zjit.$(OBJEXT): {$(VPATH)}internal/memory.h +zjit.$(OBJEXT): {$(VPATH)}internal/method.h +zjit.$(OBJEXT): {$(VPATH)}internal/module.h +zjit.$(OBJEXT): {$(VPATH)}internal/newobj.h +zjit.$(OBJEXT): {$(VPATH)}internal/numeric.h +zjit.$(OBJEXT): {$(VPATH)}internal/scan_args.h +zjit.$(OBJEXT): {$(VPATH)}internal/special_consts.h +zjit.$(OBJEXT): {$(VPATH)}internal/static_assert.h +zjit.$(OBJEXT): {$(VPATH)}internal/stdalign.h +zjit.$(OBJEXT): {$(VPATH)}internal/stdbool.h +zjit.$(OBJEXT): {$(VPATH)}internal/stdckdint.h +zjit.$(OBJEXT): {$(VPATH)}internal/symbol.h +zjit.$(OBJEXT): {$(VPATH)}internal/value.h +zjit.$(OBJEXT): {$(VPATH)}internal/value_type.h +zjit.$(OBJEXT): {$(VPATH)}internal/variable.h +zjit.$(OBJEXT): {$(VPATH)}internal/warning_push.h +zjit.$(OBJEXT): {$(VPATH)}internal/xmalloc.h +zjit.$(OBJEXT): {$(VPATH)}iseq.h +zjit.$(OBJEXT): {$(VPATH)}method.h +zjit.$(OBJEXT): {$(VPATH)}missing.h +zjit.$(OBJEXT): {$(VPATH)}node.h +zjit.$(OBJEXT): {$(VPATH)}onigmo.h +zjit.$(OBJEXT): {$(VPATH)}oniguruma.h +zjit.$(OBJEXT): {$(VPATH)}prism/ast.h +zjit.$(OBJEXT): {$(VPATH)}prism/diagnostic.h +zjit.$(OBJEXT): {$(VPATH)}prism/version.h +zjit.$(OBJEXT): {$(VPATH)}prism_compile.h +zjit.$(OBJEXT): {$(VPATH)}probes.dmyh +zjit.$(OBJEXT): {$(VPATH)}probes.h +zjit.$(OBJEXT): {$(VPATH)}probes_helper.h +zjit.$(OBJEXT): {$(VPATH)}ruby_assert.h +zjit.$(OBJEXT): {$(VPATH)}ruby_atomic.h +zjit.$(OBJEXT): {$(VPATH)}rubyparser.h +zjit.$(OBJEXT): {$(VPATH)}shape.h +zjit.$(OBJEXT): {$(VPATH)}st.h +zjit.$(OBJEXT): {$(VPATH)}subst.h +zjit.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h +zjit.$(OBJEXT): {$(VPATH)}thread_native.h +zjit.$(OBJEXT): {$(VPATH)}vm_callinfo.h +zjit.$(OBJEXT): {$(VPATH)}vm_core.h +zjit.$(OBJEXT): {$(VPATH)}vm_debug.h +zjit.$(OBJEXT): {$(VPATH)}vm_insnhelper.h +zjit.$(OBJEXT): {$(VPATH)}vm_opts.h +zjit.$(OBJEXT): {$(VPATH)}vm_sync.h zjit.$(OBJEXT): {$(VPATH)}zjit.c # AUTOGENERATED DEPENDENCIES END diff --git a/vm.c b/vm.c index dffb5fb5ad..d43deb43cd 100644 --- a/vm.c +++ b/vm.c @@ -419,7 +419,7 @@ rb_yjit_threshold_hit(const rb_iseq_t *iseq, uint64_t entry_calls) #define rb_yjit_threshold_hit(iseq, entry_calls) false #endif -#if USE_YJIT +#if USE_YJIT || USE_ZJIT // Generate JIT code that supports the following kinds of ISEQ entries: // * The first ISEQ on vm_exec (e.g.
, or Ruby methods/blocks // called by a C method). The current frame has VM_FRAME_FLAG_FINISH. @@ -433,12 +433,27 @@ jit_compile(rb_execution_context_t *ec) { const rb_iseq_t *iseq = ec->cfp->iseq; struct rb_iseq_constant_body *body = ISEQ_BODY(iseq); + bool yjit_enabled = rb_yjit_enabled_p; + extern bool rb_zjit_enabled_p; + bool zjit_enabled = rb_zjit_enabled_p; + if (!(yjit_enabled || zjit_enabled || rb_rjit_call_p)) { + return NULL; + } // Increment the ISEQ's call counter and trigger JIT compilation if not compiled if (body->jit_entry == NULL && rb_yjit_enabled_p) { body->jit_entry_calls++; - if (rb_yjit_threshold_hit(iseq, body->jit_entry_calls)) { - rb_yjit_compile_iseq(iseq, ec, false); + if (zjit_enabled) { + extern void rb_zjit_compile_iseq(const rb_iseq_t *iseq, rb_execution_context_t *ec, bool jit_exception); + rb_zjit_compile_iseq(iseq, ec, false); + } + else if (yjit_enabled) { + if (rb_yjit_threshold_hit(iseq, body->jit_entry_calls)) { + rb_yjit_compile_iseq(iseq, ec, false); + } + } + else if (body->jit_entry_calls == rb_rjit_call_threshold()) { + rb_rjit_compile(iseq); } } return body->jit_entry; diff --git a/zjit.c b/zjit.c index e69de29bb2..bebad7b005 100644 --- a/zjit.c +++ b/zjit.c @@ -0,0 +1,48 @@ +#include "internal.h" +#include "internal/sanitizers.h" +#include "internal/string.h" +#include "internal/hash.h" +#include "internal/variable.h" +#include "internal/compile.h" +#include "internal/class.h" +#include "internal/fixnum.h" +#include "internal/numeric.h" +#include "internal/gc.h" +#include "internal/vm.h" +#include "vm_core.h" +#include "vm_callinfo.h" +#include "builtin.h" +#include "insns.inc" +#include "insns_info.inc" +#include "vm_sync.h" +#include "yjit.h" +#include "vm_insnhelper.h" +#include "probes.h" +#include "probes_helper.h" +#include "iseq.h" +#include "ruby/debug.h" +#include "internal/cont.h" + +// For mmapp(), sysconf() +#ifndef _WIN32 +#include +#include +#endif + +#include + +void +rb_zjit_compile_iseq(const rb_iseq_t *iseq, rb_execution_context_t *ec, bool jit_exception) +{ + RB_VM_LOCK_ENTER(); + rb_vm_barrier(); + + // Compile a block version starting at the current instruction + uint8_t *rb_zjit_iseq_gen_entry_point(const rb_iseq_t *iseq, rb_execution_context_t *ec); // defined in Rust + uintptr_t code_ptr = (uintptr_t)rb_zjit_iseq_gen_entry_point(iseq, ec); + + // TODO: support jit_exception + iseq->body->jit_entry = (rb_jit_func_t)code_ptr; + + RB_VM_LOCK_LEAVE(); +} diff --git a/zjit/src/lib.rs b/zjit/src/lib.rs index 626a98731b..a3cc574d68 100644 --- a/zjit/src/lib.rs +++ b/zjit/src/lib.rs @@ -3,10 +3,16 @@ mod cruby; mod stats; mod ir; +use crate::cruby::*; + +#[allow(non_upper_case_globals)] +#[no_mangle] +pub static mut rb_zjit_enabled_p: bool = false; #[no_mangle] pub extern "C" fn rb_zjit_init() { - println!("zjit init"); + assert!(unsafe{ !rb_zjit_enabled_p }); + unsafe { rb_zjit_enabled_p = true; } } #[no_mangle] @@ -14,3 +20,9 @@ pub extern "C" fn rb_zjit_parse_option() -> bool { println!("parsing zjit options"); false } + +#[no_mangle] +pub extern "C" fn rb_zjit_iseq_gen_entry_point(_iseq: IseqPtr, _ec: EcPtr) -> *const u8 { + println!("compiling zjit"); + std::ptr::null() +}