This commit is contained in:
Takashi Kokubun 2023-03-06 23:17:25 -08:00
Родитель 2e875549a9
Коммит 23ec248e48
63 изменённых файлов: 1070 добавлений и 1072 удалений

Просмотреть файл

@ -18,7 +18,7 @@ gc.rb
io.rb
kernel.rb
marshal.rb
mjit.rb
rjit.rb
numeric.rb
nilclass.rb
pack.rb

2
.github/workflows/rjit-bindgen.yml поставляемый
Просмотреть файл

@ -27,7 +27,7 @@ jobs:
strategy:
matrix:
include:
- task: mjit-bindgen
- task: rjit-bindgen
fail-fast: false
runs-on: ubuntu-20.04
if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}

2
.github/workflows/rjit.yml поставляемый
Просмотреть файл

@ -30,7 +30,7 @@ jobs:
matrix:
# main variables included in the job name
test_task: [check]
run_opts: ['--mjit-call-threshold=1']
run_opts: ['--rjit-call-threshold=1']
arch: ['']
fail-fast: false
env:

8
.gitignore поставляемый
Просмотреть файл

@ -239,11 +239,11 @@ lcov*.info
/win32/*.ico
# RJIT
/include/ruby-*/*/rb_mjit_min_header-*.h
/lib/ruby_vm/mjit/instruction.rb
/include/ruby-*/*/rb_rjit_min_header-*.h
/lib/ruby_vm/rjit/instruction.rb
/mjit_config.h
/rb_mjit_header.h*
/lib/ruby_vm/rjit/instruction.rb
/rjit_config.h
/rb_rjit_header.h*
# YJIT
/yjit-bench

Просмотреть файл

@ -14,7 +14,7 @@ ms = "a".."k"
o.send(meth)
end
end
}, '[ruby-dev:39453]' unless ENV.fetch('RUN_OPTS', '').include?('mjit') # speed up RJIT CI
}, '[ruby-dev:39453]' unless ENV.fetch('RUN_OPTS', '').include?('rjit') # speed up RJIT CI
assert_normal_exit %q{
a = []

Просмотреть файл

@ -283,7 +283,7 @@ assert_equal 30.times.map { 'ok' }.to_s, %q{
30.times.map{|i|
test i
}
} unless ENV['RUN_OPTS'] =~ /--mjit-call-threshold=5/ || # This always fails with --mjit-wait --mjit-call-threshold=5
} unless ENV['RUN_OPTS'] =~ /--rjit-call-threshold=5/ || # This always fails with --rjit-wait --rjit-call-threshold=5
(ENV.key?('TRAVIS') && ENV['TRAVIS_CPU_ARCH'] == 'arm64') # https://bugs.ruby-lang.org/issues/17878
# Exception for empty select
@ -1532,7 +1532,7 @@ assert_equal "ok", %q{
1_000.times { idle_worker, tmp_reporter = Ractor.select(*workers) }
"ok"
} unless ENV['RUN_OPTS'] =~ /mjit/ # flaky
} unless ENV['RUN_OPTS'] =~ /rjit/ # flaky
assert_equal "ok", %q{
def foo(*); ->{ super }; end

944
common.mk

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -2929,9 +2929,9 @@ AC_SUBST(DLDFLAGS)dnl
AC_SUBST(ARCH_FLAG)dnl
AC_SUBST(RJIT_CC)dnl
AS_CASE(["$GCC:$target_os"],
[yes:aix*], [mjit_std_cflag="-std=gnu99"],
[mjit_std_cflag=])
AC_SUBST(RJIT_CFLAGS, [${RJIT_CFLAGS-"-w ${mjit_std_cflag} ${orig_cflags}"}])dnl
[yes:aix*], [rjit_std_cflag="-std=gnu99"],
[rjit_std_cflag=])
AC_SUBST(RJIT_CFLAGS, [${RJIT_CFLAGS-"-w ${rjit_std_cflag} ${orig_cflags}"}])dnl
AC_SUBST(RJIT_OPTFLAGS, [${RJIT_OPTFLAGS-'$(optflags)'}])dnl
AC_SUBST(RJIT_DEBUGFLAGS, [${RJIT_DEBUGFLAGS-'$(debugflags)'}])dnl
AC_SUBST(RJIT_LDSHARED)dnl

6
cont.c
Просмотреть файл

@ -34,7 +34,7 @@ extern int madvise(caddr_t, size_t, int);
#include "internal/sanitizers.h"
#include "internal/warnings.h"
#include "ruby/fiber/scheduler.h"
#include "mjit.h"
#include "rjit.h"
#include "yjit.h"
#include "vm_core.h"
#include "vm_sync.h"
@ -70,7 +70,7 @@ static VALUE rb_cFiberPool;
#define FIBER_POOL_ALLOCATION_FREE
#endif
#define jit_cont_enabled (mjit_enabled || rb_yjit_enabled_p())
#define jit_cont_enabled (rjit_enabled || rb_yjit_enabled_p())
enum context_type {
CONTINUATION_CONTEXT = 0,
@ -2547,7 +2547,7 @@ rb_threadptr_root_fiber_setup(rb_thread_t *th)
fiber->blocking = 1;
fiber_status_set(fiber, FIBER_RESUMED); /* skip CREATED */
th->ec = &fiber->cont.saved_ec;
// When rb_threadptr_root_fiber_setup is called for the first time, mjit_enabled and
// When rb_threadptr_root_fiber_setup is called for the first time, rjit_enabled and
// rb_yjit_enabled_p() are still false. So this does nothing and rb_jit_cont_init() that is
// called later will take care of it. However, you still have to call cont_init_jit_cont()
// here for other Ractors, which are not initialized by rb_jit_cont_init().

Просмотреть файл

