s/mjit/rjit/

This commit is contained in:
Takashi Kokubun 2023-03-06 23:17:25 -08:00
parent 2e875549a9
commit 23ec248e48
Notes: git 2023-03-07 07:44:22 +00:00
63 changed files with 1070 additions and 1072 deletions

View File

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

View File

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

View File

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

8
.gitignore vendored
View File

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

View File

@ -14,7 +14,7 @@ ms = "a".."k"
o.send(meth) o.send(meth)
end end
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{ assert_normal_exit %q{
a = [] a = []

View File

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

944
common.mk

File diff suppressed because it is too large Load Diff

View File

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

6
cont.c
View File

@ -34,7 +34,7 @@ extern int madvise(caddr_t, size_t, int);
#include "internal/sanitizers.h" #include "internal/sanitizers.h"
#include "internal/warnings.h" #include "internal/warnings.h"
#include "ruby/fiber/scheduler.h" #include "ruby/fiber/scheduler.h"
#include "mjit.h" #include "rjit.h"
#include "yjit.h" #include "yjit.h"
#include "vm_core.h" #include "vm_core.h"
#include "vm_sync.h" #include "vm_sync.h"
@ -70,7 +70,7 @@ static VALUE rb_cFiberPool;
#define FIBER_POOL_ALLOCATION_FREE #define FIBER_POOL_ALLOCATION_FREE
#endif #endif
#define jit_cont_enabled (mjit_enabled || rb_yjit_enabled_p()) #define jit_cont_enabled (rjit_enabled || rb_yjit_enabled_p())
enum context_type { enum context_type {
CONTINUATION_CONTEXT = 0, CONTINUATION_CONTEXT = 0,
@ -2547,7 +2547,7 @@ rb_threadptr_root_fiber_setup(rb_thread_t *th)
fiber->blocking = 1; fiber->blocking = 1;
fiber_status_set(fiber, FIBER_RESUMED); /* skip CREATED */ fiber_status_set(fiber, FIBER_RESUMED); /* skip CREATED */
th->ec = &fiber->cont.saved_ec; 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 // 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() // 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(). // here for other Ractors, which are not initialized by rb_jit_cont_init().

View File

@ -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. 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`. macOS seems to have libclang by default. On Ubuntu, you can install it with `apt install libclang1`.
### Always run make install ### 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. 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. 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. which is useful for profiling benchmarks.
`--mjit-debug` alone, on the other hand, disables `-O3` and adds debug flags. `--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 `--mjit-debug=-ggdb3` but `--mjit-debug`. If you're debugging RJIT, what you need to use is not `--rjit-debug=-ggdb3` but `--rjit-debug`.

4
eval.c
View File

@ -32,7 +32,7 @@
#include "internal/variable.h" #include "internal/variable.h"
#include "ruby/fiber/scheduler.h" #include "ruby/fiber/scheduler.h"
#include "iseq.h" #include "iseq.h"
#include "mjit.h" #include "rjit.h"
#include "probes.h" #include "probes.h"
#include "probes_helper.h" #include "probes_helper.h"
#include "ruby/vm.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); rb_ec_finalize(ec);

2
gc.c
View File

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

View File

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

View File

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

8
iseq.c
View File

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

View File

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

View File

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

View File

@ -911,9 +911,9 @@ module RubyVM::RJIT
end end
def incr_counter(name) def incr_counter(name)
if C.mjit_opts.stats if C.rjit_opts.stats
comment("increment counter #{name}") 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 add([:rax], 1) # TODO: lock
end end
end end

View File

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

View File

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

View File

@ -81,17 +81,17 @@ module RubyVM::RJIT
# @param branch_stub [RubyVM::RJIT::BranchStub] # @param branch_stub [RubyVM::RJIT::BranchStub]
# @param target0_p [TrueClass,FalseClass] # @param target0_p [TrueClass,FalseClass]
def compile_branch_stub(ctx, asm, branch_stub, target0_p) 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 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)}") 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 end
asm.mov(:rdi, to_value(branch_stub)) asm.mov(:rdi, to_value(branch_stub))
asm.mov(:esi, ctx.sp_offset) asm.mov(:esi, ctx.sp_offset)
asm.mov(:edx, target0_p ? 1 : 0) 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) asm.jmp(:rax)
end end
@ -104,10 +104,10 @@ module RubyVM::RJIT
# @param pc [Integer] # @param pc [Integer]
# @param asm [RubyVM::RJIT::Assembler] # @param asm [RubyVM::RJIT::Assembler]
def incr_insn_exit(pc, asm) def incr_insn_exit(pc, asm)
if C.mjit_opts.stats if C.rjit_opts.stats
insn = Compiler.decode_insn(C.VALUE.new(pc).*) insn = Compiler.decode_insn(C.VALUE.new(pc).*)
asm.comment("increment insn exit: #{insn.name}") 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 asm.add([:rax], 1) # TODO: lock
end end
end end

View File

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

View File

@ -21,7 +21,7 @@ module RubyVM::RJIT
# @param asm [RubyVM::RJIT::Assembler] # @param asm [RubyVM::RJIT::Assembler]
# @param insn `RubyVM::RJIT::Instruction` # @param insn `RubyVM::RJIT::Instruction`
def compile(jit, ctx, asm, insn) def compile(jit, ctx, asm, insn)
asm.incr_counter(:mjit_insns_count) asm.incr_counter(:rjit_insns_count)
asm.comment("Insn: #{insn.name}") asm.comment("Insn: #{insn.name}")
# 72/101 # 72/101
@ -512,7 +512,7 @@ module RubyVM::RJIT
idlist = ic.segments idlist = ic.segments
# Make sure there is an exit for this block as the interpreter might want # 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. # 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') Invariants.ensure_block_entry_exit(jit, cause: 'opt_getconstant_path')
@ -3296,7 +3296,7 @@ module RubyVM::RJIT
end end
# EXEC_EVENT_HOOK: RUBY_EVENT_C_CALL and RUBY_EVENT_C_RETURN # 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) asm.incr_counter(:send_c_tracing)
return CantCompile return CantCompile
end end

View File

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

View File

@ -29,7 +29,7 @@ module RubyVM::RJIT
def peek_at_stack(depth_from_top) def peek_at_stack(depth_from_top)
raise 'not at current insn' unless at_current_insn? raise 'not at current insn' unless at_current_insn?
offset = -(1 + depth_from_top) 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).* value = (cfp.sp + offset).*
C.to_ruby(value) C.to_ruby(value)
end end

