зеркало из https://github.com/github/ruby.git
Allow enabling YJIT and RJIT independently (#7474)
We used to require MJIT is supported when YJIT is supported. However, now that RJIT dropped some platforms that YJIT supports, it no longer makes sense. We should be able to enable only YJIT, and vice versa.
This commit is contained in:
Родитель
0bf4cd8e1c
Коммит
6d91df08b5
|
@ -197,8 +197,10 @@ jobs:
|
|||
# - { name: VM_DEBUG_BP_CHECK, env: { cppflags: '-DVM_DEBUG_BP_CHECK' } }
|
||||
# - { name: VM_DEBUG_VERIFY_METHOD_CACHE, env: { cppflags: '-DVM_DEBUG_VERIFY_METHOD_CACHE' } }
|
||||
|
||||
- { name: enable-yjit, env: { append_configure: '--enable-yjit --disable-rjit' }, rust: true }
|
||||
- { name: enable-rjit, env: { append_configure: '--enable-rjit --disable-yjit' } }
|
||||
- { name: YJIT_FORCE_ENABLE, env: { cppflags: '-DYJIT_FORCE_ENABLE' }, rust: true }
|
||||
- { name: RJIT_FORCE_ENABLE, env: { cppflags: '-DRJIT_FORCE_ENABLE' } }
|
||||
- { name: YJIT_FORCE_ENABLE, env: { cppflags: '-DYJIT_FORCE_ENABLE' } }
|
||||
|
||||
name: ${{ matrix.entry.name }}
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -222,6 +224,9 @@ jobs:
|
|||
with:
|
||||
path: src/.downloaded-cache
|
||||
key: downloaded-cache
|
||||
- name: Install Rust
|
||||
if: ${{ matrix.entry.rust }}
|
||||
run: sudo apt-get update && sudo apt install -y rustc
|
||||
- name: autogen
|
||||
run: |
|
||||
if [ ! -f ./autogen.sh ]; then
|
||||
|
|
925
common.mk
925
common.mk
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
79
configure.ac
79
configure.ac
|
@ -3725,16 +3725,6 @@ AC_SUBST(CAPITARGET)
|
|||
AS_CASE(["$RDOCTARGET:$CAPITARGET"],[nodoc:nodoc],[INSTALLDOC=nodoc],[INSTALLDOC=all])
|
||||
AC_SUBST(INSTALLDOC)
|
||||
|
||||
AC_ARG_ENABLE(jit-support,
|
||||
AS_HELP_STRING([--disable-jit-support], [disable JIT features]),
|
||||
[RJIT_SUPPORT=$enableval],
|
||||
[AS_CASE(["$target_os"],
|
||||
[wasi | mingw* | solaris*], [RJIT_SUPPORT=no],
|
||||
[RJIT_SUPPORT=yes]
|
||||
)])
|
||||
|
||||
AC_SUBST(RJIT_SUPPORT)
|
||||
|
||||
AC_CHECK_PROG(RUSTC, [rustc], [rustc], [no]) dnl no ac_tool_prefix
|
||||
|
||||
dnl check if rustc is recent enough to build YJIT (rustc >= 1.58.0)
|
||||
|
@ -3780,8 +3770,8 @@ AC_ARG_ENABLE(yjit,
|
|||
AS_HELP_STRING([--enable-yjit],
|
||||
[enable in-process JIT compiler that requires Rust build tools. enabled by default on supported platforms if rustc 1.58.0+ is available]),
|
||||
[YJIT_SUPPORT=$enableval],
|
||||
[AS_CASE(["$enable_jit_support:$YJIT_TARGET_OK:$YJIT_RUSTC_OK"],
|
||||
[yes:yes:yes|:yes:yes], [
|
||||
[AS_CASE(["$YJIT_TARGET_OK:$YJIT_RUSTC_OK"],
|
||||
[yes:yes], [
|
||||
YJIT_SUPPORT=yes
|
||||
],
|
||||
[YJIT_SUPPORT=no]
|
||||
|
@ -3793,9 +3783,6 @@ CARGO_BUILD_ARGS=
|
|||
YJIT_LIBS=
|
||||
AS_CASE(["${YJIT_SUPPORT}"],
|
||||
[yes|dev|stats|dev_nodebug], [
|
||||
AS_IF([test x"$enable_jit_support" = "xno"],
|
||||
AC_MSG_ERROR([--disable-jit-support but --enable-yjit. YJIT requires JIT support])
|
||||
)
|
||||
AS_IF([test x"$RUSTC" = "xno"],
|
||||
AC_MSG_ERROR([rustc is required. Installation instructions available at https://www.rust-lang.org/tools/install])
|
||||
)
|
||||
|
@ -3835,16 +3822,8 @@ AS_CASE(["${YJIT_SUPPORT}"],
|
|||
AC_DEFINE_UNQUOTED(YJIT_SUPPORT, [$YJIT_SUPPORT])
|
||||
])
|
||||
AC_DEFINE(USE_YJIT, 1)
|
||||
AC_DEFINE(USE_RJIT, 1)
|
||||
], [
|
||||
AC_DEFINE(USE_YJIT, 0)
|
||||
AC_DEFINE(USE_RJIT, 0)
|
||||
])
|
||||
|
||||
# If YJIT links capstone, libcapstone stops working on the C side.
|
||||
# capstone should be linked for RJIT only when YJIT doesn't.
|
||||
AS_IF([test x"$RJIT_SUPPORT" = "xyes" -a -z "$CARGO_BUILD_ARGS" ], [
|
||||
AC_CHECK_LIB([capstone], [cs_disasm])
|
||||
])
|
||||
|
||||
dnl These variables end up in ::RbConfig::CONFIG
|
||||
|
@ -3855,6 +3834,58 @@ AC_SUBST(CARGO_BUILD_ARGS)dnl for selecting Rust build profiles
|
|||
AC_SUBST(YJIT_LIBS)dnl for optionally building the Rust parts of YJIT
|
||||
AC_SUBST(YJIT_OBJ)dnl for optionally building the C parts of YJIT
|
||||
|
||||
dnl Currently, RJIT only supports Unix x86_64 platforms.
|
||||
RJIT_TARGET_OK=no
|
||||
AS_IF([test "$cross_compiling" = no],
|
||||
AS_CASE(["$target_cpu-$target_os"],
|
||||
[*android*], [
|
||||
RJIT_TARGET_OK=no
|
||||
],
|
||||
[x86_64-darwin*], [
|
||||
RJIT_TARGET_OK=yes
|
||||
],
|
||||
[x86_64-*linux*], [
|
||||
RJIT_TARGET_OK=yes
|
||||
],
|
||||
[x86_64-*bsd*], [
|
||||
RJIT_TARGET_OK=yes
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
dnl Build RJIT on Unix x86_64 platforms or if --enable-rjit is specified.
|
||||
AC_ARG_ENABLE(rjit,
|
||||
AS_HELP_STRING([--enable-rjit],
|
||||
[enable pure-Ruby JIT compiler. enabled by default on Unix x86_64 platforms]),
|
||||
[RJIT_SUPPORT=$enableval],
|
||||
[AS_CASE(["$YJIT_TARGET_OK"],
|
||||
[yes], [RJIT_SUPPORT=yes],
|
||||
[RJIT_SUPPORT=no]
|
||||
)]
|
||||
)
|
||||
|
||||
AS_CASE(["${RJIT_SUPPORT}"],
|
||||
[yes|dev], [
|
||||
AS_CASE(["${RJIT_SUPPORT}"],
|
||||
[dev], [
|
||||
# Link libcapstone for --rjit-dump-disasm. If YJIT links libcapstone
|
||||
# with cargo, linking libcapstone here doesn't work. It should be
|
||||
# linked for RJIT only when YJIT doesn't.
|
||||
AS_IF([test -z "$CARGO_BUILD_ARGS"], [
|
||||
AC_CHECK_LIB([capstone], [cs_disasm])
|
||||
])
|
||||
|
||||
# Enable RJIT_STATS (vm_insns_count of --rjit-stats)
|
||||
AC_DEFINE(RUBY_DEBUG, 1)
|
||||
])
|
||||
|
||||
AC_DEFINE(USE_RJIT, 1)
|
||||
], [
|
||||
AC_DEFINE(USE_RJIT, 0)
|
||||
])
|
||||
|
||||
AC_SUBST(RJIT_SUPPORT)
|
||||
|
||||
AC_ARG_ENABLE(install-static-library,
|
||||
AS_HELP_STRING([--disable-install-static-library], [do not install static ruby library]),
|
||||
[INSTALL_STATIC_LIBRARY=$enableval
|
||||
|
@ -4541,8 +4572,8 @@ config_summary "debugflags" "$debugflags"
|
|||
config_summary "warnflags" "$warnflags"
|
||||
config_summary "strip command" "$STRIP"
|
||||
config_summary "install doc" "$DOCTARGETS"
|
||||
config_summary "RJIT support" "$RJIT_SUPPORT"
|
||||
config_summary "YJIT support" "$YJIT_SUPPORT"
|
||||
config_summary "RJIT support" "$RJIT_SUPPORT"
|
||||
config_summary "man page type" "$MANTYPE"
|
||||
config_summary "search path" "$search_path"
|
||||
config_summary "static-linked-ext" ${EXTSTATIC:+"yes"}
|
||||
|
|
108
rjit.c
108
rjit.c
|
@ -56,6 +56,12 @@ void rb_rjit(void) {}
|
|||
#endif
|
||||
#include "dln.h"
|
||||
|
||||
// For mmapp(), sysconf()
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include "ruby/util.h"
|
||||
|
||||
// A copy of RJIT portion of MRI options since RJIT initialization. We
|
||||
|
@ -261,6 +267,105 @@ rjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id)
|
|||
// New stuff from here
|
||||
//
|
||||
|
||||
#if defined(MAP_FIXED_NOREPLACE) && defined(_SC_PAGESIZE)
|
||||
// Align the current write position to a multiple of bytes
|
||||
static uint8_t *
|
||||
align_ptr(uint8_t *ptr, uint32_t multiple)
|
||||
{
|
||||
// Compute the pointer modulo the given alignment boundary
|
||||
uint32_t rem = ((uint32_t)(uintptr_t)ptr) % multiple;
|
||||
|
||||
// If the pointer is already aligned, stop
|
||||
if (rem == 0)
|
||||
return ptr;
|
||||
|
||||
// Pad the pointer by the necessary amount to align it
|
||||
uint32_t pad = multiple - rem;
|
||||
|
||||
return ptr + pad;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Address space reservation. Memory pages are mapped on an as needed basis.
|
||||
// See the Rust mm module for details.
|
||||
static uint8_t *
|
||||
rb_mjit_reserve_addr_space(uint32_t mem_size)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
uint8_t *mem_block;
|
||||
|
||||
// On Linux
|
||||
#if defined(MAP_FIXED_NOREPLACE) && defined(_SC_PAGESIZE)
|
||||
uint32_t const page_size = (uint32_t)sysconf(_SC_PAGESIZE);
|
||||
uint8_t *const cfunc_sample_addr = (void *)&rb_mjit_reserve_addr_space;
|
||||
uint8_t *const probe_region_end = cfunc_sample_addr + INT32_MAX;
|
||||
// Align the requested address to page size
|
||||
uint8_t *req_addr = align_ptr(cfunc_sample_addr, page_size);
|
||||
|
||||
// Probe for addresses close to this function using MAP_FIXED_NOREPLACE
|
||||
// to improve odds of being in range for 32-bit relative call instructions.
|
||||
do {
|
||||
mem_block = mmap(
|
||||
req_addr,
|
||||
mem_size,
|
||||
PROT_NONE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE,
|
||||
-1,
|
||||
0
|
||||
);
|
||||
|
||||
// If we succeeded, stop
|
||||
if (mem_block != MAP_FAILED) {
|
||||
break;
|
||||
}
|
||||
|
||||
// +4MB
|
||||
req_addr += 4 * 1024 * 1024;
|
||||
} while (req_addr < probe_region_end);
|
||||
|
||||
// On MacOS and other platforms
|
||||
#else
|
||||
// Try to map a chunk of memory as executable
|
||||
mem_block = mmap(
|
||||
(void *)rb_mjit_reserve_addr_space,
|
||||
mem_size,
|
||||
PROT_NONE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
-1,
|
||||
0
|
||||
);
|
||||
#endif
|
||||
|
||||
// Fallback
|
||||
if (mem_block == MAP_FAILED) {
|
||||
// Try again without the address hint (e.g., valgrind)
|
||||
mem_block = mmap(
|
||||
NULL,
|
||||
mem_size,
|
||||
PROT_NONE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
-1,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
// Check that the memory mapping was successful
|
||||
if (mem_block == MAP_FAILED) {
|
||||
perror("ruby: yjit: mmap:");
|
||||
if(errno == ENOMEM) {
|
||||
// No crash report if it's only insufficient memory
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
rb_bug("mmap failed");
|
||||
}
|
||||
|
||||
return mem_block;
|
||||
#else
|
||||
// Windows not supported for now
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
// JIT buffer
|
||||
uint8_t *rb_rjit_mem_block = NULL;
|
||||
|
||||
|
@ -485,8 +590,7 @@ rjit_init(const struct rjit_options *opts)
|
|||
VM_ASSERT(rjit_enabled);
|
||||
rjit_opts = *opts;
|
||||
|
||||
extern uint8_t* rb_yjit_reserve_addr_space(uint32_t mem_size);
|
||||
rb_rjit_mem_block = rb_yjit_reserve_addr_space(RJIT_CODE_SIZE);
|
||||
rb_rjit_mem_block = rb_mjit_reserve_addr_space(RJIT_CODE_SIZE);
|
||||
|
||||
// RJIT doesn't support miniruby, but it might reach here by RJIT_FORCE_ENABLE.
|
||||
rb_mRJIT = rb_const_get(rb_cRubyVM, rb_intern("RJIT"));
|
||||
|
|
11
rjit.h
11
rjit.h
|
@ -86,12 +86,12 @@ struct rb_rjit_compile_info {
|
|||
bool disable_const_cache;
|
||||
};
|
||||
|
||||
typedef VALUE (*jit_func_t)(rb_execution_context_t *, rb_control_frame_t *);
|
||||
|
||||
RUBY_SYMBOL_EXPORT_BEGIN
|
||||
RUBY_EXTERN struct rjit_options rjit_opts;
|
||||
RUBY_EXTERN bool rjit_call_p;
|
||||
|
||||
#define rb_rjit_call_threshold() rjit_opts.call_threshold
|
||||
|
||||
extern void rb_rjit_compile(const rb_iseq_t *iseq);
|
||||
extern struct rb_rjit_compile_info* rb_rjit_iseq_compile_info(const struct rb_iseq_constant_body *body);
|
||||
extern void rb_rjit_recompile_send(const rb_iseq_t *iseq);
|
||||
|
@ -132,10 +132,11 @@ void rjit_finish(bool close_handle_p);
|
|||
|
||||
# else // USE_RJIT
|
||||
|
||||
static inline void rb_rjit_compile(const rb_iseq_t *iseq){}
|
||||
|
||||
static inline void rjit_cancel_all(const char *reason){}
|
||||
static inline void rjit_free_iseq(const rb_iseq_t *iseq){}
|
||||
static inline void rjit_mark(void){}
|
||||
static inline VALUE jit_exec(rb_execution_context_t *ec) { return Qundef; /* unreachable */ }
|
||||
static inline void rjit_child_after_fork(void){}
|
||||
|
||||
static inline void rb_rjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop) {}
|
||||
|
@ -146,7 +147,11 @@ static inline void rb_rjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic
|
|||
static inline void rb_rjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events) {}
|
||||
|
||||
#define rjit_enabled false
|
||||
#define rjit_call_p false
|
||||
#define rjit_stats_enabled false
|
||||
|
||||
#define rb_rjit_call_threshold() UINT_MAX
|
||||
|
||||
static inline VALUE rjit_pause(bool wait_p){ return Qnil; } // unreachable
|
||||
static inline VALUE rjit_resume(void){ return Qnil; } // unreachable
|
||||
static inline void rjit_finish(bool close_handle_p){}
|
||||
|
|
82
rjit_c.c
82
rjit_c.c
|
@ -23,10 +23,92 @@ void rb_rjit_c(void) {}
|
|||
#include "internal/gc.h"
|
||||
#include "yjit.h"
|
||||
#include "vm_insnhelper.h"
|
||||
#include "probes.h"
|
||||
#include "probes_helper.h"
|
||||
|
||||
#include "insns.inc"
|
||||
#include "insns_info.inc"
|
||||
|
||||
// For mmapp(), sysconf()
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
bool
|
||||
rb_rjit_mark_writable(void *mem_block, uint32_t mem_size)
|
||||
{
|
||||
return mprotect(mem_block, mem_size, PROT_READ | PROT_WRITE) == 0;
|
||||
}
|
||||
|
||||
void
|
||||
rb_rjit_mark_executable(void *mem_block, uint32_t mem_size)
|
||||
{
|
||||
// Do not call mprotect when mem_size is zero. Some platforms may return
|
||||
// an error for it. https://github.com/Shopify/ruby/issues/450
|
||||
if (mem_size == 0) {
|
||||
return;
|
||||
}
|
||||
if (mprotect(mem_block, mem_size, PROT_READ | PROT_EXEC)) {
|
||||
rb_bug("Couldn't make JIT page (%p, %lu bytes) executable, errno: %s\n",
|
||||
mem_block, (unsigned long)mem_size, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_rjit_optimized_call(VALUE *recv, rb_execution_context_t *ec, int argc, VALUE *argv, int kw_splat, VALUE block_handler)
|
||||
{
|
||||
rb_proc_t *proc;
|
||||
GetProcPtr(recv, proc);
|
||||
return rb_vm_invoke_proc(ec, proc, argc, argv, kw_splat, block_handler);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_rjit_str_neq_internal(VALUE str1, VALUE str2)
|
||||
{
|
||||
return rb_str_eql_internal(str1, str2) == Qtrue ? Qfalse : Qtrue;
|
||||
}
|
||||
|
||||
// The code we generate in gen_send_cfunc() doesn't fire the c_return TracePoint event
|
||||
// like the interpreter. When tracing for c_return is enabled, we patch the code after
|
||||
// the C method return to call into this to fire the event.
|
||||
void
|
||||
rb_rjit_full_cfunc_return(rb_execution_context_t *ec, VALUE return_value)
|
||||
{
|
||||
rb_control_frame_t *cfp = ec->cfp;
|
||||
RUBY_ASSERT_ALWAYS(cfp == GET_EC()->cfp);
|
||||
const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
|
||||
|
||||
RUBY_ASSERT_ALWAYS(RUBYVM_CFUNC_FRAME_P(cfp));
|
||||
RUBY_ASSERT_ALWAYS(me->def->type == VM_METHOD_TYPE_CFUNC);
|
||||
|
||||
// CHECK_CFP_CONSISTENCY("full_cfunc_return"); TODO revive this
|
||||
|
||||
// Pop the C func's frame and fire the c_return TracePoint event
|
||||
// Note that this is the same order as vm_call_cfunc_with_frame().
|
||||
rb_vm_pop_frame(ec);
|
||||
EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_RETURN, cfp->self, me->def->original_id, me->called_id, me->owner, return_value);
|
||||
// Note, this deviates from the interpreter in that users need to enable
|
||||
// a c_return TracePoint for this DTrace hook to work. A reasonable change
|
||||
// since the Ruby return event works this way as well.
|
||||
RUBY_DTRACE_CMETHOD_RETURN_HOOK(ec, me->owner, me->def->original_id);
|
||||
|
||||
// Push return value into the caller's stack. We know that it's a frame that
|
||||
// uses cfp->sp because we are patching a call done with gen_send_cfunc().
|
||||
ec->cfp->sp[0] = return_value;
|
||||
ec->cfp->sp++;
|
||||
}
|
||||
|
||||
rb_proc_t *
|
||||
rb_rjit_get_proc_ptr(VALUE procv)
|
||||
{
|
||||
rb_proc_t *proc;
|
||||
GetProcPtr(procv, proc);
|
||||
return proc;
|
||||
}
|
||||
|
||||
#if SIZEOF_LONG == SIZEOF_VOIDP
|
||||
#define NUM2PTR(x) NUM2ULONG(x)
|
||||
#define PTR2NUM(x) ULONG2NUM(x)
|
||||
|
|
24
rjit_c.rb
24
rjit_c.rb
|
@ -11,16 +11,16 @@ module RubyVM::RJIT # :nodoc: all
|
|||
#
|
||||
def rjit_mark_writable
|
||||
Primitive.cstmt! %{
|
||||
extern bool rb_yjit_mark_writable(void *mem_block, uint32_t mem_size);
|
||||
rb_yjit_mark_writable(rb_rjit_mem_block, RJIT_CODE_SIZE);
|
||||
extern bool rb_rjit_mark_writable(void *mem_block, uint32_t mem_size);
|
||||
rb_rjit_mark_writable(rb_rjit_mem_block, RJIT_CODE_SIZE);
|
||||
return Qnil;
|
||||
}
|
||||
end
|
||||
|
||||
def rjit_mark_executable
|
||||
Primitive.cstmt! %{
|
||||
extern bool rb_yjit_mark_executable(void *mem_block, uint32_t mem_size);
|
||||
rb_yjit_mark_executable(rb_rjit_mem_block, RJIT_CODE_SIZE);
|
||||
extern void rb_rjit_mark_executable(void *mem_block, uint32_t mem_size);
|
||||
rb_rjit_mark_executable(rb_rjit_mem_block, RJIT_CODE_SIZE);
|
||||
return Qnil;
|
||||
}
|
||||
end
|
||||
|
@ -147,8 +147,8 @@ module RubyVM::RJIT # :nodoc: all
|
|||
|
||||
def rb_full_cfunc_return
|
||||
Primitive.cstmt! %{
|
||||
extern void rb_full_cfunc_return(rb_execution_context_t *ec, VALUE return_value);
|
||||
return SIZET2NUM((size_t)rb_full_cfunc_return);
|
||||
extern void rb_rjit_full_cfunc_return(rb_execution_context_t *ec, VALUE return_value);
|
||||
return SIZET2NUM((size_t)rb_rjit_full_cfunc_return);
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -177,8 +177,8 @@ module RubyVM::RJIT # :nodoc: all
|
|||
|
||||
def rb_str_neq_internal
|
||||
Primitive.cstmt! %{
|
||||
extern VALUE rb_str_neq_internal(VALUE str1, VALUE str2);
|
||||
return SIZET2NUM((size_t)rb_str_neq_internal);
|
||||
extern VALUE rb_rjit_str_neq_internal(VALUE str1, VALUE str2);
|
||||
return SIZET2NUM((size_t)rb_rjit_str_neq_internal);
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -398,8 +398,8 @@ module RubyVM::RJIT # :nodoc: all
|
|||
|
||||
def rb_optimized_call
|
||||
Primitive.cstmt! %{
|
||||
extern VALUE rb_optimized_call(VALUE *recv, rb_execution_context_t *ec, int argc, VALUE *argv, int kw_splat, VALUE block_handler);
|
||||
return SIZET2NUM((size_t)rb_optimized_call);
|
||||
extern VALUE rb_rjit_optimized_call(VALUE *recv, rb_execution_context_t *ec, int argc, VALUE *argv, int kw_splat, VALUE block_handler);
|
||||
return SIZET2NUM((size_t)rb_rjit_optimized_call);
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -414,8 +414,8 @@ module RubyVM::RJIT # :nodoc: all
|
|||
|
||||
def rb_yjit_get_proc_ptr(proc_addr)
|
||||
proc_t_addr = Primitive.cstmt! %{
|
||||
extern rb_proc_t * rb_yjit_get_proc_ptr(VALUE procv);
|
||||
return SIZET2NUM((size_t)rb_yjit_get_proc_ptr((VALUE)NUM2SIZET(proc_addr)));
|
||||
extern rb_proc_t * rb_rjit_get_proc_ptr(VALUE procv);
|
||||
return SIZET2NUM((size_t)rb_rjit_get_proc_ptr((VALUE)NUM2SIZET(proc_addr)));
|
||||
}
|
||||
rb_proc_t.new(proc_t_addr)
|
||||
end
|
||||
|
|
8
vm.c
8
vm.c
|
@ -403,7 +403,7 @@ jit_exec(rb_execution_context_t *ec)
|
|||
}
|
||||
}
|
||||
else { // rjit_call_p
|
||||
if (body->total_calls == rjit_opts.call_threshold) {
|
||||
if (body->total_calls == rb_rjit_call_threshold()) {
|
||||
rb_rjit_compile(iseq);
|
||||
}
|
||||
if ((func = body->jit_func) == 0) {
|
||||
|
@ -414,6 +414,12 @@ jit_exec(rb_execution_context_t *ec)
|
|||
// Call the JIT code
|
||||
return func(ec, ec->cfp); // SystemV x64 calling convention: ec -> RDI, cfp -> RSI
|
||||
}
|
||||
#else
|
||||
static inline VALUE
|
||||
jit_exec(rb_execution_context_t *ec)
|
||||
{
|
||||
return Qundef;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "vm_insnhelper.c"
|
||||
|
|
|
@ -521,6 +521,8 @@ struct rb_iseq_constant_body {
|
|||
#endif
|
||||
};
|
||||
|
||||
typedef VALUE (*jit_func_t)(struct rb_execution_context_struct *, struct rb_control_frame_struct *);
|
||||
|
||||
/* T_IMEMO/iseq */
|
||||
/* typedef rb_iseq_t is in method.h */
|
||||
struct rb_iseq_struct {
|
||||
|
|
Загрузка…
Ссылка в новой задаче