@ -22,7 +22,7 @@ The RJIT support for the following platforms is no longer maintained.
If you see an "RJIT bindgen" GitHub Actions failure, please commit the `git diff` shown on the failed job.
For doing the same thing locally, run `make mjit-bindgen` after installing libclang.
For doing the same thing locally, run `make rjit-bindgen` after installing libclang.
macOS seems to have libclang by default. On Ubuntu, you can install it with `apt install libclang1`.
### Always run make install
@ -30,10 +30,10 @@ macOS seems to have libclang by default. On Ubuntu, you can install it with `apt
Always run `make install` before running RJIT. It could easily cause a SEGV if you don't.
RJIT looks for the installed header for security reasons.
### --mjit-debug vs --mjit-debug=-ggdb3
### --rjit-debug vs --rjit-debug=-ggdb3
`--mjit-debug=[flags]` allows you to specify arbitrary flags while keeping other compiler flags like `-O3`,
`--rjit-debug=[flags]` allows you to specify arbitrary flags while keeping other compiler flags like `-O3`,
which is useful for profiling benchmarks.
`--mjit-debug` alone, on the other hand, disables `-O3` and adds debug flags.
If you're debugging RJIT, what you need to use is not `--mjit-debug=-ggdb3` but `--mjit-debug`.
`--rjit-debug` alone, on the other hand, disables `-O3` and adds debug flags.
If you're debugging RJIT, what you need to use is not `--rjit-debug=-ggdb3` but `--rjit-debug`.

4
eval.c
Просмотреть файл

@ -32,7 +32,7 @@
#include "internal/variable.h"
#include "ruby/fiber/scheduler.h"
#include "iseq.h"
#include "mjit.h"
#include "rjit.h"
#include "probes.h"
#include "probes_helper.h"
#include "ruby/vm.h"
@ -257,7 +257,7 @@ rb_ec_cleanup(rb_execution_context_t *ec, enum ruby_tag_type ex)
}
}
mjit_finish(true); // We still need ISeqs here, so it's before rb_ec_finalize().
rjit_finish(true); // We still need ISeqs here, so it's before rb_ec_finalize().
rb_ec_finalize(ec);

2
gc.c
Просмотреть файл

@ -119,7 +119,7 @@
#include "internal/thread.h"
#include "internal/variable.h"
#include "internal/warnings.h"
#include "mjit.h"
#include "rjit.h"
#include "probes.h"
#include "regint.h"
#include "ruby/debug.h"

Просмотреть файл

@ -106,8 +106,8 @@ rb_call_builtin_inits(void)
BUILTIN(nilclass);
BUILTIN(marshal);
#if USE_RJIT
BUILTIN(mjit_c);
BUILTIN(mjit);
BUILTIN(rjit_c);
BUILTIN(rjit);
#endif
Init_builtin_prelude();
}

Просмотреть файл

@ -1,7 +1,7 @@
#ifndef INTERNAL_CMDLINEOPT_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_CMDLINEOPT_H
#include "mjit.h"
#include "rjit.h"
#include "yjit.h"
typedef struct {
@ -24,7 +24,7 @@ typedef struct ruby_cmdline_options {
ruby_features_t warn;
unsigned int dump;
#if USE_RJIT
struct mjit_options mjit;
struct rjit_options rjit;
#endif
int sflag, xflag;

8
iseq.c
Просмотреть файл

@ -34,7 +34,7 @@
#include "internal/thread.h"
#include "internal/variable.h"
#include "iseq.h"
#include "mjit.h"
#include "rjit.h"
#include "ruby/util.h"
#include "vm_core.h"
#include "vm_callinfo.h"
@ -164,7 +164,7 @@ rb_iseq_free(const rb_iseq_t *iseq)
if (iseq && ISEQ_BODY(iseq)) {
iseq_clear_ic_references(iseq);
struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
mjit_free_iseq(iseq); /* Notify RJIT */
rjit_free_iseq(iseq); /* Notify RJIT */
#if USE_YJIT
rb_yjit_iseq_free(body->yjit_payload);
#endif
@ -357,7 +357,7 @@ rb_iseq_mark_and_move(rb_iseq_t *iseq, bool reference_updating)
if (reference_updating) {
#if USE_RJIT
rb_mjit_iseq_update_references(body);
rb_rjit_iseq_update_references(body);
#endif
#if USE_YJIT
rb_yjit_iseq_update_references(body->yjit_payload);
@ -365,7 +365,7 @@ rb_iseq_mark_and_move(rb_iseq_t *iseq, bool reference_updating)
}
else {
#if USE_RJIT
rb_mjit_iseq_mark(body->mjit_blocks);
rb_rjit_iseq_mark(body->rjit_blocks);
#endif
#if USE_YJIT
rb_yjit_iseq_mark(body->yjit_payload);

Просмотреть файл

@ -3,7 +3,7 @@
begin
require 'rbconfig'
rescue LoadError
# for make mjit-headers
# for make rjit-headers
end
# Namespace for file utility methods for copying, moving, removing, etc.

Просмотреть файл

@ -3,7 +3,7 @@
begin
require 'rbconfig'
rescue LoadError
# for make mjit-headers
# for make rjit-headers
end
# Namespace for file utility methods for copying, moving, removing, etc.

Просмотреть файл

@ -911,9 +911,9 @@ module RubyVM::RJIT
end
def incr_counter(name)
if C.mjit_opts.stats
if C.rjit_opts.stats
comment("increment counter #{name}")
mov(:rax, C.rb_mjit_counters[name].to_i)
mov(:rax, C.rb_rjit_counters[name].to_i)
add([:rax], 1) # TODO: lock
end
end

Просмотреть файл

@ -18,9 +18,9 @@ module RubyVM::RJIT
start_addr = write_addr
# Write machine code
C.mjit_mark_writable
C.rjit_mark_writable
@write_pos += asm.assemble(start_addr)
C.mjit_mark_executable
C.rjit_mark_executable
end_addr = write_addr
@ -30,8 +30,8 @@ module RubyVM::RJIT
end
asm.comments.clear
# Dump disasm if --mjit-dump-disasm
if C.mjit_opts.dump_disasm && start_addr < end_addr
# Dump disasm if --rjit-dump-disasm
if C.rjit_opts.dump_disasm && start_addr < end_addr
dump_disasm(start_addr, end_addr)
end
start_addr

Просмотреть файл

@ -1,13 +1,13 @@
require 'ruby_vm/mjit/assembler'
require 'ruby_vm/mjit/block'
require 'ruby_vm/mjit/branch_stub'
require 'ruby_vm/mjit/code_block'
require 'ruby_vm/mjit/context'
require 'ruby_vm/mjit/exit_compiler'
require 'ruby_vm/mjit/insn_compiler'
require 'ruby_vm/mjit/instruction'
require 'ruby_vm/mjit/invariants'
require 'ruby_vm/mjit/jit_state'
require 'ruby_vm/rjit/assembler'
require 'ruby_vm/rjit/block'
require 'ruby_vm/rjit/branch_stub'
require 'ruby_vm/rjit/code_block'
require 'ruby_vm/rjit/context'
require 'ruby_vm/rjit/exit_compiler'
require 'ruby_vm/rjit/insn_compiler'
require 'ruby_vm/rjit/instruction'
require 'ruby_vm/rjit/invariants'
require 'ruby_vm/rjit/jit_state'
module RubyVM::RJIT
# Compilation status
@ -266,45 +266,45 @@ module RubyVM::RJIT
end
def incr_counter(name)
if C.mjit_opts.stats
C.rb_mjit_counters[name][0] += 1
if C.rjit_opts.stats
C.rb_rjit_counters[name][0] += 1
end
end
def list_blocks(iseq, pc)
mjit_blocks(iseq)[pc].values
rjit_blocks(iseq)[pc].values
end
# @param [Integer] pc
# @param [RubyVM::RJIT::Context] ctx
# @return [RubyVM::RJIT::Block,NilClass]
def find_block(iseq, pc, ctx)
mjit_blocks(iseq)[pc][ctx]
rjit_blocks(iseq)[pc][ctx]
end
# @param [RubyVM::RJIT::Block] block
def set_block(iseq, block)
mjit_blocks(iseq)[block.pc][block.ctx] = block
rjit_blocks(iseq)[block.pc][block.ctx] = block
end
# @param [RubyVM::RJIT::Block] block
def remove_block(iseq, block)
mjit_blocks(iseq)[block.pc].delete(block.ctx)
rjit_blocks(iseq)[block.pc].delete(block.ctx)
end
def mjit_blocks(iseq)
def rjit_blocks(iseq)
# Guard against ISEQ GC at random moments
if C.imemo_type(iseq) != C.imemo_iseq
return Hash.new { |h, k| h[k] = {} }
end
unless iseq.body.mjit_blocks
iseq.body.mjit_blocks = Hash.new { |h, k| h[k] = {} }
# For some reason, rb_mjit_iseq_mark didn't protect this Hash
unless iseq.body.rjit_blocks
iseq.body.rjit_blocks = Hash.new { |h, k| h[k] = {} }
# For some reason, rb_rjit_iseq_mark didn't protect this Hash
# from being freed. So we rely on GC_REFS to keep the Hash.
GC_REFS << iseq.body.mjit_blocks
GC_REFS << iseq.body.rjit_blocks
end
iseq.body.mjit_blocks
iseq.body.rjit_blocks
end
end
end

Просмотреть файл

@ -81,17 +81,17 @@ module RubyVM::RJIT
# @param branch_stub [RubyVM::RJIT::BranchStub]
# @param target0_p [TrueClass,FalseClass]
def compile_branch_stub(ctx, asm, branch_stub, target0_p)
# Call rb_mjit_branch_stub_hit
# Call rb_rjit_branch_stub_hit
iseq = branch_stub.iseq
if C.mjit_opts.dump_disasm && C.imemo_type(iseq) == C.imemo_iseq # Guard against ISEQ GC at random moments
if C.rjit_opts.dump_disasm && C.imemo_type(iseq) == C.imemo_iseq # Guard against ISEQ GC at random moments
asm.comment("branch stub hit: #{iseq.body.location.label}@#{C.rb_iseq_path(iseq)}:#{iseq_lineno(iseq, target0_p ? branch_stub.target0.pc : branch_stub.target1.pc)}")
end
asm.mov(:rdi, to_value(branch_stub))
asm.mov(:esi, ctx.sp_offset)
asm.mov(:edx, target0_p ? 1 : 0)
asm.call(C.rb_mjit_branch_stub_hit)
asm.call(C.rb_rjit_branch_stub_hit)
# Jump to the address returned by rb_mjit_stub_hit
# Jump to the address returned by rb_rjit_stub_hit
asm.jmp(:rax)
end
@ -104,10 +104,10 @@ module RubyVM::RJIT
# @param pc [Integer]
# @param asm [RubyVM::RJIT::Assembler]
def incr_insn_exit(pc, asm)
if C.mjit_opts.stats
if C.rjit_opts.stats
insn = Compiler.decode_insn(C.VALUE.new(pc).*)
asm.comment("increment insn exit: #{insn.name}")
asm.mov(:rax, (C.mjit_insn_exits + insn.bin).to_i)
asm.mov(:rax, (C.rjit_insn_exits + insn.bin).to_i)
asm.add([:rax], 1) # TODO: lock
end
end

Просмотреть файл

@ -1,7 +1,7 @@
module RubyVM::RJIT
module Hooks # :nodoc: all
def self.on_bop_redefined(_redefined_flag, _bop)
# C.mjit_cancel_all("BOP is redefined")
# C.rjit_cancel_all("BOP is redefined")
end
def self.on_cme_invalidate(cme)
@ -10,7 +10,7 @@ module RubyVM::RJIT
end
def self.on_ractor_spawn
# C.mjit_cancel_all("Ractor is spawned")
# C.rjit_cancel_all("Ractor is spawned")
end
# Global constant changes like const_set

Просмотреть файл

@ -21,7 +21,7 @@ module RubyVM::RJIT
# @param asm [RubyVM::RJIT::Assembler]
# @param insn `RubyVM::RJIT::Instruction`
def compile(jit, ctx, asm, insn)
asm.incr_counter(:mjit_insns_count)
asm.incr_counter(:rjit_insns_count)
asm.comment("Insn: #{insn.name}")
# 72/101
@ -512,7 +512,7 @@ module RubyVM::RJIT
idlist = ic.segments
# Make sure there is an exit for this block as the interpreter might want
# to invalidate this block from rb_mjit_constant_ic_update().
# to invalidate this block from rb_rjit_constant_ic_update().
# For now, we always take an entry exit even if it was a side exit.
Invariants.ensure_block_entry_exit(jit, cause: 'opt_getconstant_path')
@ -3296,7 +3296,7 @@ module RubyVM::RJIT
end
# EXEC_EVENT_HOOK: RUBY_EVENT_C_CALL and RUBY_EVENT_C_RETURN
if C.rb_mjit_global_events & (C.RUBY_EVENT_C_CALL | C.RUBY_EVENT_C_RETURN) != 0
if C.rb_rjit_global_events & (C.RUBY_EVENT_C_CALL | C.RUBY_EVENT_C_RETURN) != 0
asm.incr_counter(:send_c_tracing)
return CantCompile
end

Просмотреть файл

@ -130,11 +130,11 @@ module RubyVM::RJIT
end
@patches.clear
C.mjit_for_each_iseq do |iseq|
C.rjit_for_each_iseq do |iseq|
# Avoid entering past code
iseq.body.jit_func = 0
# Avoid reusing past code
iseq.body.mjit_blocks.clear if iseq.body.mjit_blocks
iseq.body.rjit_blocks.clear if iseq.body.rjit_blocks
# Compile this again if not converted to trace_* insns
iseq.body.total_calls = 0
end

Просмотреть файл

@ -29,7 +29,7 @@ module RubyVM::RJIT
def peek_at_stack(depth_from_top)
raise 'not at current insn' unless at_current_insn?
offset = -(1 + depth_from_top)
# rb_mjit_branch_stub_hit updates SP, so you don't need to worry about sp_offset
# rb_rjit_branch_stub_hit updates SP, so you don't need to worry about sp_offset
value = (cfp.sp + offset).*
C.to_ruby(value)
end

Просмотреть файл

@ -5,23 +5,23 @@ module RubyVM::RJIT
# Insn exits
INSNS.each_value do |insn|
exits = C.mjit_insn_exits[insn.bin]
exits = C.rjit_insn_exits[insn.bin]
if exits > 0
stats[:"exit_#{insn.name}"] = exits
end
end
# Runtime stats
C.rb_mjit_runtime_counters.members.each do |member|
stats[member] = C.rb_mjit_counters.public_send(member)
C.rb_rjit_runtime_counters.members.each do |member|
stats[member] = C.rb_rjit_counters.public_send(member)
end
# Other stats are calculated here
stats[:side_exit_count] = stats.select { |name, _count| name.start_with?('exit_') }.sum(&:last)
if stats[:vm_insns_count] > 0
retired_in_mjit = stats[:mjit_insns_count] - stats[:side_exit_count]
stats[:total_insns_count] = retired_in_mjit + stats[:vm_insns_count]
stats[:ratio_in_mjit] = 100.0 * retired_in_mjit / stats[:total_insns_count]
retired_in_rjit = stats[:rjit_insns_count] - stats[:side_exit_count]
stats[:total_insns_count] = retired_in_rjit + stats[:vm_insns_count]
stats[:ratio_in_rjit] = 100.0 * retired_in_rjit / stats[:total_insns_count]
end
stats
@ -47,8 +47,8 @@ module RubyVM::RJIT
$stderr.puts "side_exit_count: #{format_number(13, stats[:side_exit_count])}"
$stderr.puts "total_insns_count: #{format_number(13, stats[:total_insns_count])}" if stats.key?(:total_insns_count)
$stderr.puts "vm_insns_count: #{format_number(13, stats[:vm_insns_count])}" if stats.key?(:vm_insns_count)
$stderr.puts "mjit_insns_count: #{format_number(13, stats[:mjit_insns_count])}"
$stderr.puts "ratio_in_mjit: #{format('%12.1f', stats[:ratio_in_mjit])}%" if stats.key?(:ratio_in_mjit)
$stderr.puts "rjit_insns_count: #{format_number(13, stats[:rjit_insns_count])}"
$stderr.puts "ratio_in_rjit: #{format('%12.1f', stats[:ratio_in_rjit])}%" if stats.key?(:ratio_in_rjit)
print_exit_counts(stats)
end

Просмотреть файл

@ -109,7 +109,7 @@ int initgroups(const char *, rb_gid_t);
#include "internal/thread.h"
#include "internal/variable.h"
#include "internal/warnings.h"
#include "mjit.h"
#include "rjit.h"
#include "ruby/io.h"
#include "ruby/st.h"
#include "ruby/thread.h"
@ -1080,12 +1080,12 @@ void rb_sigwait_fd_put(const rb_thread_t *, int fd);
void rb_thread_sleep_interruptible(void);
#if USE_RJIT
static struct waitpid_state mjit_waitpid_state;
static struct waitpid_state rjit_waitpid_state;
// variables shared with thread.c
// TODO: implement the same thing with postponed_job and obviate these variables
bool mjit_waitpid_finished = false;
int mjit_waitpid_status = 0;
bool rjit_waitpid_finished = false;
int rjit_waitpid_status = 0;
#endif
static int
@ -1096,9 +1096,9 @@ waitpid_signal(struct waitpid_state *w)
return TRUE;
}
#if USE_RJIT
else if (w == &mjit_waitpid_state && w->ret) { /* mjit_add_waiting_pid */
mjit_waitpid_finished = true;
mjit_waitpid_status = w->status;
else if (w == &rjit_waitpid_state && w->ret) { /* rjit_add_waiting_pid */
rjit_waitpid_finished = true;
rjit_waitpid_status = w->status;
return TRUE;
}
#endif
@ -1202,11 +1202,11 @@ waitpid_state_init(struct waitpid_state *w, rb_pid_t pid, int options)
* must be called with vm->waitpid_lock held, this is not interruptible
*/
void
mjit_add_waiting_pid(rb_vm_t *vm, rb_pid_t pid)
rjit_add_waiting_pid(rb_vm_t *vm, rb_pid_t pid)
{
waitpid_state_init(&mjit_waitpid_state, pid, 0);
mjit_waitpid_state.ec = 0; // switch the behavior of waitpid_signal
ccan_list_add(&vm->waiting_pids, &mjit_waitpid_state.wnode);
waitpid_state_init(&rjit_waitpid_state, pid, 0);
rjit_waitpid_state.ec = 0; // switch the behavior of waitpid_signal
ccan_list_add(&vm->waiting_pids, &rjit_waitpid_state.wnode);
}
#endif
@ -1250,7 +1250,7 @@ waitpid_wait(struct waitpid_state *w)
/*
* Lock here to prevent do_waitpid from stealing work from the
* ruby_waitpid_locked done by mjit workers since mjit works
* ruby_waitpid_locked done by rjit workers since rjit works
* outside of GVL
*/
rb_native_mutex_lock(&vm->waitpid_lock);
@ -3078,7 +3078,7 @@ rb_f_exec(int argc, const VALUE *argv)
execarg_obj = rb_execarg_new(argc, argv, TRUE, FALSE);
eargp = rb_execarg_get(execarg_obj);
if (mjit_enabled) mjit_finish(false); // avoid leaking resources, and do not leave files. XXX: JIT-ed handle can leak after exec error is rescued.
if (rjit_enabled) rjit_finish(false); // avoid leaking resources, and do not leave files. XXX: JIT-ed handle can leak after exec error is rescued.
before_exec(); /* stop timer thread before redirects */
rb_protect(rb_execarg_parent_start1, execarg_obj, &state);
@ -4190,7 +4190,7 @@ retry_fork_async_signal_safe(struct rb_process_status *status, int *ep,
#if USE_RJIT
// This is used to create RJIT's child Ruby process
pid_t
rb_mjit_fork(void)
rb_rjit_fork(void)
{
struct child_handler_disabler_state old;
rb_vm_t *vm = GET_VM();
@ -4200,7 +4200,7 @@ rb_mjit_fork(void)
rb_native_mutex_lock(&vm->waitpid_lock);
pid_t pid = rb_fork();
if (pid > 0) mjit_add_waiting_pid(vm, pid);
if (pid > 0) rjit_add_waiting_pid(vm, pid);
rb_native_mutex_unlock(&vm->waitpid_lock);
after_fork_ruby();
@ -4297,7 +4297,7 @@ rb_fork_ruby2(struct rb_process_status *status)
while (1) {
prefork();
if (mjit_enabled) mjit_pause(false); // Don't leave locked mutex to child. Note: child_handler must be enabled to pause RJIT.
if (rjit_enabled) rjit_pause(false); // Don't leave locked mutex to child. Note: child_handler must be enabled to pause RJIT.
disable_child_handler_before_fork(&old);
before_fork_ruby();
pid = rb_fork();
@ -4309,7 +4309,7 @@ rb_fork_ruby2(struct rb_process_status *status)
after_fork_ruby();
disable_child_handler_fork_parent(&old); /* yes, bad name */
if (mjit_enabled && pid > 0) mjit_resume(); /* child (pid == 0) is cared by rb_thread_atfork */
if (rjit_enabled && pid > 0) rjit_resume(); /* child (pid == 0) is cared by rb_thread_atfork */
if (pid >= 0) { /* fork succeed */
if (pid == 0) rb_thread_atfork();
@ -4722,7 +4722,7 @@ rb_execarg_spawn(VALUE execarg_obj, char *errmsg, size_t errmsg_buflen)
* Prevent a race with RJIT where the compiler process where
* can hold an FD of ours in between vfork + execve
*/
if (!eargp->waitpid_state && mjit_enabled) {
if (!eargp->waitpid_state && rjit_enabled) {
eargp->waitpid_state = WAITPID_LOCK_ONLY;
}
@ -7088,11 +7088,11 @@ rb_daemon(int nochdir, int noclose)
{
int err = 0;
#ifdef HAVE_DAEMON
if (mjit_enabled) mjit_pause(false); // Don't leave locked mutex to child.
if (rjit_enabled) rjit_pause(false); // Don't leave locked mutex to child.
before_fork_ruby();
err = daemon(nochdir, noclose);
after_fork_ruby();
rb_thread_atfork(); /* calls mjit_resume() */
rb_thread_atfork(); /* calls rjit_resume() */
#else
int n;

Просмотреть файл

@ -18,7 +18,7 @@
#include "variable.h"
#include "transient_heap.h"
#include "yjit.h"
#include "mjit.h"
#include "rjit.h"
VALUE rb_cRactor;
static VALUE rb_cRactorSelector;
@ -2008,7 +2008,7 @@ ractor_create(rb_execution_context_t *ec, VALUE self, VALUE loc, VALUE name, VAL
r->debug = cr->debug;
rb_yjit_before_ractor_spawn();
rb_mjit_before_ractor_spawn();
rb_rjit_before_ractor_spawn();
rb_thread_create_ractor(r, args, block);
RB_GC_GUARD(rv);

261
rjit.c
Просмотреть файл

@ -1,16 +1,15 @@
/**********************************************************************
mjit.c - MRI method JIT compiler functions
rjit.c - Ruby JIT compiler functions
Copyright (C) 2017 Vladimir Makarov <vmakarov@redhat.com>.
Copyright (C) 2017 Takashi Kokubun <k0kubun@ruby-lang.org>.
Copyright (C) 2023 Takashi Kokubun <k0kubun@ruby-lang.org>.
**********************************************************************/
#include "ruby/internal/config.h" // defines USE_RJIT
// ISO C requires a translation unit to contain at least one declaration
void rb_mjit(void) {}
void rb_rjit(void) {}
#if USE_RJIT
@ -33,8 +32,8 @@ void rb_mjit(void) {}
#include "vm_core.h"
#include "vm_callinfo.h"
#include "mjit.h"
#include "mjit_c.h"
#include "rjit.h"
#include "rjit_c.h"
#include "ruby_assert.h"
#include "ruby/debug.h"
#include "ruby/thread.h"
@ -62,23 +61,23 @@ void rb_mjit(void) {}
// A copy of RJIT portion of MRI options since RJIT initialization. We
// need them as RJIT threads still can work when the most MRI data were
// freed.
struct mjit_options mjit_opts;
struct rjit_options rjit_opts;
// true if RJIT is enabled.
bool mjit_enabled = false;
bool mjit_stats_enabled = false;
bool rjit_enabled = false;
bool rjit_stats_enabled = false;
// true if JIT-ed code should be called. When `ruby_vm_event_enabled_global_flags & ISEQ_TRACE_EVENTS`
// and `mjit_call_p == false`, any JIT-ed code execution is cancelled as soon as possible.
bool mjit_call_p = false;
// A flag to communicate that mjit_call_p should be disabled while it's temporarily false.
bool mjit_cancel_p = false;
// and `rjit_call_p == false`, any JIT-ed code execution is cancelled as soon as possible.
bool rjit_call_p = false;
// A flag to communicate that rjit_call_p should be disabled while it's temporarily false.
bool rjit_cancel_p = false;
// Print the arguments according to FORMAT to stderr only if RJIT
// verbose option value is more or equal to LEVEL.
PRINTF_ARGS(static void, 2, 3)
verbose(int level, const char *format, ...)
{
if (mjit_opts.verbose >= level) {
if (rjit_opts.verbose >= level) {
va_list args;
size_t len = strlen(format);
char *full_format = alloca(sizeof(char) * (len + 2));
@ -95,33 +94,33 @@ verbose(int level, const char *format, ...)
}
int
mjit_capture_cc_entries(const struct rb_iseq_constant_body *compiled_iseq, const struct rb_iseq_constant_body *captured_iseq)
rjit_capture_cc_entries(const struct rb_iseq_constant_body *compiled_iseq, const struct rb_iseq_constant_body *captured_iseq)
{
// TODO: remove this
return 0;
}
void
mjit_cancel_all(const char *reason)
rjit_cancel_all(const char *reason)
{
if (!mjit_enabled)
if (!rjit_enabled)
return;
mjit_call_p = false;
mjit_cancel_p = true;
if (mjit_opts.warnings || mjit_opts.verbose) {
rjit_call_p = false;
rjit_cancel_p = true;
if (rjit_opts.warnings || rjit_opts.verbose) {
fprintf(stderr, "JIT cancel: Disabled JIT-ed code because %s\n", reason);
}
}
void
mjit_free_iseq(const rb_iseq_t *iseq)
rjit_free_iseq(const rb_iseq_t *iseq)
{
// TODO: remove this
}
void
mjit_notify_waitpid(int exit_code)
rjit_notify_waitpid(int exit_code)
{
// TODO: remove this function
}
@ -140,44 +139,44 @@ static VALUE rb_cRJITCfpPtr = 0;
static VALUE rb_mRJITHooks = 0;
void
rb_mjit_add_iseq_to_process(const rb_iseq_t *iseq)
rb_rjit_add_iseq_to_process(const rb_iseq_t *iseq)
{
// TODO: implement
}
struct rb_mjit_compile_info*
rb_mjit_iseq_compile_info(const struct rb_iseq_constant_body *body)
struct rb_rjit_compile_info*
rb_rjit_iseq_compile_info(const struct rb_iseq_constant_body *body)
{
// TODO: remove this
return NULL;
}
void
rb_mjit_recompile_send(const rb_iseq_t *iseq)
rb_rjit_recompile_send(const rb_iseq_t *iseq)
{
// TODO: remove this
}
void
rb_mjit_recompile_ivar(const rb_iseq_t *iseq)
rb_rjit_recompile_ivar(const rb_iseq_t *iseq)
{
// TODO: remove this
}
void
rb_mjit_recompile_exivar(const rb_iseq_t *iseq)
rb_rjit_recompile_exivar(const rb_iseq_t *iseq)
{
// TODO: remove this
}
void
rb_mjit_recompile_inlining(const rb_iseq_t *iseq)
rb_rjit_recompile_inlining(const rb_iseq_t *iseq)
{
// TODO: remove this
}
void
rb_mjit_recompile_const(const rb_iseq_t *iseq)
rb_rjit_recompile_const(const rb_iseq_t *iseq)
{
// TODO: remove this
}
@ -188,50 +187,50 @@ rb_mjit_recompile_const(const rb_iseq_t *iseq)
#define DEFAULT_CALL_THRESHOLD 30
#define opt_match_noarg(s, l, name) \
opt_match(s, l, name) && (*(s) ? (rb_warn("argument to --mjit-" name " is ignored"), 1) : 1)
opt_match(s, l, name) && (*(s) ? (rb_warn("argument to --rjit-" name " is ignored"), 1) : 1)
#define opt_match_arg(s, l, name) \
opt_match(s, l, name) && (*(s) ? 1 : (rb_raise(rb_eRuntimeError, "--mjit-" name " needs an argument"), 0))
opt_match(s, l, name) && (*(s) ? 1 : (rb_raise(rb_eRuntimeError, "--rjit-" name " needs an argument"), 0))
void
mjit_setup_options(const char *s, struct mjit_options *mjit_opt)
rjit_setup_options(const char *s, struct rjit_options *rjit_opt)
{
const size_t l = strlen(s);
if (l == 0) {
return;
}
else if (opt_match_noarg(s, l, "warnings")) {
mjit_opt->warnings = true;
rjit_opt->warnings = true;
}
else if (opt_match(s, l, "debug")) {
if (*s)
mjit_opt->debug_flags = strdup(s + 1);
rjit_opt->debug_flags = strdup(s + 1);
else
mjit_opt->debug = true;
rjit_opt->debug = true;
}
else if (opt_match_noarg(s, l, "wait")) {
mjit_opt->wait = true;
rjit_opt->wait = true;
}
else if (opt_match_noarg(s, l, "save-temps")) {
mjit_opt->save_temps = true;
rjit_opt->save_temps = true;
}
else if (opt_match(s, l, "verbose")) {
mjit_opt->verbose = *s ? atoi(s + 1) : 1;
rjit_opt->verbose = *s ? atoi(s + 1) : 1;
}
else if (opt_match_arg(s, l, "max-cache")) {
mjit_opt->max_cache_size = atoi(s + 1);
rjit_opt->max_cache_size = atoi(s + 1);
}
else if (opt_match_arg(s, l, "call-threshold")) {
mjit_opt->call_threshold = atoi(s + 1);
rjit_opt->call_threshold = atoi(s + 1);
}
else if (opt_match_noarg(s, l, "stats")) {
mjit_opt->stats = true;
rjit_opt->stats = true;
}
// --mjit=pause is an undocumented feature for experiments
// --rjit=pause is an undocumented feature for experiments
else if (opt_match_noarg(s, l, "pause")) {
mjit_opt->pause = true;
rjit_opt->pause = true;
}
else if (opt_match_noarg(s, l, "dump-disasm")) {
mjit_opt->dump_disasm = true;
rjit_opt->dump_disasm = true;
}
else {
rb_raise(rb_eRuntimeError,
@ -240,42 +239,42 @@ mjit_setup_options(const char *s, struct mjit_options *mjit_opt)
}
#define M(shortopt, longopt, desc) RUBY_OPT_MESSAGE(shortopt, longopt, desc)
const struct ruby_opt_message mjit_option_messages[] = {
M("--mjit-warnings", "", "Enable printing JIT warnings"),
M("--mjit-debug", "", "Enable JIT debugging (very slow), or add cflags if specified"),
M("--mjit-wait", "", "Wait until JIT compilation finishes every time (for testing)"),
M("--mjit-save-temps", "", "Save JIT temporary files in $TMP or /tmp (for testing)"),
M("--mjit-verbose=num", "", "Print JIT logs of level num or less to stderr (default: 0)"),
M("--mjit-max-cache=num", "", "Max number of methods to be JIT-ed in a cache (default: " STRINGIZE(DEFAULT_MAX_CACHE_SIZE) ")"),
M("--mjit-call-threshold=num", "", "Number of calls to trigger JIT (for testing, default: " STRINGIZE(DEFAULT_CALL_THRESHOLD) ")"),
M("--mjit-stats", "", "Enable collecting RJIT statistics"),
const struct ruby_opt_message rjit_option_messages[] = {
M("--rjit-warnings", "", "Enable printing JIT warnings"),
M("--rjit-debug", "", "Enable JIT debugging (very slow), or add cflags if specified"),
M("--rjit-wait", "", "Wait until JIT compilation finishes every time (for testing)"),
M("--rjit-save-temps", "", "Save JIT temporary files in $TMP or /tmp (for testing)"),
M("--rjit-verbose=num", "", "Print JIT logs of level num or less to stderr (default: 0)"),
M("--rjit-max-cache=num", "", "Max number of methods to be JIT-ed in a cache (default: " STRINGIZE(DEFAULT_MAX_CACHE_SIZE) ")"),
M("--rjit-call-threshold=num", "", "Number of calls to trigger JIT (for testing, default: " STRINGIZE(DEFAULT_CALL_THRESHOLD) ")"),
M("--rjit-stats", "", "Enable collecting RJIT statistics"),
{0}
};
#undef M
VALUE
mjit_pause(bool wait_p)
rjit_pause(bool wait_p)
{
// TODO: remove this
return Qtrue;
}
VALUE
mjit_resume(void)
rjit_resume(void)
{
// TODO: remove this
return Qnil;
}
void
mjit_child_after_fork(void)
rjit_child_after_fork(void)
{
// TODO: remove this
}
// Compile ISeq to C code in `f`. It returns true if it succeeds to compile.
bool
mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id)
rjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id)
{
// TODO: implement
return false;
@ -287,23 +286,23 @@ mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id)
//
// JIT buffer
uint8_t *rb_mjit_mem_block = NULL;
uint8_t *rb_rjit_mem_block = NULL;
// `rb_ec_ractor_hooks(ec)->events` is moved to this variable during compilation.
rb_event_flag_t rb_mjit_global_events = 0;
rb_event_flag_t rb_rjit_global_events = 0;
// Basically mjit_opts.stats, but this becomes false during RJIT compilation.
static bool mjit_stats_p = false;
// Basically rjit_opts.stats, but this becomes false during RJIT compilation.
static bool rjit_stats_p = false;
#if RJIT_STATS
struct rb_mjit_runtime_counters rb_mjit_counters = { 0 };
struct rb_rjit_runtime_counters rb_rjit_counters = { 0 };
void
rb_mjit_collect_vm_usage_insn(int insn)
rb_rjit_collect_vm_usage_insn(int insn)
{
if (!mjit_stats_p) return;
rb_mjit_counters.vm_insns_count++;
if (!rjit_stats_p) return;
rb_rjit_counters.vm_insns_count++;
}
#endif // YJIT_STATS
@ -314,29 +313,29 @@ extern VALUE rb_gc_disable(void);
#define WITH_RJIT_ISOLATED(stmt) do { \
VALUE was_disabled = rb_gc_disable(); \
rb_hook_list_t *global_hooks = rb_ec_ractor_hooks(GET_EC()); \
rb_mjit_global_events = global_hooks->events; \
rb_rjit_global_events = global_hooks->events; \
global_hooks->events = 0; \
bool original_call_p = mjit_call_p; \
mjit_stats_p = false; \
mjit_call_p = false; \
bool original_call_p = rjit_call_p; \
rjit_stats_p = false; \
rjit_call_p = false; \
stmt; \
mjit_call_p = (mjit_cancel_p ? false : original_call_p); \
mjit_stats_p = mjit_opts.stats; \
global_hooks->events = rb_mjit_global_events; \
rjit_call_p = (rjit_cancel_p ? false : original_call_p); \
rjit_stats_p = rjit_opts.stats; \
global_hooks->events = rb_rjit_global_events; \
if (!was_disabled) rb_gc_enable(); \
} while (0);
void
rb_mjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop)
rb_rjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop)
{
if (!mjit_call_p) return;
mjit_call_p = false;
if (!rjit_call_p) return;
rjit_call_p = false;
}
static void
mjit_cme_invalidate(void *data)
rjit_cme_invalidate(void *data)
{
if (!mjit_enabled || !mjit_call_p || !rb_mRJITHooks) return;
if (!rjit_enabled || !rjit_call_p || !rb_mRJITHooks) return;
WITH_RJIT_ISOLATED({
rb_funcall(rb_mRJITHooks, rb_intern("on_cme_invalidate"), 1, SIZET2NUM((size_t)data));
});
@ -345,24 +344,24 @@ mjit_cme_invalidate(void *data)
extern int rb_workqueue_register(unsigned flags, rb_postponed_job_func_t func, void *data);
void
rb_mjit_cme_invalidate(rb_callable_method_entry_t *cme)
rb_rjit_cme_invalidate(rb_callable_method_entry_t *cme)
{
if (!mjit_enabled || !mjit_call_p || !rb_mRJITHooks) return;
if (!rjit_enabled || !rjit_call_p || !rb_mRJITHooks) return;
// Asynchronously hook the Ruby code since running Ruby in the middle of cme invalidation is dangerous.
rb_workqueue_register(0, mjit_cme_invalidate, (void *)cme);
rb_workqueue_register(0, rjit_cme_invalidate, (void *)cme);
}
void
rb_mjit_before_ractor_spawn(void)
rb_rjit_before_ractor_spawn(void)
{
if (!mjit_call_p) return;
mjit_call_p = false;
if (!rjit_call_p) return;
rjit_call_p = false;
}
static void
mjit_constant_state_changed(void *data)
rjit_constant_state_changed(void *data)
{
if (!mjit_enabled || !mjit_call_p || !rb_mRJITHooks) return;
if (!rjit_enabled || !rjit_call_p || !rb_mRJITHooks) return;
RB_VM_LOCK_ENTER();
rb_vm_barrier();
@ -374,17 +373,17 @@ mjit_constant_state_changed(void *data)
}
void
rb_mjit_constant_state_changed(ID id)
rb_rjit_constant_state_changed(ID id)
{
if (!mjit_enabled || !mjit_call_p || !rb_mRJITHooks) return;
if (!rjit_enabled || !rjit_call_p || !rb_mRJITHooks) return;
// Asynchronously hook the Ruby code since this is hooked during a "Ruby critical section".
rb_workqueue_register(0, mjit_constant_state_changed, (void *)id);
rb_workqueue_register(0, rjit_constant_state_changed, (void *)id);
}
void
rb_mjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx)
rb_rjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx)
{
if (!mjit_enabled || !mjit_call_p || !rb_mRJITHooks) return;
if (!rjit_enabled || !rjit_call_p || !rb_mRJITHooks) return;
RB_VM_LOCK_ENTER();
rb_vm_barrier();
@ -398,59 +397,59 @@ rb_mjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx
}
void
rb_mjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events)
rb_rjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events)
{
if (!mjit_enabled || !mjit_call_p || !rb_mRJITHooks) return;
if (!rjit_enabled || !rjit_call_p || !rb_mRJITHooks) return;
WITH_RJIT_ISOLATED({
rb_funcall(rb_mRJITHooks, rb_intern("on_tracing_invalidate_all"), 1, UINT2NUM(new_iseq_events));
});
}
static void
mjit_iseq_update_references(void *data)
rjit_iseq_update_references(void *data)
{
if (!mjit_enabled || !mjit_call_p || !rb_mRJITHooks) return;
if (!rjit_enabled || !rjit_call_p || !rb_mRJITHooks) return;
WITH_RJIT_ISOLATED({
rb_funcall(rb_mRJITHooks, rb_intern("on_update_references"), 0);
});
}
void
rb_mjit_iseq_update_references(struct rb_iseq_constant_body *const body)
rb_rjit_iseq_update_references(struct rb_iseq_constant_body *const body)
{
if (!mjit_enabled) return;
if (!rjit_enabled) return;
if (body->mjit_blocks) {
body->mjit_blocks = rb_gc_location(body->mjit_blocks);
if (body->rjit_blocks) {
body->rjit_blocks = rb_gc_location(body->rjit_blocks);
}
// Asynchronously hook the Ruby code to avoid allocation during GC.compact.
// Using _one because it's too slow to invalidate all for each ISEQ. Thus
// not giving an ISEQ pointer.
rb_postponed_job_register_one(0, mjit_iseq_update_references, NULL);
rb_postponed_job_register_one(0, rjit_iseq_update_references, NULL);
}
void
rb_mjit_iseq_mark(VALUE mjit_blocks)
rb_rjit_iseq_mark(VALUE rjit_blocks)
{
if (!mjit_enabled) return;
if (!rjit_enabled) return;
// Note: This wasn't enough for some reason.
// We actually rely on RubyVM::RJIT::GC_REFS to mark this.
if (mjit_blocks) {
rb_gc_mark_movable(mjit_blocks);
if (rjit_blocks) {
rb_gc_mark_movable(rjit_blocks);
}
}
// TODO: Use this in more places
VALUE
rb_mjit_iseq_new(rb_iseq_t *iseq)
rb_rjit_iseq_new(rb_iseq_t *iseq)
{
return rb_funcall(rb_cRJITIseqPtr, rb_intern("new"), 1, SIZET2NUM((size_t)iseq));
}
void
rb_mjit_compile(const rb_iseq_t *iseq)
rb_rjit_compile(const rb_iseq_t *iseq)
{
RB_VM_LOCK_ENTER();
rb_vm_barrier();
@ -465,7 +464,7 @@ rb_mjit_compile(const rb_iseq_t *iseq)
}
void *
rb_mjit_branch_stub_hit(VALUE branch_stub, int sp_offset, int target0_p)
rb_rjit_branch_stub_hit(VALUE branch_stub, int sp_offset, int target0_p)
{
VALUE result;
@ -489,11 +488,11 @@ rb_mjit_branch_stub_hit(VALUE branch_stub, int sp_offset, int target0_p)
// Called by rb_vm_mark()
void
mjit_mark(void)
rjit_mark(void)
{
if (!mjit_enabled)
if (!rjit_enabled)
return;
RUBY_MARK_ENTER("mjit");
RUBY_MARK_ENTER("rjit");
// Pin object pointers used in this file
rb_gc_mark(rb_RJITCompiler);
@ -501,67 +500,67 @@ mjit_mark(void)
rb_gc_mark(rb_cRJITCfpPtr);
rb_gc_mark(rb_mRJITHooks);
RUBY_MARK_LEAVE("mjit");
RUBY_MARK_LEAVE("rjit");
}
void
mjit_init(const struct mjit_options *opts)
rjit_init(const struct rjit_options *opts)
{
VM_ASSERT(mjit_enabled);
mjit_opts = *opts;
VM_ASSERT(rjit_enabled);
rjit_opts = *opts;
extern uint8_t* rb_yjit_reserve_addr_space(uint32_t mem_size);
rb_mjit_mem_block = rb_yjit_reserve_addr_space(RJIT_CODE_SIZE);
rb_rjit_mem_block = rb_yjit_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"));
if (!rb_const_defined(rb_mRJIT, rb_intern("Compiler"))) {
verbose(1, "Disabling RJIT because RubyVM::RJIT::Compiler is not defined");
mjit_enabled = false;
rjit_enabled = false;
return;
}
rb_mRJITC = rb_const_get(rb_mRJIT, rb_intern("C"));
VALUE rb_cRJITCompiler = rb_const_get(rb_mRJIT, rb_intern("Compiler"));
rb_RJITCompiler = rb_funcall(rb_cRJITCompiler, rb_intern("new"), 2,
SIZET2NUM((size_t)rb_mjit_mem_block), UINT2NUM(RJIT_CODE_SIZE));
SIZET2NUM((size_t)rb_rjit_mem_block), UINT2NUM(RJIT_CODE_SIZE));
rb_cRJITIseqPtr = rb_funcall(rb_mRJITC, rb_intern("rb_iseq_t"), 0);
rb_cRJITCfpPtr = rb_funcall(rb_mRJITC, rb_intern("rb_control_frame_t"), 0);
rb_mRJITHooks = rb_const_get(rb_mRJIT, rb_intern("Hooks"));
mjit_call_p = true;
mjit_stats_p = mjit_opts.stats;
rjit_call_p = true;
rjit_stats_p = rjit_opts.stats;
// Normalize options
if (mjit_opts.call_threshold == 0)
mjit_opts.call_threshold = DEFAULT_CALL_THRESHOLD;
if (rjit_opts.call_threshold == 0)
rjit_opts.call_threshold = DEFAULT_CALL_THRESHOLD;
#ifndef HAVE_LIBCAPSTONE
if (mjit_opts.dump_disasm)
verbose(1, "libcapstone has not been linked. Ignoring --mjit-dump-disasm.");
if (rjit_opts.dump_disasm)
verbose(1, "libcapstone has not been linked. Ignoring --rjit-dump-disasm.");
#endif
}
void
mjit_finish(bool close_handle_p)
rjit_finish(bool close_handle_p)
{
// TODO: implement
}
// Same as `RubyVM::RJIT::C.enabled?`, but this is used before mjit_init.
// Same as `RubyVM::RJIT::C.enabled?`, but this is used before rjit_init.
static VALUE
mjit_stats_enabled_p(rb_execution_context_t *ec, VALUE self)
rjit_stats_enabled_p(rb_execution_context_t *ec, VALUE self)
{
return RBOOL(mjit_stats_enabled);
return RBOOL(rjit_stats_enabled);
}
// Disable anything that could impact stats. It ends up disabling JIT calls as well.
static VALUE
mjit_stop_stats(rb_execution_context_t *ec, VALUE self)
rjit_stop_stats(rb_execution_context_t *ec, VALUE self)
{
mjit_call_p = false;
mjit_stats_p = false;
rjit_call_p = false;
rjit_stats_p = false;
return Qnil;
}
#include "mjit.rbinc"
#include "rjit.rbinc"
#endif // USE_RJIT

111
rjit.h
Просмотреть файл

@ -2,10 +2,9 @@
#define RUBY_RJIT_H 1
/**********************************************************************
mjit.h - Interface to MRI method JIT compiler
rjit.h - Interface to RJIT
Copyright (C) 2017 Vladimir Makarov <vmakarov@redhat.com>.
Copyright (C) 2017 Takashi Kokubun <k0kubun@ruby-lang.org>.
Copyright (C) 2023 Takashi Kokubun <k0kubun@ruby-lang.org>.
**********************************************************************/
@ -24,7 +23,7 @@
// Special address values of a function generated from the
// corresponding iseq by RJIT:
enum rb_mjit_func_state {
enum rb_rjit_func_state {
// ISEQ has not been compiled yet
RJIT_FUNC_NOT_COMPILED = 0,
// ISEQ is already queued for the machine code generation but the
@ -34,11 +33,11 @@ enum rb_mjit_func_state {
// or the unit is unloaded
RJIT_FUNC_FAILED = 2,
};
// Return true if jit_func is part of enum rb_mjit_func_state
// Return true if jit_func is part of enum rb_rjit_func_state
#define RJIT_FUNC_STATE_P(jit_func) ((uintptr_t)(jit_func) <= (uintptr_t)RJIT_FUNC_FAILED)
// RJIT options which can be defined on the MRI command line.
struct mjit_options {
struct rjit_options {
// Converted from "jit" feature flag to tell the enablement
// information to ruby_show_version().
bool on;
@ -74,7 +73,7 @@ struct mjit_options {
};
// State of optimization switches
struct rb_mjit_compile_info {
struct rb_rjit_compile_info {
// Disable getinstancevariable/setinstancevariable optimizations based on inline cache (T_OBJECT)
bool disable_ivar_cache;
// Disable getinstancevariable/setinstancevariable optimizations based on inline cache (FL_EXIVAR)
@ -90,69 +89,69 @@ struct rb_mjit_compile_info {
typedef VALUE (*jit_func_t)(rb_execution_context_t *, rb_control_frame_t *);
RUBY_SYMBOL_EXPORT_BEGIN
RUBY_EXTERN struct mjit_options mjit_opts;
RUBY_EXTERN bool mjit_call_p;
RUBY_EXTERN struct rjit_options rjit_opts;
RUBY_EXTERN bool rjit_call_p;
extern void rb_mjit_compile(const rb_iseq_t *iseq);
extern struct rb_mjit_compile_info* rb_mjit_iseq_compile_info(const struct rb_iseq_constant_body *body);
extern void rb_mjit_recompile_send(const rb_iseq_t *iseq);
extern void rb_mjit_recompile_ivar(const rb_iseq_t *iseq);
extern void rb_mjit_recompile_exivar(const rb_iseq_t *iseq);
extern void rb_mjit_recompile_inlining(const rb_iseq_t *iseq);
extern void rb_mjit_recompile_const(const rb_iseq_t *iseq);
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);
extern void rb_rjit_recompile_ivar(const rb_iseq_t *iseq);
extern void rb_rjit_recompile_exivar(const rb_iseq_t *iseq);
extern void rb_rjit_recompile_inlining(const rb_iseq_t *iseq);
extern void rb_rjit_recompile_const(const rb_iseq_t *iseq);
RUBY_SYMBOL_EXPORT_END
extern void mjit_cancel_all(const char *reason);
extern bool mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id);
extern void mjit_init(const struct mjit_options *opts);
extern void mjit_free_iseq(const rb_iseq_t *iseq);
extern void rb_mjit_iseq_update_references(struct rb_iseq_constant_body *const body);
extern void mjit_mark(void);
extern void rb_mjit_iseq_mark(VALUE mjit_blocks);
extern void mjit_notify_waitpid(int exit_code);
extern void rjit_cancel_all(const char *reason);
extern bool rjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id);
extern void rjit_init(const struct rjit_options *opts);
extern void rjit_free_iseq(const rb_iseq_t *iseq);
extern void rb_rjit_iseq_update_references(struct rb_iseq_constant_body *const body);
extern void rjit_mark(void);
extern void rb_rjit_iseq_mark(VALUE rjit_blocks);
extern void rjit_notify_waitpid(int exit_code);
extern void rb_mjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop);
extern void rb_mjit_cme_invalidate(rb_callable_method_entry_t *cme);
extern void rb_mjit_before_ractor_spawn(void);
extern void rb_mjit_constant_state_changed(ID id);
extern void rb_mjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx);
extern void rb_mjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events);
extern void rb_rjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop);
extern void rb_rjit_cme_invalidate(rb_callable_method_entry_t *cme);
extern void rb_rjit_before_ractor_spawn(void);
extern void rb_rjit_constant_state_changed(ID id);
extern void rb_rjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx);
extern void rb_rjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events);
void mjit_child_after_fork(void);
void rjit_child_after_fork(void);
extern void rb_mjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop);
extern void rb_mjit_before_ractor_spawn(void);
extern void rb_mjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events);
extern void rb_mjit_collect_vm_usage_insn(int insn);
extern void rb_rjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop);
extern void rb_rjit_before_ractor_spawn(void);
extern void rb_rjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events);
extern void rb_rjit_collect_vm_usage_insn(int insn);
extern bool mjit_enabled;
extern bool mjit_stats_enabled;
VALUE mjit_pause(bool wait_p);
VALUE mjit_resume(void);
void mjit_finish(bool close_handle_p);
extern bool rjit_enabled;
extern bool rjit_stats_enabled;
VALUE rjit_pause(bool wait_p);
VALUE rjit_resume(void);
void rjit_finish(bool close_handle_p);
# else // USE_RJIT
static inline void mjit_cancel_all(const char *reason){}
static inline void mjit_free_iseq(const rb_iseq_t *iseq){}
static inline void mjit_mark(void){}
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 mjit_child_after_fork(void){}
static inline void rjit_child_after_fork(void){}
static inline void rb_mjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop) {}
static inline void rb_mjit_cme_invalidate(rb_callable_method_entry_t *cme) {}
static inline void rb_mjit_before_ractor_spawn(void) {}
static inline void rb_mjit_constant_state_changed(ID id) {}
static inline void rb_mjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx) {}
static inline void rb_mjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events) {}
static inline void rb_rjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop) {}
static inline void rb_rjit_cme_invalidate(rb_callable_method_entry_t *cme) {}
static inline void rb_rjit_before_ractor_spawn(void) {}
static inline void rb_rjit_constant_state_changed(ID id) {}
static inline void rb_rjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx) {}
static inline void rb_rjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events) {}
#define mjit_enabled false
#define mjit_stats_enabled false
static inline VALUE mjit_pause(bool wait_p){ return Qnil; } // unreachable
static inline VALUE mjit_resume(void){ return Qnil; } // unreachable
static inline void mjit_finish(bool close_handle_p){}
#define rjit_enabled false
#define rjit_stats_enabled false
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){}
static inline void rb_mjit_collect_vm_usage_insn(int insn) {}
static inline void rb_rjit_collect_vm_usage_insn(int insn) {}
# endif // USE_RJIT
#endif // RUBY_RJIT_H

18
rjit.rb
Просмотреть файл

@ -1,22 +1,22 @@
module RubyVM::RJIT
# Return true if RJIT is enabled.
def self.enabled?
Primitive.cexpr! 'RBOOL(mjit_enabled)'
Primitive.cexpr! 'RBOOL(rjit_enabled)'
end
# Stop generating JITed code.
def self.pause(wait: true)
Primitive.cexpr! 'mjit_pause(RTEST(wait))'
Primitive.cexpr! 'rjit_pause(RTEST(wait))'
end
# Start generating JITed code again after pause.
def self.resume
Primitive.cexpr! 'mjit_resume()'
Primitive.cexpr! 'rjit_resume()'
end
if Primitive.mjit_stats_enabled_p
if Primitive.rjit_stats_enabled_p
at_exit do
Primitive.mjit_stop_stats
Primitive.rjit_stop_stats
print_stats
end
end
@ -30,8 +30,8 @@ if RubyVM::RJIT.enabled?
return # miniruby doesn't support RJIT
end
require 'ruby_vm/mjit/c_type'
require 'ruby_vm/mjit/compiler'
require 'ruby_vm/mjit/hooks'
require 'ruby_vm/mjit/stats'
require 'ruby_vm/rjit/c_type'
require 'ruby_vm/rjit/compiler'
require 'ruby_vm/rjit/hooks'
require 'ruby_vm/rjit/stats'
end

Просмотреть файл

@ -1,6 +1,6 @@
/**********************************************************************
mjit_c.c - C helpers for RJIT
rjit_c.c - C helpers for RJIT
Copyright (C) 2017 Takashi Kokubun <k0kubun@ruby-lang.org>.
@ -9,12 +9,12 @@
#include "ruby/internal/config.h" // defines USE_RJIT
// ISO C requires a translation unit to contain at least one declaration
void rb_mjit_c(void) {}
void rb_rjit_c(void) {}
#if USE_RJIT
#include "mjit.h"
#include "mjit_c.h"
#include "rjit.h"
#include "rjit_c.h"
#include "internal.h"
#include "internal/compile.h"
#include "internal/fixnum.h"
@ -44,7 +44,7 @@ void rb_mjit_c(void) {}
#if RJIT_STATS
// Insn side exit counters
static size_t mjit_insn_exits[VM_INSTRUCTION_SIZE] = { 0 };
static size_t rjit_insn_exits[VM_INSTRUCTION_SIZE] = { 0 };
#endif // YJIT_STATS
// macOS: brew install capstone
@ -85,9 +85,9 @@ dump_disasm(rb_execution_context_t *ec, VALUE self, VALUE from, VALUE to)
// Same as `RubyVM::RJIT.enabled?`, but this is used before it's defined.
static VALUE
mjit_enabled_p(rb_execution_context_t *ec, VALUE self)
rjit_enabled_p(rb_execution_context_t *ec, VALUE self)
{
return RBOOL(mjit_enabled);
return RBOOL(rjit_enabled);
}
static int
@ -100,9 +100,9 @@ for_each_iseq_i(void *vstart, void *vend, size_t stride, void *data)
asan_unpoison_object(v, false);
if (rb_obj_is_iseq(v)) {
extern VALUE rb_mjit_iseq_new(rb_iseq_t *iseq);
extern VALUE rb_rjit_iseq_new(rb_iseq_t *iseq);
rb_iseq_t *iseq = (rb_iseq_t *)v;
rb_funcall(block, rb_intern("call"), 1, rb_mjit_iseq_new(iseq));
rb_funcall(block, rb_intern("call"), 1, rb_rjit_iseq_new(iseq));
}
asan_poison_object_if(ptr, v);
@ -111,7 +111,7 @@ for_each_iseq_i(void *vstart, void *vend, size_t stride, void *data)
}
static VALUE
mjit_for_each_iseq(rb_execution_context_t *ec, VALUE self, VALUE block)
rjit_for_each_iseq(rb_execution_context_t *ec, VALUE self, VALUE block)
{
rb_objspace_each_objects(for_each_iseq_i, (void *)block);
return Qnil;
@ -120,6 +120,6 @@ mjit_for_each_iseq(rb_execution_context_t *ec, VALUE self, VALUE block)
extern bool rb_simple_iseq_p(const rb_iseq_t *iseq);
extern ID rb_get_symbol_id(VALUE name);
#include "mjit_c.rbinc"
#include "rjit_c.rbinc"
#endif // USE_RJIT

Просмотреть файл

@ -1,4 +1,4 @@
// This file is parsed by tool/mjit/generate.rb to generate mjit_c.rb
// This file is parsed by tool/rjit/generate.rb to generate rjit_c.rb
#ifndef RJIT_C_H
#define RJIT_C_H
@ -10,44 +10,44 @@
#include "vm_callinfo.h"
#include "builtin.h"
#include "ccan/list/list.h"
#include "mjit.h"
#include "rjit.h"
#include "shape.h"
// Macros to check if a position is already compiled using compile_status.stack_size_for_pos
#define NOT_COMPILED_STACK_SIZE -1
#define ALREADY_COMPILED_P(status, pos) (status->stack_size_for_pos[pos] != NOT_COMPILED_STACK_SIZE)
// Linked list of struct rb_mjit_unit.
struct rb_mjit_unit_list {
// Linked list of struct rb_rjit_unit.
struct rb_rjit_unit_list {
struct ccan_list_head head;
int length; // the list length
};
enum rb_mjit_unit_type {
enum rb_rjit_unit_type {
// Single-ISEQ unit for unit_queue
RJIT_UNIT_ISEQ = 0,
// Multi-ISEQ unit for mjit_batch
// Multi-ISEQ unit for rjit_batch
RJIT_UNIT_BATCH = 1,
// All-ISEQ unit for mjit_compact
// All-ISEQ unit for rjit_compact
RJIT_UNIT_COMPACT = 2,
};
// The unit structure that holds metadata of ISeq for RJIT.
// TODO: Use different structs for ISEQ and BATCH/COMPACT
struct rb_mjit_unit {
struct rb_rjit_unit {
struct ccan_list_node unode;
// Unique order number of unit.
int id;
// Type of this unit
enum rb_mjit_unit_type type;
enum rb_rjit_unit_type type;
/* RJIT_UNIT_ISEQ */
// ISEQ for a non-batch unit
rb_iseq_t *iseq;
// Only used by unload_units. Flag to check this unit is currently on stack or not.
bool used_code_p;
// mjit_compile's optimization switches
struct rb_mjit_compile_info compile_info;
// rjit_compile's optimization switches
struct rb_rjit_compile_info compile_info;
// captured CC values, they should be marked with iseq.
const struct rb_callcache **cc_entries;
// ISEQ_BODY(iseq)->ci_size + ones of inlined iseqs
@ -57,7 +57,7 @@ struct rb_mjit_unit {
// Dlopen handle of the loaded object file.
void *handle;
// Units compacted by this batch
struct rb_mjit_unit_list units; // RJIT_UNIT_BATCH only
struct rb_rjit_unit_list units; // RJIT_UNIT_BATCH only
};
// Storage to keep data which is consistent in each conditional branch.
@ -77,7 +77,7 @@ struct inlined_call_context {
};
// Storage to keep compiler's status. This should have information
// which is global during one `mjit_compile` call. Ones conditional
// which is global during one `rjit_compile` call. Ones conditional
// in each branch should be stored in `compile_branch`.
struct compile_status {
bool success; // has true if compilation has had no issue
@ -91,8 +91,8 @@ struct compile_status {
const struct rb_iseq_constant_body *compiled_iseq;
int compiled_id; // Just a copy of compiled_iseq->jit_unit->id
// Mutated optimization levels
struct rb_mjit_compile_info *compile_info;
// If `inlined_iseqs[pos]` is not NULL, `mjit_compile_body` tries to inline ISeq there.
struct rb_rjit_compile_info *compile_info;
// If `inlined_iseqs[pos]` is not NULL, `rjit_compile_body` tries to inline ISeq there.
const struct rb_iseq_constant_body **inlined_iseqs;
struct inlined_call_context inline_context;
};
@ -105,12 +105,12 @@ struct compile_status {
// TODO: Make it configurable
#define RJIT_CODE_SIZE 64 * 1024 * 1024
extern uint8_t *rb_mjit_mem_block;
extern uint8_t *rb_rjit_mem_block;
#define RJIT_RUNTIME_COUNTERS(...) struct rb_mjit_runtime_counters { size_t __VA_ARGS__; };
#define RJIT_RUNTIME_COUNTERS(...) struct rb_rjit_runtime_counters { size_t __VA_ARGS__; };
RJIT_RUNTIME_COUNTERS(
vm_insns_count,
mjit_insns_count,
rjit_insns_count,
send_args_splat,
send_klass_megamorphic,
@ -208,6 +208,6 @@ RJIT_RUNTIME_COUNTERS(
compiled_block_count
)
#undef RJIT_RUNTIME_COUNTERS
extern struct rb_mjit_runtime_counters rb_mjit_counters;
extern struct rb_rjit_runtime_counters rb_rjit_counters;
#endif /* RJIT_C_H */

314
rjit_c.rb
Просмотреть файл

@ -1,34 +1,34 @@
# frozen_string_literal: true
# Part of this file is generated by tool/mjit/bindgen.rb.
# Run `make mjit-bindgen` to update code between "RJIT bindgen begin" and "RJIT bindgen end".
# Part of this file is generated by tool/rjit/bindgen.rb.
# Run `make rjit-bindgen` to update code between "RJIT bindgen begin" and "RJIT bindgen end".
module RubyVM::RJIT # :nodoc: all
# This `class << C` section is for calling C functions. For importing variables
# or macros as is, please consider using tool/mjit/bindgen.rb instead.
# or macros as is, please consider using tool/rjit/bindgen.rb instead.
class << C = Object.new
#========================================================================================
#
# New stuff
#
def mjit_mark_writable
def rjit_mark_writable
Primitive.cstmt! %{
extern bool rb_yjit_mark_writable(void *mem_block, uint32_t mem_size);
rb_yjit_mark_writable(rb_mjit_mem_block, RJIT_CODE_SIZE);
rb_yjit_mark_writable(rb_rjit_mem_block, RJIT_CODE_SIZE);
return Qnil;
}
end
def mjit_mark_executable
def rjit_mark_executable
Primitive.cstmt! %{
extern bool rb_yjit_mark_executable(void *mem_block, uint32_t mem_size);
rb_yjit_mark_executable(rb_mjit_mem_block, RJIT_CODE_SIZE);
rb_yjit_mark_executable(rb_rjit_mem_block, RJIT_CODE_SIZE);
return Qnil;
}
end
def mjit_insn_exits
def rjit_insn_exits
addr = Primitive.cstmt! %{
#if RJIT_STATS
return SIZET2NUM((size_t)mjit_insn_exits);
return SIZET2NUM((size_t)rjit_insn_exits);
#else
return SIZET2NUM(0);
#endif
@ -36,22 +36,22 @@ module RubyVM::RJIT # :nodoc: all
CType::Immediate.parse("size_t").new(addr)
end
def rb_mjit_branch_stub_hit
def rb_rjit_branch_stub_hit
Primitive.cstmt! %{
extern void *rb_mjit_branch_stub_hit(VALUE branch_stub, int sp_offset, int target0_p);
return SIZET2NUM((size_t)rb_mjit_branch_stub_hit);
extern void *rb_rjit_branch_stub_hit(VALUE branch_stub, int sp_offset, int target0_p);
return SIZET2NUM((size_t)rb_rjit_branch_stub_hit);
}
end
def rb_mjit_counters
def rb_rjit_counters
addr = Primitive.cstmt! %{
#if RJIT_STATS
return SIZET2NUM((size_t)&rb_mjit_counters);
return SIZET2NUM((size_t)&rb_rjit_counters);
#else
return SIZET2NUM(0);
#endif
}
rb_mjit_runtime_counters.new(addr)
rb_rjit_runtime_counters.new(addr)
end
# @param from [Integer] - From address
@ -160,14 +160,14 @@ module RubyVM::RJIT # :nodoc: all
Primitive.cexpr! 'SIZET2NUM((size_t)rb_fix_mod_fix)'
end
def mjit_for_each_iseq(&block)
Primitive.mjit_for_each_iseq(block)
def rjit_for_each_iseq(&block)
Primitive.rjit_for_each_iseq(block)
end
def rb_mjit_global_events
def rb_rjit_global_events
Primitive.cstmt! %{
extern rb_event_flag_t rb_mjit_global_events;
return SIZET2NUM((size_t)rb_mjit_global_events);
extern rb_event_flag_t rb_rjit_global_events;
return SIZET2NUM((size_t)rb_rjit_global_events);
}
end
@ -437,7 +437,7 @@ module RubyVM::RJIT # :nodoc: all
def builtin_compiler(buf, bf_ptr, index, stack_size, builtin_inline_p)
_bf_addr = bf_ptr.to_i
# Call "mjit_compile_invokebuiltin_for_#{func}" in mk_builtin_loader.rb
# Call "rjit_compile_invokebuiltin_for_#{func}" in mk_builtin_loader.rb
Primitive.cstmt! %{
RB_BUILTIN bf = (RB_BUILTIN)NUM2PTR(_bf_addr);
bf->compiler(buf, NIL_P(index) ? -1 : NUM2LONG(index), NUM2UINT(stack_size), RTEST(builtin_inline_p));
@ -520,23 +520,23 @@ module RubyVM::RJIT # :nodoc: all
}
end
def mjit_opts
addr = Primitive.cexpr! 'PTR2NUM((VALUE)&mjit_opts)'
mjit_options.new(addr)
def rjit_opts
addr = Primitive.cexpr! 'PTR2NUM((VALUE)&rjit_opts)'
rjit_options.new(addr)
end
def mjit_capture_cc_entries(compiled_body, captured_body)
def rjit_capture_cc_entries(compiled_body, captured_body)
_compiled_body_addr = compiled_body.to_i
_captured_body_addr = captured_body.to_i
Primitive.cstmt! %{
extern int mjit_capture_cc_entries(const struct rb_iseq_constant_body *compiled_iseq, const struct rb_iseq_constant_body *captured_iseq);
return INT2NUM(mjit_capture_cc_entries((struct rb_iseq_constant_body *)NUM2PTR(_compiled_body_addr), (struct rb_iseq_constant_body *)NUM2PTR(_captured_body_addr)));
extern int rjit_capture_cc_entries(const struct rb_iseq_constant_body *compiled_iseq, const struct rb_iseq_constant_body *captured_iseq);
return INT2NUM(rjit_capture_cc_entries((struct rb_iseq_constant_body *)NUM2PTR(_compiled_body_addr), (struct rb_iseq_constant_body *)NUM2PTR(_captured_body_addr)));
}
end
def mjit_cancel_all(reason)
def rjit_cancel_all(reason)
Primitive.cstmt! %{
mjit_cancel_all(RSTRING_PTR(reason));
rjit_cancel_all(RSTRING_PTR(reason));
return Qnil;
}
end
@ -1085,7 +1085,7 @@ module RubyVM::RJIT # :nodoc: all
cc_entries_index: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), cc_entries_index)")],
compiled_iseq: [CType::Pointer.new { self.rb_iseq_constant_body }, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), compiled_iseq)")],
compiled_id: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), compiled_id)")],
compile_info: [CType::Pointer.new { self.rb_mjit_compile_info }, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), compile_info)")],
compile_info: [CType::Pointer.new { self.rb_rjit_compile_info }, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), compile_info)")],
inlined_iseqs: [CType::Pointer.new { CType::Pointer.new { self.rb_iseq_constant_body } }, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), inlined_iseqs)")],
inline_context: [self.inlined_call_context, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), inline_context)")],
)
@ -1145,22 +1145,22 @@ module RubyVM::RJIT # :nodoc: all
@method_optimized_type ||= CType::Immediate.parse("int")
end
def C.mjit_options
@mjit_options ||= CType::Struct.new(
"mjit_options", Primitive.cexpr!("SIZEOF(struct mjit_options)"),
on: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), on)")],
save_temps: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), save_temps)")],
warnings: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), warnings)")],
debug: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), debug)")],
debug_flags: [CType::Pointer.new { CType::Immediate.parse("char") }, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), debug_flags)")],
wait: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), wait)")],
call_threshold: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), call_threshold)")],
stats: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), stats)")],
verbose: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), verbose)")],
max_cache_size: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), max_cache_size)")],
pause: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), pause)")],
custom: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), custom)")],
dump_disasm: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), dump_disasm)")],
def C.rjit_options
@rjit_options ||= CType::Struct.new(
"rjit_options", Primitive.cexpr!("SIZEOF(struct rjit_options)"),
on: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rjit_options *)NULL)), on)")],
save_temps: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rjit_options *)NULL)), save_temps)")],
warnings: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rjit_options *)NULL)), warnings)")],
debug: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rjit_options *)NULL)), debug)")],
debug_flags: [CType::Pointer.new { CType::Immediate.parse("char") }, Primitive.cexpr!("OFFSETOF((*((struct rjit_options *)NULL)), debug_flags)")],
wait: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rjit_options *)NULL)), wait)")],
call_threshold: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rjit_options *)NULL)), call_threshold)")],
stats: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rjit_options *)NULL)), stats)")],
verbose: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rjit_options *)NULL)), verbose)")],
max_cache_size: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rjit_options *)NULL)), max_cache_size)")],
pause: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rjit_options *)NULL)), pause)")],
custom: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rjit_options *)NULL)), custom)")],
dump_disasm: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rjit_options *)NULL)), dump_disasm)")],
)
end
@ -1392,7 +1392,7 @@ module RubyVM::RJIT # :nodoc: all
mandatory_only_iseq: [CType::Pointer.new { self.rb_iseq_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), mandatory_only_iseq)")],
jit_func: [CType::Immediate.parse("void *"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), jit_func)")],
total_calls: [CType::Immediate.parse("unsigned long"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), total_calls)")],
mjit_blocks: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), mjit_blocks)"), true],
rjit_blocks: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), rjit_blocks)"), true],
)
end
@ -1515,117 +1515,117 @@ module RubyVM::RJIT # :nodoc: all
@rb_method_type_t ||= CType::Immediate.parse("int")
end
def C.rb_mjit_compile_info
@rb_mjit_compile_info ||= CType::Struct.new(
"rb_mjit_compile_info", Primitive.cexpr!("SIZEOF(struct rb_mjit_compile_info)"),
disable_ivar_cache: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_compile_info *)NULL)), disable_ivar_cache)")],
disable_exivar_cache: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_compile_info *)NULL)), disable_exivar_cache)")],
disable_send_cache: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_compile_info *)NULL)), disable_send_cache)")],
disable_inlining: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_compile_info *)NULL)), disable_inlining)")],
disable_const_cache: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_compile_info *)NULL)), disable_const_cache)")],
def C.rb_rjit_compile_info
@rb_rjit_compile_info ||= CType::Struct.new(
"rb_rjit_compile_info", Primitive.cexpr!("SIZEOF(struct rb_rjit_compile_info)"),
disable_ivar_cache: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_compile_info *)NULL)), disable_ivar_cache)")],
disable_exivar_cache: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_compile_info *)NULL)), disable_exivar_cache)")],
disable_send_cache: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_compile_info *)NULL)), disable_send_cache)")],
disable_inlining: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_compile_info *)NULL)), disable_inlining)")],
disable_const_cache: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_compile_info *)NULL)), disable_const_cache)")],
)
end
def C.rb_mjit_runtime_counters
@rb_mjit_runtime_counters ||= CType::Struct.new(
"rb_mjit_runtime_counters", Primitive.cexpr!("SIZEOF(struct rb_mjit_runtime_counters)"),
vm_insns_count: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), vm_insns_count)")],
mjit_insns_count: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), mjit_insns_count)")],
send_args_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_args_splat)")],
send_klass_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_klass_megamorphic)")],
send_kw_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_kw_splat)")],
send_kwarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_kwarg)")],
send_missing_cme: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_missing_cme)")],
send_private: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_private)")],
send_protected_check_failed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_protected_check_failed)")],
send_tailcall: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_tailcall)")],
send_notimplemented: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_notimplemented)")],
send_cfunc: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_cfunc)")],
send_attrset: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_attrset)")],
send_missing: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_missing)")],
send_bmethod: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_bmethod)")],
send_alias: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_alias)")],
send_undef: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_undef)")],
send_zsuper: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_zsuper)")],
send_refined: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_refined)")],
send_unknown_type: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_unknown_type)")],
send_stackoverflow: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_stackoverflow)")],
send_arity: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_arity)")],
send_c_tracing: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_c_tracing)")],
send_blockarg_not_nil_or_proxy: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_blockarg_not_nil_or_proxy)")],
send_blockiseq: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_blockiseq)")],
send_block_handler: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_block_handler)")],
send_block_setup: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_block_setup)")],
send_block_not_nil: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_block_not_nil)")],
send_block_not_proxy: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_block_not_proxy)")],
send_iseq_kwparam: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_iseq_kwparam)")],
send_iseq_kw_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_iseq_kw_splat)")],
send_cfunc_variadic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_cfunc_variadic)")],
send_cfunc_too_many_args: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_cfunc_too_many_args)")],
send_cfunc_ruby_array_varg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_cfunc_ruby_array_varg)")],
send_ivar: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar)")],
send_ivar_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar_splat)")],
send_ivar_opt_send: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar_opt_send)")],
send_ivar_blockarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar_blockarg)")],
send_optimized_send_no_args: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized_send_no_args)")],
send_optimized_send_not_sym_or_str: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized_send_not_sym_or_str)")],
send_optimized_send_mid_class_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized_send_mid_class_changed)")],
send_optimized_send_mid_id_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized_send_mid_id_changed)")],
send_optimized_send_null_mid: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized_send_null_mid)")],
send_optimized_send_send: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized_send_send)")],
send_optimized_call_block: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized_call_block)")],
send_optimized_call_kwarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized_call_kwarg)")],
send_optimized_call_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized_call_splat)")],
send_optimized_struct_aref_error: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized_struct_aref_error)")],
send_optimized_blockarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized_blockarg)")],
send_optimized_block_call: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized_block_call)")],
send_optimized_struct_aset: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized_struct_aset)")],
send_optimized_unknown_type: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized_unknown_type)")],
send_bmethod_not_iseq: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_bmethod_not_iseq)")],
send_bmethod_blockarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_bmethod_blockarg)")],
invokesuper_me_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), invokesuper_me_changed)")],
invokesuper_same_me: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), invokesuper_same_me)")],
getivar_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getivar_megamorphic)")],
getivar_not_heap: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getivar_not_heap)")],
getivar_special_const: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getivar_special_const)")],
getivar_too_complex: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getivar_too_complex)")],
optaref_arg_not_fixnum: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), optaref_arg_not_fixnum)")],
optaref_argc_not_one: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), optaref_argc_not_one)")],
optaref_recv_not_array: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), optaref_recv_not_array)")],
optaref_recv_not_hash: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), optaref_recv_not_hash)")],
optaref_send: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), optaref_send)")],
optgetconst_not_cached: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), optgetconst_not_cached)")],
optgetconst_cref: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), optgetconst_cref)")],
optgetconst_cache_miss: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), optgetconst_cache_miss)")],
setivar_frozen: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), setivar_frozen)")],
setivar_not_heap: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), setivar_not_heap)")],
setivar_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), setivar_megamorphic)")],
setivar_too_complex: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), setivar_too_complex)")],
expandarray_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), expandarray_splat)")],
expandarray_postarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), expandarray_postarg)")],
expandarray_not_array: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), expandarray_not_array)")],
expandarray_rhs_too_small: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), expandarray_rhs_too_small)")],
getblockpp_block_param_modified: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getblockpp_block_param_modified)")],
getblockpp_block_handler_none: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getblockpp_block_handler_none)")],
getblockpp_not_gc_guarded: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getblockpp_not_gc_guarded)")],
getblockpp_not_iseq_block: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getblockpp_not_iseq_block)")],
compiled_block_count: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), compiled_block_count)")],
def C.rb_rjit_runtime_counters
@rb_rjit_runtime_counters ||= CType::Struct.new(
"rb_rjit_runtime_counters", Primitive.cexpr!("SIZEOF(struct rb_rjit_runtime_counters)"),
vm_insns_count: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), vm_insns_count)")],
rjit_insns_count: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), rjit_insns_count)")],
send_args_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_args_splat)")],
send_klass_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_klass_megamorphic)")],
send_kw_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_kw_splat)")],
send_kwarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_kwarg)")],
send_missing_cme: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_missing_cme)")],
send_private: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_private)")],
send_protected_check_failed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_protected_check_failed)")],
send_tailcall: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_tailcall)")],
send_notimplemented: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_notimplemented)")],
send_cfunc: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_cfunc)")],
send_attrset: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_attrset)")],
send_missing: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_missing)")],
send_bmethod: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_bmethod)")],
send_alias: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_alias)")],
send_undef: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_undef)")],
send_zsuper: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_zsuper)")],
send_refined: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_refined)")],
send_unknown_type: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_unknown_type)")],
send_stackoverflow: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_stackoverflow)")],
send_arity: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_arity)")],
send_c_tracing: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_c_tracing)")],
send_blockarg_not_nil_or_proxy: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_blockarg_not_nil_or_proxy)")],
send_blockiseq: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_blockiseq)")],
send_block_handler: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_block_handler)")],
send_block_setup: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_block_setup)")],
send_block_not_nil: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_block_not_nil)")],
send_block_not_proxy: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_block_not_proxy)")],
send_iseq_kwparam: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_kwparam)")],
send_iseq_kw_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_kw_splat)")],
send_cfunc_variadic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_cfunc_variadic)")],
send_cfunc_too_many_args: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_cfunc_too_many_args)")],
send_cfunc_ruby_array_varg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_cfunc_ruby_array_varg)")],
send_ivar: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_ivar)")],
send_ivar_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_ivar_splat)")],
send_ivar_opt_send: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_ivar_opt_send)")],
send_ivar_blockarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_ivar_blockarg)")],
send_optimized_send_no_args: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_send_no_args)")],
send_optimized_send_not_sym_or_str: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_send_not_sym_or_str)")],
send_optimized_send_mid_class_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_send_mid_class_changed)")],
send_optimized_send_mid_id_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_send_mid_id_changed)")],
send_optimized_send_null_mid: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_send_null_mid)")],
send_optimized_send_send: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_send_send)")],
send_optimized_call_block: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_call_block)")],
send_optimized_call_kwarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_call_kwarg)")],
send_optimized_call_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_call_splat)")],
send_optimized_struct_aref_error: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_struct_aref_error)")],
send_optimized_blockarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_blockarg)")],
send_optimized_block_call: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_block_call)")],
send_optimized_struct_aset: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_struct_aset)")],
send_optimized_unknown_type: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_unknown_type)")],
send_bmethod_not_iseq: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_bmethod_not_iseq)")],
send_bmethod_blockarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_bmethod_blockarg)")],
invokesuper_me_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokesuper_me_changed)")],
invokesuper_same_me: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokesuper_same_me)")],
getivar_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_megamorphic)")],
getivar_not_heap: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_not_heap)")],
getivar_special_const: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_special_const)")],
getivar_too_complex: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_too_complex)")],
optaref_arg_not_fixnum: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optaref_arg_not_fixnum)")],
optaref_argc_not_one: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optaref_argc_not_one)")],
optaref_recv_not_array: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optaref_recv_not_array)")],
optaref_recv_not_hash: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optaref_recv_not_hash)")],
optaref_send: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optaref_send)")],
optgetconst_not_cached: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optgetconst_not_cached)")],
optgetconst_cref: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optgetconst_cref)")],
optgetconst_cache_miss: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optgetconst_cache_miss)")],
setivar_frozen: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), setivar_frozen)")],
setivar_not_heap: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), setivar_not_heap)")],
setivar_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), setivar_megamorphic)")],
setivar_too_complex: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), setivar_too_complex)")],
expandarray_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), expandarray_splat)")],
expandarray_postarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), expandarray_postarg)")],
expandarray_not_array: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), expandarray_not_array)")],
expandarray_rhs_too_small: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), expandarray_rhs_too_small)")],
getblockpp_block_param_modified: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getblockpp_block_param_modified)")],
getblockpp_block_handler_none: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getblockpp_block_handler_none)")],
getblockpp_not_gc_guarded: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getblockpp_not_gc_guarded)")],
getblockpp_not_iseq_block: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getblockpp_not_iseq_block)")],
compiled_block_count: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), compiled_block_count)")],
)
end
def C.rb_mjit_unit
@rb_mjit_unit ||= CType::Struct.new(
"rb_mjit_unit", Primitive.cexpr!("SIZEOF(struct rb_mjit_unit)"),
unode: [self.ccan_list_node, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), unode)")],
id: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), id)")],
type: [self.rb_mjit_unit_type, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), type)")],
iseq: [CType::Pointer.new { self.rb_iseq_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), iseq)")],
used_code_p: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), used_code_p)")],
compile_info: [self.rb_mjit_compile_info, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), compile_info)")],
cc_entries: [CType::Pointer.new { CType::Pointer.new { self.rb_callcache } }, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), cc_entries)")],
cc_entries_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), cc_entries_size)")],
handle: [CType::Pointer.new { CType::Immediate.parse("void") }, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), handle)")],
units: [self.rb_mjit_unit_list, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), units)")],
def C.rb_rjit_unit
@rb_rjit_unit ||= CType::Struct.new(
"rb_rjit_unit", Primitive.cexpr!("SIZEOF(struct rb_rjit_unit)"),
unode: [self.ccan_list_node, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_unit *)NULL)), unode)")],
id: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_unit *)NULL)), id)")],
type: [self.rb_rjit_unit_type, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_unit *)NULL)), type)")],
iseq: [CType::Pointer.new { self.rb_iseq_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_unit *)NULL)), iseq)")],
used_code_p: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_unit *)NULL)), used_code_p)")],
compile_info: [self.rb_rjit_compile_info, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_unit *)NULL)), compile_info)")],
cc_entries: [CType::Pointer.new { CType::Pointer.new { self.rb_callcache } }, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_unit *)NULL)), cc_entries)")],
cc_entries_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_unit *)NULL)), cc_entries_size)")],
handle: [CType::Pointer.new { CType::Immediate.parse("void") }, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_unit *)NULL)), handle)")],
units: [self.rb_rjit_unit_list, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_unit *)NULL)), units)")],
)
end
@ -1820,12 +1820,12 @@ module RubyVM::RJIT # :nodoc: all
CType::Stub.new(:ccan_list_node)
end
def C.rb_mjit_unit_type
CType::Stub.new(:rb_mjit_unit_type)
def C.rb_rjit_unit_type
CType::Stub.new(:rb_rjit_unit_type)
end
def C.rb_mjit_unit_list
CType::Stub.new(:rb_mjit_unit_list)
def C.rb_rjit_unit_list
CType::Stub.new(:rb_rjit_unit_list)
end
def C.rb_ractor_t
@ -1873,4 +1873,4 @@ module RubyVM::RJIT # :nodoc: all
end
### RJIT bindgen end ###
end if Primitive.mjit_enabled_p
end if Primitive.rjit_enabled_p

50
ruby.c
Просмотреть файл

@ -105,7 +105,7 @@ void rb_warning_category_update(unsigned int mask, unsigned int bits);
SEP \
X(frozen_string_literal) \
SEP \
X(mjit) \
X(rjit) \
SEP \
X(yjit) \
/* END OF FEATURES */
@ -119,11 +119,11 @@ enum feature_flag_bits {
EACH_FEATURES(DEFINE_FEATURE, COMMA),
feature_debug_flag_first,
#if defined(RJIT_FORCE_ENABLE) || !USE_YJIT
DEFINE_FEATURE(jit) = feature_mjit,
DEFINE_FEATURE(jit) = feature_rjit,
#else
DEFINE_FEATURE(jit) = feature_yjit,
#endif
feature_jit_mask = FEATURE_BIT(mjit) | FEATURE_BIT(yjit),
feature_jit_mask = FEATURE_BIT(rjit) | FEATURE_BIT(yjit),
feature_debug_flag_begin = feature_debug_flag_first - 1,
EACH_DEBUG_FEATURES(DEFINE_DEBUG_FEATURE, COMMA),
@ -214,7 +214,7 @@ cmdline_options_init(ruby_cmdline_options_t *opt)
opt->intern.enc.index = -1;
opt->features.set = DEFAULT_FEATURES;
#ifdef RJIT_FORCE_ENABLE /* to use with: ./configure cppflags="-DRJIT_FORCE_ENABLE" */
opt->features.set |= FEATURE_BIT(mjit);
opt->features.set |= FEATURE_BIT(rjit);
#elif defined(YJIT_FORCE_ENABLE)
opt->features.set |= FEATURE_BIT(yjit);
#endif
@ -262,7 +262,7 @@ usage(const char *name, int help, int highlight, int columns)
#if USE_YJIT
# define PLATFORM_JIT_OPTION "--yjit"
#else
# define PLATFORM_JIT_OPTION "--mjit (experimental)"
# define PLATFORM_JIT_OPTION "--rjit (experimental)"
#endif
static const struct ruby_opt_message usage_msg[] = {
M("-0[octal]", "", "specify record separator (\\0, if no argument)"),
@ -287,7 +287,7 @@ usage(const char *name, int help, int highlight, int columns)
M("-x[directory]", "", "strip off text before #!ruby line and perhaps cd to directory"),
M("--jit", "", "enable JIT for the platform, same as " PLATFORM_JIT_OPTION),
#if USE_RJIT
M("--mjit", "", "enable C compiler-based JIT compiler (experimental)"),
M("--rjit", "", "enable C compiler-based JIT compiler (experimental)"),
#endif
#if USE_YJIT
M("--yjit", "", "enable in-process JIT compiler"),
@ -322,7 +322,7 @@ usage(const char *name, int help, int highlight, int columns)
M("rubyopt", "", "RUBYOPT environment variable (default: enabled)"),
M("frozen-string-literal", "", "freeze all string literals (default: disabled)"),
#if USE_RJIT
M("mjit", "", "C compiler-based JIT compiler (default: disabled)"),
M("rjit", "", "C compiler-based JIT compiler (default: disabled)"),
#endif
#if USE_YJIT
M("yjit", "", "in-process JIT compiler (default: disabled)"),
@ -333,7 +333,7 @@ usage(const char *name, int help, int highlight, int columns)
M("experimental", "", "experimental features"),
};
#if USE_RJIT
extern const struct ruby_opt_message mjit_option_messages[];
extern const struct ruby_opt_message rjit_option_messages[];
#endif
#if USE_YJIT
static const struct ruby_opt_message yjit_options[] = {
@ -372,8 +372,8 @@ usage(const char *name, int help, int highlight, int columns)
SHOW(warn_categories[i]);
#if USE_RJIT
printf("%s""RJIT options (experimental):%s\n", sb, se);
for (i = 0; mjit_option_messages[i].str; ++i)
SHOW(mjit_option_messages[i]);
for (i = 0; rjit_option_messages[i].str; ++i)
SHOW(rjit_option_messages[i]);
#endif
#if USE_YJIT
printf("%s""YJIT options:%s\n", sb, se);
@ -1492,11 +1492,11 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
FEATURE_SET(opt->features, FEATURE_BIT(jit));
#endif
}
else if (is_option_with_optarg("mjit", '-', true, false, false)) {
else if (is_option_with_optarg("rjit", '-', true, false, false)) {
#if USE_RJIT
extern void mjit_setup_options(const char *s, struct mjit_options *mjit_opt);
FEATURE_SET(opt->features, FEATURE_BIT(mjit));
mjit_setup_options(s, &opt->mjit);
extern void rjit_setup_options(const char *s, struct rjit_options *rjit_opt);
FEATURE_SET(opt->features, FEATURE_BIT(rjit));
rjit_setup_options(s, &opt->rjit);
#else
rb_warn("RJIT support is disabled.");
#endif
@ -1613,10 +1613,10 @@ ruby_opt_init(ruby_cmdline_options_t *opt)
#if USE_RJIT
// rb_call_builtin_inits depends on RubyVM::RJIT.enabled?
if (opt->mjit.on)
mjit_enabled = true;
if (opt->mjit.stats)
mjit_stats_enabled = true;
if (opt->rjit.on)
rjit_enabled = true;
if (opt->rjit.stats)
rjit_stats_enabled = true;
#endif
Init_ext(); /* load statically linked extensions before rubygems */
@ -1626,18 +1626,18 @@ ruby_opt_init(ruby_cmdline_options_t *opt)
// Initialize JITs after prelude because JITing prelude is typically not optimal.
#if USE_RJIT
// Also, mjit_init is safe only after rb_call_builtin_inits() defines RubyVM::RJIT::Compiler.
if (opt->mjit.on)
mjit_init(&opt->mjit);
// Also, rjit_init is safe only after rb_call_builtin_inits() defines RubyVM::RJIT::Compiler.
if (opt->rjit.on)
rjit_init(&opt->rjit);
#endif
#if USE_YJIT
if (opt->yjit)
rb_yjit_init();
#endif
// rb_threadptr_root_fiber_setup for the initial thread is called before rb_yjit_enabled_p()
// or mjit_enabled becomes true, meaning jit_cont_new is skipped for the initial root fiber.
// or rjit_enabled becomes true, meaning jit_cont_new is skipped for the initial root fiber.
// Therefore we need to call this again here to set the initial root fiber's jit_cont.
rb_jit_cont_init(); // must be after mjit_enabled = true and rb_yjit_init()
rb_jit_cont_init(); // must be after rjit_enabled = true and rb_yjit_init()
ruby_set_script_name(opt->script_name);
require_libraries(&opt->req_list);
@ -1940,8 +1940,8 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
}
#if USE_RJIT
if (FEATURE_SET_P(opt->features, mjit)) {
opt->mjit.on = true; // set opt->mjit.on for Init_ruby_description() and calling mjit_init()
if (FEATURE_SET_P(opt->features, rjit)) {
opt->rjit.on = true; // set opt->rjit.on for Init_ruby_description() and calling rjit_init()
}
#endif
#if USE_YJIT

Просмотреть файл

@ -8,7 +8,7 @@ ruby_version_is "3.0" do
before :all do
begin
leaked = Process.waitall
# Ruby-space should not see PIDs used by mjit
# Ruby-space should not see PIDs used by rjit
raise "subprocesses leaked before wait specs: #{leaked}" unless leaked.empty?
rescue NotImplementedError
end

Просмотреть файл

@ -11,7 +11,7 @@ describe "Process.wait2" do
$stderr.puts "Leaked process before wait2 specs! Waiting for it"
leaked = Process.waitall
$stderr.puts "leaked before wait2 specs: #{leaked}" unless leaked.empty?
# Ruby-space should not see PIDs used by mjit
# Ruby-space should not see PIDs used by rjit
leaked.should be_empty
rescue Errno::ECHILD # No child processes
rescue NotImplementedError

Просмотреть файл

@ -7,7 +7,7 @@ describe "Process.wait" do
before :all do
begin
leaked = Process.waitall
# Ruby-space should not see PIDs used by mjit
# Ruby-space should not see PIDs used by rjit
raise "subprocesses leaked before wait specs: #{leaked}" unless leaked.empty?
rescue NotImplementedError
end

Просмотреть файл

@ -967,7 +967,7 @@ EXCLUDE_PATTERNS += encdb.h
EXCLUDE_PATTERNS += extconf.h
EXCLUDE_PATTERNS += insns.def
EXCLUDE_PATTERNS += lib
EXCLUDE_PATTERNS += rb_mjit_header.h
EXCLUDE_PATTERNS += rb_rjit_header.h
EXCLUDE_PATTERNS += spec
EXCLUDE_PATTERNS += test
EXCLUDE_PATTERNS += tmp

Просмотреть файл

@ -23,7 +23,7 @@ File.read(File.join(arg['srcdir'], 'version.c')).
scan(/rb_define_global_const\("(RUBY_\w+)",[^;]*?\bMK(?:INT|(STR))\(([^()]*)\)/m) do |n, s, v|
version[n] = arg[v] || src.value(v) || (s ? v : 0)
end
arg['RUBY_DESCRIPTION_WITH_RJIT'] = src.value('description_with_mjit') || 'description_with_mjit'
arg['RUBY_DESCRIPTION_WITH_RJIT'] = src.value('description_with_rjit') || 'description_with_rjit'
arg['RUBY_DESCRIPTION_WITH_YJIT'] = src.value('description_with_yjit') || 'description_with_yjit'
%>baseruby="<%=arg['BASERUBY']%>"
_\

Просмотреть файл

@ -12,7 +12,7 @@ class TestBugReporter < Test::Unit::TestCase
omit if ENV['RUBY_ON_BUG']
description = RUBY_DESCRIPTION
description = description.sub(/\+RJIT /, '') unless JITSupport.mjit_force_enabled?
description = description.sub(/\+RJIT /, '') unless JITSupport.rjit_force_enabled?
expected_stderr = [
:*,
/\[BUG\]\sSegmentation\sfault.*\n/,

Просмотреть файл

@ -25,7 +25,7 @@ module JITSupport
]
module_function
# Run Ruby script with --mjit-wait (Synchronous JIT compilation).
# Run Ruby script with --rjit-wait (Synchronous JIT compilation).
# Returns [stdout, stderr]
def eval_with_jit(env = nil, script, **opts)
stdout, stderr = nil, nil
@ -40,13 +40,13 @@ module JITSupport
def eval_with_jit_without_retry(env = nil, script, verbose: 0, call_threshold: 5, save_temps: false, max_cache: 1000, wait: true, timeout: JIT_TIMEOUT)
args = [
'--disable-gems', "--mjit-verbose=#{verbose}",
"--mjit-call-threshold=#{call_threshold}", "--mjit-max-cache=#{max_cache}",
'--disable-gems', "--rjit-verbose=#{verbose}",
"--rjit-call-threshold=#{call_threshold}", "--rjit-max-cache=#{max_cache}",
]
args << '--disable-yjit'
args << '--mjit-wait' if wait
args << '--mjit-save-temps' if save_temps
args << '--mjit-debug' if defined?(@mjit_debug) && @mjit_debug
args << '--rjit-wait' if wait
args << '--rjit-save-temps' if save_temps
args << '--rjit-debug' if defined?(@rjit_debug) && @rjit_debug
args << '-e' << script
args.unshift(env ? base_env.merge!(env) : base_env)
EnvUtil.invoke_ruby(args,
@ -69,7 +69,7 @@ module JITSupport
@yjit_supported = ![nil, 'no'].include?(RbConfig::CONFIG['YJIT_SUPPORT'])
end
def remove_mjit_logs(stderr)
def remove_rjit_logs(stderr)
if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? # utility for -DFORCE_RJIT_ENABLE
stderr.gsub(/^RJIT warning: Skipped to compile unsupported instruction: \w+\n/m, '')
else
@ -87,7 +87,7 @@ module JITSupport
stderr.include?("error trying to exec 'cc1': execvp: No such file or directory")
end
def mjit_force_enabled?
def rjit_force_enabled?
"#{RbConfig::CONFIG['CFLAGS']} #{RbConfig::CONFIG['CPPFLAGS']}".match?(/(\A|\s)-D ?RJIT_FORCE_ENABLE\b/)
end
end

Просмотреть файл

@ -312,7 +312,7 @@ EOS
end
def test_read_body_block_mod
# http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/3019353
# http://ci.rvm.jp/results/trunk-rjit-wait@silicon-docker/3019353
if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
omit 'too unstable with --jit-wait, and extending read_timeout did not help it'
end

Просмотреть файл

@ -2347,8 +2347,8 @@ class TestIO < Test::Unit::TestCase
end
def test_autoclose_true_closed_by_finalizer
# http://ci.rvm.jp/results/trunk-mjit@silicon-docker/1465760
# http://ci.rvm.jp/results/trunk-mjit@silicon-docker/1469765
# http://ci.rvm.jp/results/trunk-rjit@silicon-docker/1465760
# http://ci.rvm.jp/results/trunk-rjit@silicon-docker/1469765
omit 'this randomly fails with RJIT' if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
feature2250 = '[ruby-core:26222]'

Просмотреть файл

@ -3172,7 +3172,7 @@ class TestModule < Test::Unit::TestCase
end
def test_redefinition_mismatch
omit "Investigating trunk-mjit failure on ci.rvm.jp" if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
omit "Investigating trunk-rjit failure on ci.rvm.jp" if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
m = Module.new
m.module_eval "A = 1", __FILE__, line = __LINE__
e = assert_raise_with_message(TypeError, /is not a module/) {

Просмотреть файл

@ -7,11 +7,11 @@ require 'tempfile'
require_relative '../lib/jit_support'
class TestRubyOptions < Test::Unit::TestCase
def self.mjit_enabled? = defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
def self.rjit_enabled? = defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
def self.yjit_enabled? = defined?(RubyVM::YJIT.enabled?) && RubyVM::YJIT.enabled?
NO_JIT_DESCRIPTION =
if mjit_enabled?
if rjit_enabled?
RUBY_DESCRIPTION.sub(/\+RJIT /, '')
elsif yjit_enabled?
RUBY_DESCRIPTION.sub(/\+YJIT( (dev|dev_nodebug|stats))? /, '')
@ -149,7 +149,7 @@ class TestRubyOptions < Test::Unit::TestCase
def test_verbose
assert_in_out_err([{'RUBY_YJIT_ENABLE' => nil}, "-vve", ""]) do |r, e|
assert_match(VERSION_PATTERN, r[0])
if self.class.mjit_enabled? && !JITSupport.mjit_force_enabled?
if self.class.rjit_enabled? && !JITSupport.rjit_force_enabled?
assert_equal(NO_JIT_DESCRIPTION, r[0])
elsif self.class.yjit_enabled? && !yjit_force_enabled? # checking -DYJIT_FORCE_ENABLE
assert_equal(NO_JIT_DESCRIPTION, r[0])
@ -217,7 +217,7 @@ class TestRubyOptions < Test::Unit::TestCase
assert_match(VERSION_PATTERN, r[0])
if ENV['RUBY_YJIT_ENABLE'] == '1'
assert_equal(NO_JIT_DESCRIPTION, r[0])
elsif self.class.mjit_enabled? || self.class.yjit_enabled? # checking -D(M|Y)JIT_FORCE_ENABLE
elsif self.class.rjit_enabled? || self.class.yjit_enabled? # checking -D(M|Y)JIT_FORCE_ENABLE
assert_equal(EnvUtil.invoke_ruby(['-e', 'print RUBY_DESCRIPTION'], '', true).first, r[0])
else
assert_equal(RUBY_DESCRIPTION, r[0])
@ -230,9 +230,9 @@ class TestRubyOptions < Test::Unit::TestCase
return if yjit_force_enabled?
[
%w(--version --mjit --disable=mjit),
%w(--version --enable=mjit --disable=mjit),
%w(--version --enable-mjit --disable-mjit),
%w(--version --rjit --disable=rjit),
%w(--version --enable=rjit --disable=rjit),
%w(--version --enable-rjit --disable-rjit),
*([
%w(--version --jit --disable=jit),
%w(--version --enable=jit --disable=jit),
@ -248,9 +248,9 @@ class TestRubyOptions < Test::Unit::TestCase
if JITSupport.supported?
[
%w(--version --mjit),
%w(--version --enable=mjit),
%w(--version --enable-mjit),
%w(--version --rjit),
%w(--version --enable=rjit),
%w(--version --enable-rjit),
*([
%w(--version --jit),
%w(--version --enable=jit),
@ -259,10 +259,10 @@ class TestRubyOptions < Test::Unit::TestCase
].each do |args|
assert_in_out_err([env] + args) do |r, e|
assert_match(VERSION_PATTERN_WITH_JIT, r[0])
if JITSupport.mjit_force_enabled?
if JITSupport.rjit_force_enabled?
assert_equal(RUBY_DESCRIPTION, r[0])
else
assert_equal(EnvUtil.invoke_ruby([env, '--mjit', '-e', 'print RUBY_DESCRIPTION'], '', true).first, r[0])
assert_equal(EnvUtil.invoke_ruby([env, '--rjit', '-e', 'print RUBY_DESCRIPTION'], '', true).first, r[0])
end
assert_equal([], e)
end
@ -742,7 +742,7 @@ class TestRubyOptions < Test::Unit::TestCase
-e:(?:1:)?\s\[BUG\]\sSegmentation\sfault.*\n
)x,
%r(
#{ Regexp.quote((TestRubyOptions.mjit_enabled? && !JITSupport.mjit_force_enabled?) ? NO_JIT_DESCRIPTION : RUBY_DESCRIPTION) }\n\n
#{ Regexp.quote((TestRubyOptions.rjit_enabled? && !JITSupport.rjit_force_enabled?) ? NO_JIT_DESCRIPTION : RUBY_DESCRIPTION) }\n\n
)x,
%r(
(?:--\s(?:.+\n)*\n)?

Просмотреть файл

@ -11,7 +11,7 @@ require_relative '../lib/jit_support'
return unless JITSupport.yjit_supported?
# Tests for YJIT with assertions on compilation and side exits
# insipired by the RJIT tests in test/ruby/test_mjit.rb
# insipired by the RJIT tests in test/ruby/test_rjit.rb
class TestYJIT < Test::Unit::TestCase
running_with_yjit = defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?

Просмотреть файл

@ -5,8 +5,8 @@ require "timeout"
class TestGemStreamUI < Gem::TestCase
# increase timeout with RJIT for --jit-wait testing
mjit_enabled = defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
SHORT_TIMEOUT = (RUBY_ENGINE == "ruby" && !mjit_enabled) ? 0.1 : 1.0
rjit_enabled = defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
SHORT_TIMEOUT = (RUBY_ENGINE == "ruby" && !rjit_enabled) ? 0.1 : 1.0
module IsTty
attr_accessor :tty

Просмотреть файл

@ -131,7 +131,7 @@ class TestOpen3 < Test::Unit::TestCase
STDERR.reopen(old)
assert_equal("zo", o.read)
if defined?(JITSupport)
assert_equal("ze", JITSupport.remove_mjit_logs(r.read))
assert_equal("ze", JITSupport.remove_rjit_logs(r.read))
else
assert_equal("ze", r.read)
end

Просмотреть файл

@ -89,7 +89,7 @@
#include "internal/time.h"
#include "internal/warnings.h"
#include "iseq.h"
#include "mjit.h"
#include "rjit.h"
#include "ruby/debug.h"
#include "ruby/io.h"
#include "ruby/thread.h"
@ -2282,8 +2282,8 @@ threadptr_get_interrupts(rb_thread_t *th)
#if USE_RJIT
// process.c
extern bool mjit_waitpid_finished;
extern int mjit_waitpid_status;
extern bool rjit_waitpid_finished;
extern int rjit_waitpid_status;
#endif
int
@ -2338,9 +2338,9 @@ rb_threadptr_execute_interrupts(rb_thread_t *th, int blocking_timing)
#if USE_RJIT
// Handle waitpid_signal for RJIT issued by ruby_sigchld_handler. This needs to be done
// outside ruby_sigchld_handler to avoid recursively relying on the SIGCHLD handler.
if (mjit_waitpid_finished && th == th->vm->ractor.main_thread) {
mjit_waitpid_finished = false;
mjit_notify_waitpid(WIFEXITED(mjit_waitpid_status) ? WEXITSTATUS(mjit_waitpid_status) : -1);
if (rjit_waitpid_finished && th == th->vm->ractor.main_thread) {
rjit_waitpid_finished = false;
rjit_notify_waitpid(WIFEXITED(rjit_waitpid_status) ? WEXITSTATUS(rjit_waitpid_status) : -1);
}
#endif
@ -4659,7 +4659,7 @@ rb_thread_atfork(void)
rb_reset_random_seed();
/* For child, starting RJIT worker thread in this place which is safer than immediately after `after_fork_ruby`. */
mjit_child_after_fork();
rjit_child_after_fork();
}
static void

Просмотреть файл

@ -12,7 +12,7 @@
#ifdef THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
#include "internal/gc.h"
#include "mjit.h"
#include "rjit.h"
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>

Просмотреть файл

@ -57,7 +57,7 @@ IO.foreach("|#{NM} #{no_llvm} #{ARGV.join(' ')}") do |line|
next unless /[A-TV-Z]/ =~ t
next unless n.sub!(/^#{SYMBOL_PREFIX}/o, "")
next if n.include?(".")
next if /\A(?:Init_|InitVM_|RUBY_|ruby_|rb_|[Oo]nig|dln_|mjit_|coroutine_)/ =~ n
next if /\A(?:Init_|InitVM_|RUBY_|ruby_|rb_|[Oo]nig|dln_|rjit_|coroutine_)/ =~ n
next if REPLACE.include?(n)
puts col.fail("leaked") if count.zero?
count += 1

Просмотреть файл

@ -92,8 +92,8 @@ module Test
module RJITFirst
def group(list)
# RJIT first
mjit, others = list.partition {|e| /test_mjit/ =~ e}
mjit + others
rjit, others = list.partition {|e| /test_rjit/ =~ e}
rjit + others
end
end

Просмотреть файл

@ -325,7 +325,7 @@ def mk_builtin_header file
. map {|i|", argv[#{i}]"} \
. join('')
f.puts %'static void'
f.puts %'mjit_compile_invokebuiltin_for_#{func}(VALUE buf, long index, unsigned stack_size, bool inlinable_p)'
f.puts %'rjit_compile_invokebuiltin_for_#{func}(VALUE buf, long index, unsigned stack_size, bool inlinable_p)'
f.puts %'{'
f.puts %' rb_str_catf(buf, " VALUE self = GET_SELF();\\n");'
f.puts %' rb_str_catf(buf, " typedef VALUE (*func)(rb_execution_context_t *, VALUE#{decl});\\n");'
@ -371,7 +371,7 @@ def mk_builtin_header file
f.puts " // table definition"
f.puts " static const struct rb_builtin_function #{table}[] = {"
bs.each.with_index{|(func, (argc, cfunc_name)), i|
f.puts " RB_BUILTIN_FUNCTION(#{i}, #{func}, #{cfunc_name}, #{argc}, mjit_compile_invokebuiltin_for_#{func}),"
f.puts " RB_BUILTIN_FUNCTION(#{i}, #{func}, #{cfunc_name}, #{argc}, rjit_compile_invokebuiltin_for_#{func}),"
}
f.puts " RB_BUILTIN_FUNCTION(-1, NULL, NULL, 0, 0),"
f.puts " };"

Просмотреть файл

@ -436,8 +436,8 @@ end
install?(:ext, :arch, :hdr, :'arch-hdr', :'hdr-arch') do
prepare "extension headers", archhdrdir
install_recursive("#{$extout}/include/#{CONFIG['arch']}", archhdrdir, :glob => "*.h", :mode => $data_mode)
install_recursive("#{$extout}/include/#{CONFIG['arch']}", archhdrdir, :glob => "rb_mjit_header-*.obj", :mode => $data_mode)
install_recursive("#{$extout}/include/#{CONFIG['arch']}", archhdrdir, :glob => "rb_mjit_header-*.pch", :mode => $data_mode)
install_recursive("#{$extout}/include/#{CONFIG['arch']}", archhdrdir, :glob => "rb_rjit_header-*.obj", :mode => $data_mode)
install_recursive("#{$extout}/include/#{CONFIG['arch']}", archhdrdir, :glob => "rb_rjit_header-*.pch", :mode => $data_mode)
end
install?(:ext, :comm, :'ext-comm') do
prepare "extension scripts", rubylibdir

Просмотреть файл

@ -326,7 +326,7 @@ class BindingGenerator
end
src_dir = File.expand_path('../..', __dir__)
src_path = File.join(src_dir, 'mjit_c.rb')
src_path = File.join(src_dir, 'rjit_c.rb')
build_dir = File.expand_path(build_dir)
cflags = [
src_dir,
@ -341,8 +341,8 @@ if Dir.exist?(clangd_cache)
system('rm', '-rf', clangd_cache, exception: true)
end
# Parse mjit_c.h and generate mjit_c.rb
nodes = HeaderParser.new(File.join(src_dir, 'mjit_c.h'), cflags: cflags).parse
# Parse rjit_c.h and generate rjit_c.rb
nodes = HeaderParser.new(File.join(src_dir, 'rjit_c.h'), cflags: cflags).parse
generator = BindingGenerator.new(
src_path: src_path,
uses: %w[
@ -478,7 +478,7 @@ generator = BindingGenerator.new(
iseq_inline_constant_cache_entry
iseq_inline_iv_cache_entry
iseq_inline_storage_entry
mjit_options
rjit_options
rb_builtin_function
rb_call_data
rb_callable_method_entry_struct
@ -498,9 +498,9 @@ generator = BindingGenerator.new(
rb_method_iseq_t
rb_method_type_t
rb_method_bmethod_t
rb_mjit_compile_info
rb_mjit_runtime_counters
rb_mjit_unit
rb_rjit_compile_info
rb_rjit_runtime_counters
rb_rjit_unit
rb_serial_t
rb_shape
rb_shape_t
@ -527,7 +527,7 @@ generator = BindingGenerator.new(
},
ruby_fields: {
rb_iseq_constant_body: %w[
mjit_blocks
rjit_blocks
],
rb_iseq_location_struct: %w[
base_label
@ -544,5 +544,5 @@ generator = BindingGenerator.new(
)
generator.generate(nodes)
# Write mjit_c.rb
# Write rjit_c.rb
File.write(src_path, generator.src)

Просмотреть файл

@ -13,7 +13,7 @@
#include "ruby/ruby.h"
#include "version.h"
#include "vm_core.h"
#include "mjit.h"
#include "rjit.h"
#include "yjit.h"
#include <stdio.h>
@ -71,7 +71,7 @@ const char ruby_release_date[] = RUBY_RELEASE_DATE;
const char ruby_platform[] = RUBY_PLATFORM;
const int ruby_patchlevel = RUBY_PATCHLEVEL;
const char ruby_description[] = RUBY_DESCRIPTION_WITH("");
static const char ruby_description_with_mjit[] = RUBY_DESCRIPTION_WITH(" +RJIT");
static const char ruby_description_with_rjit[] = RUBY_DESCRIPTION_WITH(" +RJIT");
static const char ruby_description_with_yjit[] = RUBY_DESCRIPTION_WITH(YJIT_DESCRIPTION);
const char ruby_copyright[] = "ruby - Copyright (C) "
RUBY_BIRTH_YEAR_STR "-" RUBY_RELEASE_YEAR_STR " "
@ -127,7 +127,7 @@ Init_version(void)
}
#if USE_RJIT
#define RJIT_OPTS_ON opt->mjit.on
#define RJIT_OPTS_ON opt->rjit.on
#else
#define RJIT_OPTS_ON 0
#endif
@ -144,8 +144,8 @@ Init_ruby_description(ruby_cmdline_options_t *opt)
VALUE description;
if (RJIT_OPTS_ON) {
rb_dynamic_description = ruby_description_with_mjit;
description = MKSTR(description_with_mjit);
rb_dynamic_description = ruby_description_with_rjit;
description = MKSTR(description_with_rjit);
}
else if (YJIT_OPTS_ON) {
rb_dynamic_description = ruby_description_with_yjit;

14
vm.c
Просмотреть файл

@ -29,7 +29,7 @@
#include "internal/sanitizers.h"
#include "internal/variable.h"
#include "iseq.h"
#include "mjit.h"
#include "rjit.h"
#include "yjit.h"
#include "ruby/st.h"
#include "ruby/vm.h"
@ -379,7 +379,7 @@ jit_exec(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();
if (yjit_enabled || mjit_call_p) {
if (yjit_enabled || rjit_call_p) {
body->total_calls++;
}
else {
@ -402,9 +402,9 @@ jit_exec(rb_execution_context_t *ec)
return Qundef;
}
}
else { // mjit_call_p
if (body->total_calls == mjit_opts.call_threshold) {
rb_mjit_compile(iseq);
else { // rjit_call_p
if (body->total_calls == rjit_opts.call_threshold) {
rb_rjit_compile(iseq);
}
if ((func = body->jit_func) == 0) {
return Qundef;
@ -1969,7 +1969,7 @@ rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me, VALUE klass)
int flag = vm_redefinition_check_flag(klass);
if (flag != 0) {
rb_yjit_bop_redefined(flag, (enum ruby_basic_operators)bop);
rb_mjit_bop_redefined(flag, (enum ruby_basic_operators)bop);
rb_rjit_bop_redefined(flag, (enum ruby_basic_operators)bop);
ruby_vm_redefined_flag[bop] |= flag;
}
}
@ -2816,7 +2816,7 @@ rb_vm_mark(void *ptr)
}
}
mjit_mark();
rjit_mark();
}
RUBY_MARK_LEAVE("vm");

Просмотреть файл

@ -346,7 +346,7 @@ pathobj_realpath(VALUE pathobj)
}
/* Forward declarations */
struct rb_mjit_unit;
struct rb_rjit_unit;
typedef uintptr_t iseq_bits_t;
@ -512,7 +512,7 @@ struct rb_iseq_constant_body {
#if USE_RJIT
// RJIT stores some data on each iseq.
VALUE mjit_blocks;
VALUE rjit_blocks;
#endif
#if USE_YJIT

Просмотреть файл

@ -5442,7 +5442,7 @@ vm_ic_update(const rb_iseq_t *iseq, IC ic, VALUE val, const VALUE *reg_ep, const
RUBY_ASSERT(pc >= ISEQ_BODY(iseq)->iseq_encoded);
unsigned pos = (unsigned)(pc - ISEQ_BODY(iseq)->iseq_encoded);
rb_yjit_constant_ic_update(iseq, ic, pos);
rb_mjit_constant_ic_update(iseq, ic, pos);
rb_rjit_constant_ic_update(iseq, ic, pos);
}
static VALUE

Просмотреть файл

@ -27,12 +27,12 @@ RUBY_EXTERN rb_serial_t ruby_vm_global_cvar_state;
#define COLLECT_USAGE_REGISTER(reg, s) vm_collect_usage_register((reg), (s))
#elif RJIT_STATS && YJIT_STATS
// Both flags could be enabled at the same time. You need to call both in that case.
#define COLLECT_USAGE_INSN(insn) rb_mjit_collect_vm_usage_insn(insn); rb_yjit_collect_vm_usage_insn(insn)
#define COLLECT_USAGE_INSN(insn) rb_rjit_collect_vm_usage_insn(insn); rb_yjit_collect_vm_usage_insn(insn)
#define COLLECT_USAGE_OPERAND(insn, n, op) /* none */
#define COLLECT_USAGE_REGISTER(reg, s) /* none */
#elif RJIT_STATS
// for --mjit-stats
#define COLLECT_USAGE_INSN(insn) rb_mjit_collect_vm_usage_insn(insn)
// for --rjit-stats
#define COLLECT_USAGE_INSN(insn) rb_rjit_collect_vm_usage_insn(insn)
#define COLLECT_USAGE_OPERAND(insn, n, op) /* none */
#define COLLECT_USAGE_REGISTER(reg, s) /* none */
#elif YJIT_STATS

Просмотреть файл

@ -4,7 +4,7 @@
#include "id_table.h"
#include "yjit.h"
#include "mjit.h"
#include "rjit.h"
#define METHOD_DEBUG 0
@ -124,7 +124,7 @@ vm_cme_invalidate(rb_callable_method_entry_t *cme)
RB_DEBUG_COUNTER_INC(cc_cme_invalidate);
rb_yjit_cme_invalidate(cme);
rb_mjit_cme_invalidate(cme);
rb_rjit_cme_invalidate(cme);
}
static int
@ -150,7 +150,7 @@ rb_clear_constant_cache_for_id(ID id)
}
rb_yjit_constant_state_changed(id);
rb_mjit_constant_state_changed(id);
rb_rjit_constant_state_changed(id);
}
static void
@ -190,7 +190,7 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data;
rb_yjit_cme_invalidate((rb_callable_method_entry_t *)ccs->cme);
rb_mjit_cme_invalidate((rb_callable_method_entry_t *)ccs->cme);
rb_rjit_cme_invalidate((rb_callable_method_entry_t *)ccs->cme);
if (NIL_P(ccs->cme->owner)) invalidate_negative_cache(mid);
rb_vm_ccs_free(ccs);
rb_id_table_delete(cc_tbl, mid);
@ -204,8 +204,8 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
if (rb_yjit_enabled_p() && rb_id_table_lookup(cm_tbl, mid, &cme)) {
rb_yjit_cme_invalidate((rb_callable_method_entry_t *)cme);
}
if (mjit_enabled && rb_id_table_lookup(cm_tbl, mid, &cme)) {
rb_mjit_cme_invalidate((rb_callable_method_entry_t *)cme);
if (rjit_enabled && rb_id_table_lookup(cm_tbl, mid, &cme)) {
rb_rjit_cme_invalidate((rb_callable_method_entry_t *)cme);
}
rb_id_table_delete(cm_tbl, mid);
RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_callable);

Просмотреть файл

@ -27,7 +27,7 @@
#include "internal/hash.h"
#include "internal/symbol.h"
#include "iseq.h"
#include "mjit.h"
#include "rjit.h"
#include "ruby/debug.h"
#include "vm_core.h"
#include "ruby/ractor.h"
@ -126,7 +126,7 @@ update_global_event_hook(rb_event_flag_t prev_events, rb_event_flag_t new_events
// Do this after event flags updates so other ractors see updated vm events
// when they wake up.
rb_yjit_tracing_invalidate_all();
rb_mjit_tracing_invalidate_all(new_iseq_events);
rb_rjit_tracing_invalidate_all(new_iseq_events);
}
}
@ -1264,7 +1264,7 @@ rb_tracepoint_enable_for_target(VALUE tpval, VALUE target, VALUE target_line)
}
rb_yjit_tracing_invalidate_all();
rb_mjit_tracing_invalidate_all(tp->events);
rb_rjit_tracing_invalidate_all(tp->events);
ruby_vm_event_local_num++;