View File

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

View File

@ -109,7 +109,7 @@ int initgroups(const char *, rb_gid_t);
#include "internal/thread.h" #include "internal/thread.h"
#include "internal/variable.h" #include "internal/variable.h"
#include "internal/warnings.h" #include "internal/warnings.h"
#include "mjit.h" #include "rjit.h"
#include "ruby/io.h" #include "ruby/io.h"
#include "ruby/st.h" #include "ruby/st.h"
#include "ruby/thread.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); void rb_thread_sleep_interruptible(void);
#if USE_RJIT #if USE_RJIT
static struct waitpid_state mjit_waitpid_state; static struct waitpid_state rjit_waitpid_state;
// variables shared with thread.c // variables shared with thread.c
// TODO: implement the same thing with postponed_job and obviate these variables // TODO: implement the same thing with postponed_job and obviate these variables
bool mjit_waitpid_finished = false; bool rjit_waitpid_finished = false;
int mjit_waitpid_status = 0; int rjit_waitpid_status = 0;
#endif #endif
static int static int
@ -1096,9 +1096,9 @@ waitpid_signal(struct waitpid_state *w)
return TRUE; return TRUE;
} }
#if USE_RJIT #if USE_RJIT
else if (w == &mjit_waitpid_state && w->ret) { /* mjit_add_waiting_pid */ else if (w == &rjit_waitpid_state && w->ret) { /* rjit_add_waiting_pid */
mjit_waitpid_finished = true; rjit_waitpid_finished = true;
mjit_waitpid_status = w->status; rjit_waitpid_status = w->status;
return TRUE; return TRUE;
} }
#endif #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 * must be called with vm->waitpid_lock held, this is not interruptible
*/ */
void 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); waitpid_state_init(&rjit_waitpid_state, pid, 0);
mjit_waitpid_state.ec = 0; // switch the behavior of waitpid_signal rjit_waitpid_state.ec = 0; // switch the behavior of waitpid_signal
ccan_list_add(&vm->waiting_pids, &mjit_waitpid_state.wnode); ccan_list_add(&vm->waiting_pids, &rjit_waitpid_state.wnode);
} }
#endif #endif
@ -1250,7 +1250,7 @@ waitpid_wait(struct waitpid_state *w)
/* /*
* Lock here to prevent do_waitpid from stealing work from the * 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 * outside of GVL
*/ */
rb_native_mutex_lock(&vm->waitpid_lock); 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); execarg_obj = rb_execarg_new(argc, argv, TRUE, FALSE);
eargp = rb_execarg_get(execarg_obj); 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 */ before_exec(); /* stop timer thread before redirects */
rb_protect(rb_execarg_parent_start1, execarg_obj, &state); 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 #if USE_RJIT
// This is used to create RJIT's child Ruby process // This is used to create RJIT's child Ruby process
pid_t pid_t
rb_mjit_fork(void) rb_rjit_fork(void)
{ {
struct child_handler_disabler_state old; struct child_handler_disabler_state old;
rb_vm_t *vm = GET_VM(); rb_vm_t *vm = GET_VM();
@ -4200,7 +4200,7 @@ rb_mjit_fork(void)
rb_native_mutex_lock(&vm->waitpid_lock); rb_native_mutex_lock(&vm->waitpid_lock);
pid_t pid = rb_fork(); 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); rb_native_mutex_unlock(&vm->waitpid_lock);
after_fork_ruby(); after_fork_ruby();
@ -4297,7 +4297,7 @@ rb_fork_ruby2(struct rb_process_status *status)
while (1) { while (1) {
prefork(); 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); disable_child_handler_before_fork(&old);
before_fork_ruby(); before_fork_ruby();
pid = rb_fork(); pid = rb_fork();
@ -4309,7 +4309,7 @@ rb_fork_ruby2(struct rb_process_status *status)
after_fork_ruby(); after_fork_ruby();
disable_child_handler_fork_parent(&old); /* yes, bad name */ 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) { /* fork succeed */
if (pid == 0) rb_thread_atfork(); 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 * Prevent a race with RJIT where the compiler process where
* can hold an FD of ours in between vfork + execve * 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; eargp->waitpid_state = WAITPID_LOCK_ONLY;
} }
@ -7088,11 +7088,11 @@ rb_daemon(int nochdir, int noclose)
{ {
int err = 0; int err = 0;
#ifdef HAVE_DAEMON #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(); before_fork_ruby();
err = daemon(nochdir, noclose); err = daemon(nochdir, noclose);
after_fork_ruby(); after_fork_ruby();
rb_thread_atfork(); /* calls mjit_resume() */ rb_thread_atfork(); /* calls rjit_resume() */
#else #else
int n; int n;

View File

@ -18,7 +18,7 @@
#include "variable.h" #include "variable.h"
#include "transient_heap.h" #include "transient_heap.h"
#include "yjit.h" #include "yjit.h"
#include "mjit.h" #include "rjit.h"
VALUE rb_cRactor; VALUE rb_cRactor;
static VALUE rb_cRactorSelector; 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; r->debug = cr->debug;
rb_yjit_before_ractor_spawn(); rb_yjit_before_ractor_spawn();
rb_mjit_before_ractor_spawn(); rb_rjit_before_ractor_spawn();
rb_thread_create_ractor(r, args, block); rb_thread_create_ractor(r, args, block);
RB_GC_GUARD(rv); RB_GC_GUARD(rv);

261
rjit.c
View File

@ -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) 2023 Takashi Kokubun <k0kubun@ruby-lang.org>.
Copyright (C) 2017 Takashi Kokubun <k0kubun@ruby-lang.org>.
**********************************************************************/ **********************************************************************/
#include "ruby/internal/config.h" // defines USE_RJIT #include "ruby/internal/config.h" // defines USE_RJIT
// ISO C requires a translation unit to contain at least one declaration // ISO C requires a translation unit to contain at least one declaration
void rb_mjit(void) {} void rb_rjit(void) {}
#if USE_RJIT #if USE_RJIT
@ -33,8 +32,8 @@ void rb_mjit(void) {}
#include "vm_core.h" #include "vm_core.h"
#include "vm_callinfo.h" #include "vm_callinfo.h"
#include "mjit.h" #include "rjit.h"
#include "mjit_c.h" #include "rjit_c.h"
#include "ruby_assert.h" #include "ruby_assert.h"
#include "ruby/debug.h" #include "ruby/debug.h"
#include "ruby/thread.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 // 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 // need them as RJIT threads still can work when the most MRI data were
// freed. // freed.
struct mjit_options mjit_opts; struct rjit_options rjit_opts;
// true if RJIT is enabled. // true if RJIT is enabled.
bool mjit_enabled = false; bool rjit_enabled = false;
bool mjit_stats_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` // 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. // and `rjit_call_p == false`, any JIT-ed code execution is cancelled as soon as possible.
bool mjit_call_p = false; bool rjit_call_p = false;
// A flag to communicate that mjit_call_p should be disabled while it's temporarily false. // A flag to communicate that rjit_call_p should be disabled while it's temporarily false.
bool mjit_cancel_p = false; bool rjit_cancel_p = false;
// Print the arguments according to FORMAT to stderr only if RJIT // Print the arguments according to FORMAT to stderr only if RJIT
// verbose option value is more or equal to LEVEL. // verbose option value is more or equal to LEVEL.
PRINTF_ARGS(static void, 2, 3) PRINTF_ARGS(static void, 2, 3)
verbose(int level, const char *format, ...) verbose(int level, const char *format, ...)
{ {
if (mjit_opts.verbose >= level) { if (rjit_opts.verbose >= level) {
va_list args; va_list args;
size_t len = strlen(format); size_t len = strlen(format);
char *full_format = alloca(sizeof(char) * (len + 2)); char *full_format = alloca(sizeof(char) * (len + 2));
@ -95,33 +94,33 @@ verbose(int level, const char *format, ...)
} }
int 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 // TODO: remove this
return 0; return 0;
} }
void void
mjit_cancel_all(const char *reason) rjit_cancel_all(const char *reason)
{ {
if (!mjit_enabled) if (!rjit_enabled)
return; return;
mjit_call_p = false; rjit_call_p = false;
mjit_cancel_p = true; rjit_cancel_p = true;
if (mjit_opts.warnings || mjit_opts.verbose) { if (rjit_opts.warnings || rjit_opts.verbose) {
fprintf(stderr, "JIT cancel: Disabled JIT-ed code because %s\n", reason); fprintf(stderr, "JIT cancel: Disabled JIT-ed code because %s\n", reason);
} }
} }
void void
mjit_free_iseq(const rb_iseq_t *iseq) rjit_free_iseq(const rb_iseq_t *iseq)
{ {
// TODO: remove this // TODO: remove this
} }
void void
mjit_notify_waitpid(int exit_code) rjit_notify_waitpid(int exit_code)
{ {
// TODO: remove this function // TODO: remove this function
} }
@ -140,44 +139,44 @@ static VALUE rb_cRJITCfpPtr = 0;
static VALUE rb_mRJITHooks = 0; static VALUE rb_mRJITHooks = 0;
void 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 // TODO: implement
} }
struct rb_mjit_compile_info* struct rb_rjit_compile_info*
rb_mjit_iseq_compile_info(const struct rb_iseq_constant_body *body) rb_rjit_iseq_compile_info(const struct rb_iseq_constant_body *body)
{ {
// TODO: remove this // TODO: remove this
return NULL; return NULL;
} }
void void
rb_mjit_recompile_send(const rb_iseq_t *iseq) rb_rjit_recompile_send(const rb_iseq_t *iseq)
{ {
// TODO: remove this // TODO: remove this
} }
void void
rb_mjit_recompile_ivar(const rb_iseq_t *iseq) rb_rjit_recompile_ivar(const rb_iseq_t *iseq)
{ {
// TODO: remove this // TODO: remove this
} }
void void
rb_mjit_recompile_exivar(const rb_iseq_t *iseq) rb_rjit_recompile_exivar(const rb_iseq_t *iseq)
{ {
// TODO: remove this // TODO: remove this
} }
void void
rb_mjit_recompile_inlining(const rb_iseq_t *iseq) rb_rjit_recompile_inlining(const rb_iseq_t *iseq)
{ {
// TODO: remove this // TODO: remove this
} }
void void
rb_mjit_recompile_const(const rb_iseq_t *iseq) rb_rjit_recompile_const(const rb_iseq_t *iseq)
{ {
// TODO: remove this // TODO: remove this
} }
@ -188,50 +187,50 @@ rb_mjit_recompile_const(const rb_iseq_t *iseq)
#define DEFAULT_CALL_THRESHOLD 30 #define DEFAULT_CALL_THRESHOLD 30
#define opt_match_noarg(s, l, name) \ #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) \ #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 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); const size_t l = strlen(s);
if (l == 0) { if (l == 0) {
return; return;
} }
else if (opt_match_noarg(s, l, "warnings")) { else if (opt_match_noarg(s, l, "warnings")) {
mjit_opt->warnings = true; rjit_opt->warnings = true;
} }
else if (opt_match(s, l, "debug")) { else if (opt_match(s, l, "debug")) {
if (*s) if (*s)
mjit_opt->debug_flags = strdup(s + 1); rjit_opt->debug_flags = strdup(s + 1);
else else
mjit_opt->debug = true; rjit_opt->debug = true;
} }
else if (opt_match_noarg(s, l, "wait")) { 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")) { 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")) { 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")) { 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")) { 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")) { 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")) { 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")) { else if (opt_match_noarg(s, l, "dump-disasm")) {
mjit_opt->dump_disasm = true; rjit_opt->dump_disasm = true;
} }
else { else {
rb_raise(rb_eRuntimeError, 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) #define M(shortopt, longopt, desc) RUBY_OPT_MESSAGE(shortopt, longopt, desc)
const struct ruby_opt_message mjit_option_messages[] = { const struct ruby_opt_message rjit_option_messages[] = {
M("--mjit-warnings", "", "Enable printing JIT warnings"), M("--rjit-warnings", "", "Enable printing JIT warnings"),
M("--mjit-debug", "", "Enable JIT debugging (very slow), or add cflags if specified"), M("--rjit-debug", "", "Enable JIT debugging (very slow), or add cflags if specified"),
M("--mjit-wait", "", "Wait until JIT compilation finishes every time (for testing)"), M("--rjit-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("--rjit-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("--rjit-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("--rjit-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("--rjit-call-threshold=num", "", "Number of calls to trigger JIT (for testing, default: " STRINGIZE(DEFAULT_CALL_THRESHOLD) ")"),
M("--mjit-stats", "", "Enable collecting RJIT statistics"), M("--rjit-stats", "", "Enable collecting RJIT statistics"),
{0} {0}
}; };
#undef M #undef M
VALUE VALUE
mjit_pause(bool wait_p) rjit_pause(bool wait_p)
{ {
// TODO: remove this // TODO: remove this
return Qtrue; return Qtrue;
} }
VALUE VALUE
mjit_resume(void) rjit_resume(void)
{ {
// TODO: remove this // TODO: remove this
return Qnil; return Qnil;
} }
void void
mjit_child_after_fork(void) rjit_child_after_fork(void)
{ {
// TODO: remove this // TODO: remove this
} }
// Compile ISeq to C code in `f`. It returns true if it succeeds to compile. // Compile ISeq to C code in `f`. It returns true if it succeeds to compile.
bool 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 // TODO: implement
return false; return false;
@ -287,23 +286,23 @@ mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id)
// //
// JIT buffer // 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_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. // Basically rjit_opts.stats, but this becomes false during RJIT compilation.
static bool mjit_stats_p = false; static bool rjit_stats_p = false;
#if RJIT_STATS #if RJIT_STATS
struct rb_mjit_runtime_counters rb_mjit_counters = { 0 }; struct rb_rjit_runtime_counters rb_rjit_counters = { 0 };
void void
rb_mjit_collect_vm_usage_insn(int insn) rb_rjit_collect_vm_usage_insn(int insn)
{ {
if (!mjit_stats_p) return; if (!rjit_stats_p) return;
rb_mjit_counters.vm_insns_count++; rb_rjit_counters.vm_insns_count++;
} }
#endif // YJIT_STATS #endif // YJIT_STATS
@ -314,29 +313,29 @@ extern VALUE rb_gc_disable(void);
#define WITH_RJIT_ISOLATED(stmt) do { \ #define WITH_RJIT_ISOLATED(stmt) do { \
VALUE was_disabled = rb_gc_disable(); \ VALUE was_disabled = rb_gc_disable(); \
rb_hook_list_t *global_hooks = rb_ec_ractor_hooks(GET_EC()); \ 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; \ global_hooks->events = 0; \
bool original_call_p = mjit_call_p; \ bool original_call_p = rjit_call_p; \
mjit_stats_p = false; \ rjit_stats_p = false; \
mjit_call_p = false; \ rjit_call_p = false; \
stmt; \ stmt; \
mjit_call_p = (mjit_cancel_p ? false : original_call_p); \ rjit_call_p = (rjit_cancel_p ? false : original_call_p); \
mjit_stats_p = mjit_opts.stats; \ rjit_stats_p = rjit_opts.stats; \
global_hooks->events = rb_mjit_global_events; \ global_hooks->events = rb_rjit_global_events; \
if (!was_disabled) rb_gc_enable(); \ if (!was_disabled) rb_gc_enable(); \
} while (0); } while (0);
void 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; if (!rjit_call_p) return;
mjit_call_p = false; rjit_call_p = false;
} }
static void 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({ WITH_RJIT_ISOLATED({
rb_funcall(rb_mRJITHooks, rb_intern("on_cme_invalidate"), 1, SIZET2NUM((size_t)data)); 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); extern int rb_workqueue_register(unsigned flags, rb_postponed_job_func_t func, void *data);
void 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. // 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 void
rb_mjit_before_ractor_spawn(void) rb_rjit_before_ractor_spawn(void)
{ {
if (!mjit_call_p) return; if (!rjit_call_p) return;
mjit_call_p = false; rjit_call_p = false;
} }
static void 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_LOCK_ENTER();
rb_vm_barrier(); rb_vm_barrier();
@ -374,17 +373,17 @@ mjit_constant_state_changed(void *data)
} }
void 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". // 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 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_LOCK_ENTER();
rb_vm_barrier(); rb_vm_barrier();
@ -398,59 +397,59 @@ rb_mjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx
} }
void 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({ WITH_RJIT_ISOLATED({
rb_funcall(rb_mRJITHooks, rb_intern("on_tracing_invalidate_all"), 1, UINT2NUM(new_iseq_events)); rb_funcall(rb_mRJITHooks, rb_intern("on_tracing_invalidate_all"), 1, UINT2NUM(new_iseq_events));
}); });
} }
static void 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({ WITH_RJIT_ISOLATED({
rb_funcall(rb_mRJITHooks, rb_intern("on_update_references"), 0); rb_funcall(rb_mRJITHooks, rb_intern("on_update_references"), 0);
}); });
} }
void 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) { if (body->rjit_blocks) {
body->mjit_blocks = rb_gc_location(body->mjit_blocks); body->rjit_blocks = rb_gc_location(body->rjit_blocks);
} }
// Asynchronously hook the Ruby code to avoid allocation during GC.compact. // 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 // Using _one because it's too slow to invalidate all for each ISEQ. Thus
// not giving an ISEQ pointer. // 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 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. // Note: This wasn't enough for some reason.
// We actually rely on RubyVM::RJIT::GC_REFS to mark this. // We actually rely on RubyVM::RJIT::GC_REFS to mark this.
if (mjit_blocks) { if (rjit_blocks) {
rb_gc_mark_movable(mjit_blocks); rb_gc_mark_movable(rjit_blocks);
} }
} }
// TODO: Use this in more places // TODO: Use this in more places
VALUE 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)); return rb_funcall(rb_cRJITIseqPtr, rb_intern("new"), 1, SIZET2NUM((size_t)iseq));
} }
void void
rb_mjit_compile(const rb_iseq_t *iseq) rb_rjit_compile(const rb_iseq_t *iseq)
{ {
RB_VM_LOCK_ENTER(); RB_VM_LOCK_ENTER();
rb_vm_barrier(); rb_vm_barrier();
@ -465,7 +464,7 @@ rb_mjit_compile(const rb_iseq_t *iseq)
} }
void * 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; 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() // Called by rb_vm_mark()
void void
mjit_mark(void) rjit_mark(void)
{ {
if (!mjit_enabled) if (!rjit_enabled)
return; return;
RUBY_MARK_ENTER("mjit"); RUBY_MARK_ENTER("rjit");
// Pin object pointers used in this file // Pin object pointers used in this file
rb_gc_mark(rb_RJITCompiler); rb_gc_mark(rb_RJITCompiler);
@ -501,67 +500,67 @@ mjit_mark(void)
rb_gc_mark(rb_cRJITCfpPtr); rb_gc_mark(rb_cRJITCfpPtr);
rb_gc_mark(rb_mRJITHooks); rb_gc_mark(rb_mRJITHooks);
RUBY_MARK_LEAVE("mjit"); RUBY_MARK_LEAVE("rjit");
} }
void void
mjit_init(const struct mjit_options *opts) rjit_init(const struct rjit_options *opts)
{ {
VM_ASSERT(mjit_enabled); VM_ASSERT(rjit_enabled);
mjit_opts = *opts; rjit_opts = *opts;
extern uint8_t* rb_yjit_reserve_addr_space(uint32_t mem_size); 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. // RJIT doesn't support miniruby, but it might reach here by RJIT_FORCE_ENABLE.
rb_mRJIT = rb_const_get(rb_cRubyVM, rb_intern("RJIT")); rb_mRJIT = rb_const_get(rb_cRubyVM, rb_intern("RJIT"));
if (!rb_const_defined(rb_mRJIT, rb_intern("Compiler"))) { if (!rb_const_defined(rb_mRJIT, rb_intern("Compiler"))) {
verbose(1, "Disabling RJIT because RubyVM::RJIT::Compiler is not defined"); verbose(1, "Disabling RJIT because RubyVM::RJIT::Compiler is not defined");
mjit_enabled = false; rjit_enabled = false;
return; return;
} }
rb_mRJITC = rb_const_get(rb_mRJIT, rb_intern("C")); rb_mRJITC = rb_const_get(rb_mRJIT, rb_intern("C"));
VALUE rb_cRJITCompiler = rb_const_get(rb_mRJIT, rb_intern("Compiler")); VALUE rb_cRJITCompiler = rb_const_get(rb_mRJIT, rb_intern("Compiler"));
rb_RJITCompiler = rb_funcall(rb_cRJITCompiler, rb_intern("new"), 2, 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_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_cRJITCfpPtr = rb_funcall(rb_mRJITC, rb_intern("rb_control_frame_t"), 0);
rb_mRJITHooks = rb_const_get(rb_mRJIT, rb_intern("Hooks")); rb_mRJITHooks = rb_const_get(rb_mRJIT, rb_intern("Hooks"));
mjit_call_p = true; rjit_call_p = true;
mjit_stats_p = mjit_opts.stats; rjit_stats_p = rjit_opts.stats;
// Normalize options // Normalize options
if (mjit_opts.call_threshold == 0) if (rjit_opts.call_threshold == 0)
mjit_opts.call_threshold = DEFAULT_CALL_THRESHOLD; rjit_opts.call_threshold = DEFAULT_CALL_THRESHOLD;
#ifndef HAVE_LIBCAPSTONE #ifndef HAVE_LIBCAPSTONE
if (mjit_opts.dump_disasm) if (rjit_opts.dump_disasm)
verbose(1, "libcapstone has not been linked. Ignoring --mjit-dump-disasm."); verbose(1, "libcapstone has not been linked. Ignoring --rjit-dump-disasm.");
#endif #endif
} }
void void
mjit_finish(bool close_handle_p) rjit_finish(bool close_handle_p)
{ {
// TODO: implement // 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 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. // Disable anything that could impact stats. It ends up disabling JIT calls as well.
static VALUE 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; rjit_call_p = false;
mjit_stats_p = false; rjit_stats_p = false;
return Qnil; return Qnil;
} }
#include "mjit.rbinc" #include "rjit.rbinc"
#endif // USE_RJIT #endif // USE_RJIT

111
rjit.h
View File

@ -2,10 +2,9 @@
#define RUBY_RJIT_H 1 #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) 2023 Takashi Kokubun <k0kubun@ruby-lang.org>.
Copyright (C) 2017 Takashi Kokubun <k0kubun@ruby-lang.org>.
**********************************************************************/ **********************************************************************/
@ -24,7 +23,7 @@
// Special address values of a function generated from the // Special address values of a function generated from the
// corresponding iseq by RJIT: // corresponding iseq by RJIT:
enum rb_mjit_func_state { enum rb_rjit_func_state {
// ISEQ has not been compiled yet // ISEQ has not been compiled yet
RJIT_FUNC_NOT_COMPILED = 0, RJIT_FUNC_NOT_COMPILED = 0,
// ISEQ is already queued for the machine code generation but the // 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 // or the unit is unloaded
RJIT_FUNC_FAILED = 2, 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) #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. // 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 // Converted from "jit" feature flag to tell the enablement
// information to ruby_show_version(). // information to ruby_show_version().
bool on; bool on;
@ -74,7 +73,7 @@ struct mjit_options {
}; };
// State of optimization switches // State of optimization switches
struct rb_mjit_compile_info { struct rb_rjit_compile_info {
// Disable getinstancevariable/setinstancevariable optimizations based on inline cache (T_OBJECT) // Disable getinstancevariable/setinstancevariable optimizations based on inline cache (T_OBJECT)
bool disable_ivar_cache; bool disable_ivar_cache;
// Disable getinstancevariable/setinstancevariable optimizations based on inline cache (FL_EXIVAR) // 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 *); typedef VALUE (*jit_func_t)(rb_execution_context_t *, rb_control_frame_t *);
RUBY_SYMBOL_EXPORT_BEGIN RUBY_SYMBOL_EXPORT_BEGIN
RUBY_EXTERN struct mjit_options mjit_opts; RUBY_EXTERN struct rjit_options rjit_opts;
RUBY_EXTERN bool mjit_call_p; RUBY_EXTERN bool rjit_call_p;
extern void rb_mjit_compile(const rb_iseq_t *iseq); extern void rb_rjit_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 struct rb_rjit_compile_info* rb_rjit_iseq_compile_info(const struct rb_iseq_constant_body *body);
extern void rb_mjit_recompile_send(const rb_iseq_t *iseq); extern void rb_rjit_recompile_send(const rb_iseq_t *iseq);
extern void rb_mjit_recompile_ivar(const rb_iseq_t *iseq); extern void rb_rjit_recompile_ivar(const rb_iseq_t *iseq);
extern void rb_mjit_recompile_exivar(const rb_iseq_t *iseq); extern void rb_rjit_recompile_exivar(const rb_iseq_t *iseq);
extern void rb_mjit_recompile_inlining(const rb_iseq_t *iseq); extern void rb_rjit_recompile_inlining(const rb_iseq_t *iseq);
extern void rb_mjit_recompile_const(const rb_iseq_t *iseq); extern void rb_rjit_recompile_const(const rb_iseq_t *iseq);
RUBY_SYMBOL_EXPORT_END RUBY_SYMBOL_EXPORT_END
extern void mjit_cancel_all(const char *reason); extern void rjit_cancel_all(const char *reason);
extern bool mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id); extern bool rjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id);
extern void mjit_init(const struct mjit_options *opts); extern void rjit_init(const struct rjit_options *opts);
extern void mjit_free_iseq(const rb_iseq_t *iseq); extern void rjit_free_iseq(const rb_iseq_t *iseq);
extern void rb_mjit_iseq_update_references(struct rb_iseq_constant_body *const body); extern void rb_rjit_iseq_update_references(struct rb_iseq_constant_body *const body);
extern void mjit_mark(void); extern void rjit_mark(void);
extern void rb_mjit_iseq_mark(VALUE mjit_blocks); extern void rb_rjit_iseq_mark(VALUE rjit_blocks);
extern void mjit_notify_waitpid(int exit_code); 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_rjit_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_rjit_cme_invalidate(rb_callable_method_entry_t *cme);
extern void rb_mjit_before_ractor_spawn(void); extern void rb_rjit_before_ractor_spawn(void);
extern void rb_mjit_constant_state_changed(ID id); extern void rb_rjit_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_rjit_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_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_rjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop);
extern void rb_mjit_before_ractor_spawn(void); extern void rb_rjit_before_ractor_spawn(void);
extern void rb_mjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events); extern void rb_rjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events);
extern void rb_mjit_collect_vm_usage_insn(int insn); extern void rb_rjit_collect_vm_usage_insn(int insn);
extern bool mjit_enabled; extern bool rjit_enabled;
extern bool mjit_stats_enabled; extern bool rjit_stats_enabled;
VALUE mjit_pause(bool wait_p); VALUE rjit_pause(bool wait_p);
VALUE mjit_resume(void); VALUE rjit_resume(void);
void mjit_finish(bool close_handle_p); void rjit_finish(bool close_handle_p);
# else // USE_RJIT # else // USE_RJIT
static inline void mjit_cancel_all(const char *reason){} static inline void rjit_cancel_all(const char *reason){}
static inline void mjit_free_iseq(const rb_iseq_t *iseq){} static inline void rjit_free_iseq(const rb_iseq_t *iseq){}
static inline void mjit_mark(void){} static inline void rjit_mark(void){}
static inline VALUE jit_exec(rb_execution_context_t *ec) { return Qundef; /* unreachable */ } 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_rjit_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_rjit_cme_invalidate(rb_callable_method_entry_t *cme) {}
static inline void rb_mjit_before_ractor_spawn(void) {} static inline void rb_rjit_before_ractor_spawn(void) {}
static inline void rb_mjit_constant_state_changed(ID id) {} static inline void rb_rjit_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_rjit_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_tracing_invalidate_all(rb_event_flag_t new_iseq_events) {}
#define mjit_enabled false #define rjit_enabled false
#define mjit_stats_enabled false #define rjit_stats_enabled false
static inline VALUE mjit_pause(bool wait_p){ return Qnil; } // unreachable static inline VALUE rjit_pause(bool wait_p){ return Qnil; } // unreachable
static inline VALUE mjit_resume(void){ return Qnil; } // unreachable static inline VALUE rjit_resume(void){ return Qnil; } // unreachable
static inline void mjit_finish(bool close_handle_p){} 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 // USE_RJIT
#endif // RUBY_RJIT_H #endif // RUBY_RJIT_H

18
rjit.rb
View File

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

View File

@ -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>. Copyright (C) 2017 Takashi Kokubun <k0kubun@ruby-lang.org>.
@ -9,12 +9,12 @@
#include "ruby/internal/config.h" // defines USE_RJIT #include "ruby/internal/config.h" // defines USE_RJIT
// ISO C requires a translation unit to contain at least one declaration // 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 #if USE_RJIT
#include "mjit.h" #include "rjit.h"
#include "mjit_c.h" #include "rjit_c.h"
#include "internal.h" #include "internal.h"
#include "internal/compile.h" #include "internal/compile.h"
#include "internal/fixnum.h" #include "internal/fixnum.h"
@ -44,7 +44,7 @@ void rb_mjit_c(void) {}
#if RJIT_STATS #if RJIT_STATS
// Insn side exit counters // 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 #endif // YJIT_STATS
// macOS: brew install capstone // 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. // Same as `RubyVM::RJIT.enabled?`, but this is used before it's defined.
static VALUE 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 static int
@ -100,9 +100,9 @@ for_each_iseq_i(void *vstart, void *vend, size_t stride, void *data)
asan_unpoison_object(v, false); asan_unpoison_object(v, false);
if (rb_obj_is_iseq(v)) { 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_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); 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 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); rb_objspace_each_objects(for_each_iseq_i, (void *)block);
return Qnil; 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 bool rb_simple_iseq_p(const rb_iseq_t *iseq);
extern ID rb_get_symbol_id(VALUE name); extern ID rb_get_symbol_id(VALUE name);
#include "mjit_c.rbinc" #include "rjit_c.rbinc"
#endif // USE_RJIT #endif // USE_RJIT

View File

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

314
rjit_c.rb
View File

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

50
ruby.c
View File

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

View File

@ -8,7 +8,7 @@ ruby_version_is "3.0" do
before :all do before :all do
begin begin
leaked = Process.waitall 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? raise "subprocesses leaked before wait specs: #{leaked}" unless leaked.empty?
rescue NotImplementedError rescue NotImplementedError
end end

View File

@ -11,7 +11,7 @@ describe "Process.wait2" do
$stderr.puts "Leaked process before wait2 specs! Waiting for it" $stderr.puts "Leaked process before wait2 specs! Waiting for it"
leaked = Process.waitall leaked = Process.waitall
$stderr.puts "leaked before wait2 specs: #{leaked}" unless leaked.empty? $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 leaked.should be_empty
rescue Errno::ECHILD # No child processes rescue Errno::ECHILD # No child processes
rescue NotImplementedError rescue NotImplementedError

View File

@ -7,7 +7,7 @@ describe "Process.wait" do
before :all do before :all do
begin begin
leaked = Process.waitall 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? raise "subprocesses leaked before wait specs: #{leaked}" unless leaked.empty?
rescue NotImplementedError rescue NotImplementedError
end end

View File

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

View File

@ -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| 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) version[n] = arg[v] || src.value(v) || (s ? v : 0)
end 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' arg['RUBY_DESCRIPTION_WITH_YJIT'] = src.value('description_with_yjit') || 'description_with_yjit'
%>baseruby="<%=arg['BASERUBY']%>" %>baseruby="<%=arg['BASERUBY']%>"
_\ _\

View File

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

View File

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

View File

@ -312,7 +312,7 @@ EOS
end end
def test_read_body_block_mod 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? if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
omit 'too unstable with --jit-wait, and extending read_timeout did not help it' omit 'too unstable with --jit-wait, and extending read_timeout did not help it'
end end

View File

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

View File

@ -3172,7 +3172,7 @@ class TestModule < Test::Unit::TestCase
end end
def test_redefinition_mismatch 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.new
m.module_eval "A = 1", __FILE__, line = __LINE__ m.module_eval "A = 1", __FILE__, line = __LINE__
e = assert_raise_with_message(TypeError, /is not a module/) { e = assert_raise_with_message(TypeError, /is not a module/) {

View File

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

View File

@ -11,7 +11,7 @@ require_relative '../lib/jit_support'
return unless JITSupport.yjit_supported? return unless JITSupport.yjit_supported?
# Tests for YJIT with assertions on compilation and side exits # 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 class TestYJIT < Test::Unit::TestCase
running_with_yjit = defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled? running_with_yjit = defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?

View File

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

View File

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

View File

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

View File

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

View File

@ -57,7 +57,7 @@ IO.foreach("|#{NM} #{no_llvm} #{ARGV.join(' ')}") do |line|
next unless /[A-TV-Z]/ =~ t next unless /[A-TV-Z]/ =~ t
next unless n.sub!(/^#{SYMBOL_PREFIX}/o, "") next unless n.sub!(/^#{SYMBOL_PREFIX}/o, "")
next if n.include?(".") 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) next if REPLACE.include?(n)
puts col.fail("leaked") if count.zero? puts col.fail("leaked") if count.zero?
count += 1 count += 1

View File

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

View File

@ -325,7 +325,7 @@ def mk_builtin_header file
. map {|i|", argv[#{i}]"} \ . map {|i|", argv[#{i}]"} \
. join('') . join('')
f.puts %'static void' 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 %'{'
f.puts %' rb_str_catf(buf, " VALUE self = GET_SELF();\\n");' 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");' 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 " // table definition"
f.puts " static const struct rb_builtin_function #{table}[] = {" f.puts " static const struct rb_builtin_function #{table}[] = {"
bs.each.with_index{|(func, (argc, cfunc_name)), i| 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 " RB_BUILTIN_FUNCTION(-1, NULL, NULL, 0, 0),"
f.puts " };" f.puts " };"

View File

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

View File

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

View File

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

14
vm.c
View File

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

View File

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

View File

@ -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); RUBY_ASSERT(pc >= ISEQ_BODY(iseq)->iseq_encoded);
unsigned pos = (unsigned)(pc - ISEQ_BODY(iseq)->iseq_encoded); unsigned pos = (unsigned)(pc - ISEQ_BODY(iseq)->iseq_encoded);
rb_yjit_constant_ic_update(iseq, ic, pos); 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 static VALUE

View File

@ -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)) #define COLLECT_USAGE_REGISTER(reg, s) vm_collect_usage_register((reg), (s))
#elif RJIT_STATS && YJIT_STATS #elif RJIT_STATS && YJIT_STATS
// Both flags could be enabled at the same time. You need to call both in that case. // 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_OPERAND(insn, n, op) /* none */
#define COLLECT_USAGE_REGISTER(reg, s) /* none */ #define COLLECT_USAGE_REGISTER(reg, s) /* none */
#elif RJIT_STATS #elif RJIT_STATS
// for --mjit-stats // for --rjit-stats
#define COLLECT_USAGE_INSN(insn) rb_mjit_collect_vm_usage_insn(insn) #define COLLECT_USAGE_INSN(insn) rb_rjit_collect_vm_usage_insn(insn)
#define COLLECT_USAGE_OPERAND(insn, n, op) /* none */ #define COLLECT_USAGE_OPERAND(insn, n, op) /* none */
#define COLLECT_USAGE_REGISTER(reg, s) /* none */ #define COLLECT_USAGE_REGISTER(reg, s) /* none */
#elif YJIT_STATS #elif YJIT_STATS

View File

@ -4,7 +4,7 @@
#include "id_table.h" #include "id_table.h"
#include "yjit.h" #include "yjit.h"
#include "mjit.h" #include "rjit.h"
#define METHOD_DEBUG 0 #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_DEBUG_COUNTER_INC(cc_cme_invalidate);
rb_yjit_cme_invalidate(cme); rb_yjit_cme_invalidate(cme);
rb_mjit_cme_invalidate(cme); rb_rjit_cme_invalidate(cme);
} }
static int static int
@ -150,7 +150,7 @@ rb_clear_constant_cache_for_id(ID id)
} }
rb_yjit_constant_state_changed(id); rb_yjit_constant_state_changed(id);
rb_mjit_constant_state_changed(id); rb_rjit_constant_state_changed(id);
} }
static void 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)) { 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; 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_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); if (NIL_P(ccs->cme->owner)) invalidate_negative_cache(mid);
rb_vm_ccs_free(ccs); rb_vm_ccs_free(ccs);
rb_id_table_delete(cc_tbl, mid); 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)) { if (rb_yjit_enabled_p() && rb_id_table_lookup(cm_tbl, mid, &cme)) {
rb_yjit_cme_invalidate((rb_callable_method_entry_t *)cme); rb_yjit_cme_invalidate((rb_callable_method_entry_t *)cme);
} }
if (mjit_enabled && rb_id_table_lookup(cm_tbl, mid, &cme)) { if (rjit_enabled && rb_id_table_lookup(cm_tbl, mid, &cme)) {
rb_mjit_cme_invalidate((rb_callable_method_entry_t *)cme); rb_rjit_cme_invalidate((rb_callable_method_entry_t *)cme);
} }
rb_id_table_delete(cm_tbl, mid); rb_id_table_delete(cm_tbl, mid);
RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_callable); RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_callable);

View File

@ -27,7 +27,7 @@
#include "internal/hash.h" #include "internal/hash.h"
#include "internal/symbol.h" #include "internal/symbol.h"
#include "iseq.h" #include "iseq.h"
#include "mjit.h" #include "rjit.h"
#include "ruby/debug.h" #include "ruby/debug.h"
#include "vm_core.h" #include "vm_core.h"
#include "ruby/ractor.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 // Do this after event flags updates so other ractors see updated vm events
// when they wake up. // when they wake up.
rb_yjit_tracing_invalidate_all(); 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_yjit_tracing_invalidate_all();
rb_mjit_tracing_invalidate_all(tp->events); rb_rjit_tracing_invalidate_all(tp->events);
ruby_vm_event_local_num++; ruby_vm_event_local_num++;