summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common.mk8
-rw-r--r--insns.def1
-rw-r--r--template/Makefile.in2
-rw-r--r--tool/ruby_vm/models/bare_instructions.rb5
-rw-r--r--tool/ruby_vm/models/instructions.rb1
-rw-r--r--tool/ruby_vm/models/zjit_instructions.rb58
-rw-r--r--tool/ruby_vm/views/_insn_sp_pc_dependency.erb27
-rw-r--r--tool/ruby_vm/views/_zjit_helpers.erb14
-rw-r--r--tool/ruby_vm/views/_zjit_instruction.erb8
-rw-r--r--tool/ruby_vm/views/insns.inc.erb5
-rw-r--r--tool/ruby_vm/views/insns_info.inc.erb1
-rw-r--r--tool/ruby_vm/views/lib/ruby_vm/rjit/instruction.rb.erb14
-rw-r--r--tool/ruby_vm/views/vm.inc.erb4
-rw-r--r--vm.c18
-rw-r--r--yjit/bindgen/src/main.rs2
-rw-r--r--zjit.c43
-rw-r--r--zjit.h19
-rw-r--r--zjit/src/cruby_bindings.inc.rs226
-rw-r--r--zjit/src/hir.rs39
-rw-r--r--zjit/src/lib.rs1
-rw-r--r--zjit/src/options.rs2
-rw-r--r--zjit/src/profile.rs122
22 files changed, 498 insertions, 122 deletions
@@ -1194,10 +1194,12 @@ $(srcs_vpath)insns.inc: $(tooldir)/ruby_vm/views/insns.inc.erb $(inc_common_head
$(srcs_vpath)insns_info.inc: $(tooldir)/ruby_vm/views/insns_info.inc.erb $(inc_common_headers) \
$(tooldir)/ruby_vm/views/_insn_type_chars.erb $(tooldir)/ruby_vm/views/_insn_name_info.erb \
$(tooldir)/ruby_vm/views/_insn_len_info.erb $(tooldir)/ruby_vm/views/_insn_operand_info.erb \
- $(tooldir)/ruby_vm/views/_attributes.erb $(tooldir)/ruby_vm/views/_comptime_insn_stack_increase.erb
$(srcs_vpath)vmtc.inc: $(tooldir)/ruby_vm/views/vmtc.inc.erb $(inc_common_headers)
$(srcs_vpath)vm.inc: $(tooldir)/ruby_vm/views/vm.inc.erb $(inc_common_headers) \
- $(tooldir)/ruby_vm/views/_insn_entry.erb $(tooldir)/ruby_vm/views/_trace_instruction.erb
BUILTIN_RB_SRCS = \
$(srcdir)/ast.rb \
@@ -19568,6 +19570,7 @@ vm.$(OBJEXT): {$(VPATH)}vm_sync.h
vm.$(OBJEXT): {$(VPATH)}vmtc.inc
vm.$(OBJEXT): {$(VPATH)}yjit.h
vm.$(OBJEXT): {$(VPATH)}yjit_hook.rbinc
vm_backtrace.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
vm_backtrace.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
vm_backtrace.$(OBJEXT): $(CCAN_DIR)/list/list.h
@@ -21175,4 +21178,5 @@ zjit.$(OBJEXT): {$(VPATH)}vm_insnhelper.h
zjit.$(OBJEXT): {$(VPATH)}vm_opts.h
zjit.$(OBJEXT): {$(VPATH)}vm_sync.h
zjit.$(OBJEXT): {$(VPATH)}zjit.c
# AUTOGENERATED DEPENDENCIES END
@@ -1265,6 +1265,7 @@ opt_plus
(CALL_DATA cd)
(VALUE recv, VALUE obj)
(VALUE val)
{
val = vm_opt_plus(recv, obj);
@@ -640,6 +640,7 @@ $(INSNS): $(srcdir)/insns.def vm_opts.h \
$(tooldir)/ruby_vm/models/operands_unifications.rb \
$(tooldir)/ruby_vm/models/trace_instructions.rb \
$(tooldir)/ruby_vm/models/typemap.rb \
$(tooldir)/ruby_vm/scripts/converter.rb \
$(tooldir)/ruby_vm/scripts/insns2vm.rb \
$(tooldir)/ruby_vm/views/_attributes.erb \
@@ -655,6 +656,7 @@ $(INSNS): $(srcdir)/insns.def vm_opts.h \
$(tooldir)/ruby_vm/views/_notice.erb \
$(tooldir)/ruby_vm/views/_sp_inc_helpers.erb \
$(tooldir)/ruby_vm/views/_trace_instruction.erb \
$(tooldir)/ruby_vm/views/insns.inc.erb \
$(tooldir)/ruby_vm/views/insns_info.inc.erb \
$(tooldir)/ruby_vm/views/optinsn.inc.erb \
@@ -148,6 +148,10 @@ class RubyVM::BareInstructions
@variables.find { |_, var_info| var_info[:type] == 'CALL_DATA' }
end
private
def check_attribute_consistency
@@ -186,6 +190,7 @@ class RubyVM::BareInstructions
generate_attribute 'rb_snum_t', 'sp_inc', rets.size - pops.size
generate_attribute 'bool', 'handles_sp', default_definition_of_handles_sp
generate_attribute 'bool', 'leaf', default_definition_of_leaf
end
def default_definition_of_handles_sp
@@ -17,5 +17,6 @@ RubyVM::Instructions = RubyVM::BareInstructions.to_a + \
RubyVM::OperandsUnifications.to_a + \
RubyVM::InstructionsUnifications.to_a
require_relative 'trace_instructions'
RubyVM::Instructions.freeze
@@ -0,0 +1,58 @@
@@ -0,0 +1,27 @@
@@ -0,0 +1,14 @@
@@ -0,0 +1,8 @@
@@ -12,6 +12,9 @@
edit: __FILE__,
} -%>
/* BIN : Basic Instruction Name */
#define BIN(n) YARVINSN_##n
@@ -24,3 +27,5 @@ enum ruby_vminsn_type {
#define ASSERT_VM_INSTRUCTION_SIZE(array) \
STATIC_ASSERT(numberof_##array, numberof(array) == VM_INSTRUCTION_SIZE)
@@ -17,5 +17,6 @@
<%= render 'insn_operand_info' %>
<%= render 'leaf_helpers' %>
<%= render 'sp_inc_helpers' %>
<%= render 'attributes' %>
<%= render 'comptime_insn_stack_increase' %>
@@ -0,0 +1,14 @@
@@ -25,6 +25,10 @@
<%= render 'insn_entry', locals: { insn: insn } -%>
% end
%
% RubyVM::TraceInstructions.to_a.each do |insn|
<%= render 'trace_instruction', locals: { insn: insn } -%>
% end
@@ -44,6 +44,8 @@
#include "ractor_core.h"
#include "vm_sync.h"
#include "shape.h"
#include "builtin.h"
@@ -434,18 +436,26 @@ jit_compile(rb_execution_context_t *ec)
const rb_iseq_t *iseq = ec->cfp->iseq;
struct rb_iseq_constant_body *body = ISEQ_BODY(iseq);
- // Increment the ISEQ's call counter and trigger JIT compilation if not compiled
#if USE_ZJIT
- extern bool rb_zjit_enabled_p;
- extern uint64_t rb_zjit_call_threshold;
if (body->jit_entry == NULL && rb_zjit_enabled_p) {
body->jit_entry_calls++;
if (body->jit_entry_calls == rb_zjit_call_threshold) {
- extern void rb_zjit_compile_iseq(const rb_iseq_t *iseq, rb_execution_context_t *ec, bool jit_exception);
rb_zjit_compile_iseq(iseq, ec, false);
}
}
#elif USE_YJIT
if (body->jit_entry == NULL && rb_yjit_enabled_p) {
body->jit_entry_calls++;
if (rb_yjit_threshold_hit(iseq, body->jit_entry_calls)) {
@@ -318,7 +318,7 @@ fn main() {
// From yjit.c
.allowlist_function("rb_object_shape_count")
- .allowlist_function("rb_iseq_(get|set)_yjit_payload")
.allowlist_function("rb_iseq_pc_at_idx")
.allowlist_function("rb_iseq_opcode_at_pc")
.allowlist_function("rb_(yjit|zjit)_reserve_addr_space")
@@ -22,6 +22,7 @@
#include "iseq.h"
#include "ruby/debug.h"
#include "internal/cont.h"
// For mmapp(), sysconf()
#ifndef _WIN32
@@ -634,3 +635,45 @@ rb_RCLASS_ORIGIN(VALUE c)
{
return RCLASS_ORIGIN(c);
}
@@ -0,0 +1,19 @@
@@ -597,117 +597,119 @@ pub const YARVINSN_setlocal_WC_0: ruby_vminsn_type = 106;
pub const YARVINSN_setlocal_WC_1: ruby_vminsn_type = 107;
pub const YARVINSN_putobject_INT2FIX_0_: ruby_vminsn_type = 108;
pub const YARVINSN_putobject_INT2FIX_1_: ruby_vminsn_type = 109;
-pub const YARVINSN_trace_nop: ruby_vminsn_type = 110;
-pub const YARVINSN_trace_getlocal: ruby_vminsn_type = 111;
-pub const YARVINSN_trace_setlocal: ruby_vminsn_type = 112;
-pub const YARVINSN_trace_getblockparam: ruby_vminsn_type = 113;
-pub const YARVINSN_trace_setblockparam: ruby_vminsn_type = 114;
-pub const YARVINSN_trace_getblockparamproxy: ruby_vminsn_type = 115;
-pub const YARVINSN_trace_getspecial: ruby_vminsn_type = 116;
-pub const YARVINSN_trace_setspecial: ruby_vminsn_type = 117;
-pub const YARVINSN_trace_getinstancevariable: ruby_vminsn_type = 118;
-pub const YARVINSN_trace_setinstancevariable: ruby_vminsn_type = 119;
-pub const YARVINSN_trace_getclassvariable: ruby_vminsn_type = 120;
-pub const YARVINSN_trace_setclassvariable: ruby_vminsn_type = 121;
-pub const YARVINSN_trace_opt_getconstant_path: ruby_vminsn_type = 122;
-pub const YARVINSN_trace_getconstant: ruby_vminsn_type = 123;
-pub const YARVINSN_trace_setconstant: ruby_vminsn_type = 124;
-pub const YARVINSN_trace_getglobal: ruby_vminsn_type = 125;
-pub const YARVINSN_trace_setglobal: ruby_vminsn_type = 126;
-pub const YARVINSN_trace_putnil: ruby_vminsn_type = 127;
-pub const YARVINSN_trace_putself: ruby_vminsn_type = 128;
-pub const YARVINSN_trace_putobject: ruby_vminsn_type = 129;
-pub const YARVINSN_trace_putspecialobject: ruby_vminsn_type = 130;
-pub const YARVINSN_trace_putstring: ruby_vminsn_type = 131;
-pub const YARVINSN_trace_putchilledstring: ruby_vminsn_type = 132;
-pub const YARVINSN_trace_concatstrings: ruby_vminsn_type = 133;
-pub const YARVINSN_trace_anytostring: ruby_vminsn_type = 134;
-pub const YARVINSN_trace_toregexp: ruby_vminsn_type = 135;
-pub const YARVINSN_trace_intern: ruby_vminsn_type = 136;
-pub const YARVINSN_trace_newarray: ruby_vminsn_type = 137;
-pub const YARVINSN_trace_pushtoarraykwsplat: ruby_vminsn_type = 138;
-pub const YARVINSN_trace_duparray: ruby_vminsn_type = 139;
-pub const YARVINSN_trace_duphash: ruby_vminsn_type = 140;
-pub const YARVINSN_trace_expandarray: ruby_vminsn_type = 141;
-pub const YARVINSN_trace_concatarray: ruby_vminsn_type = 142;
-pub const YARVINSN_trace_concattoarray: ruby_vminsn_type = 143;
-pub const YARVINSN_trace_pushtoarray: ruby_vminsn_type = 144;
-pub const YARVINSN_trace_splatarray: ruby_vminsn_type = 145;
-pub const YARVINSN_trace_splatkw: ruby_vminsn_type = 146;
-pub const YARVINSN_trace_newhash: ruby_vminsn_type = 147;
-pub const YARVINSN_trace_newrange: ruby_vminsn_type = 148;
-pub const YARVINSN_trace_pop: ruby_vminsn_type = 149;
-pub const YARVINSN_trace_dup: ruby_vminsn_type = 150;
-pub const YARVINSN_trace_dupn: ruby_vminsn_type = 151;
-pub const YARVINSN_trace_swap: ruby_vminsn_type = 152;
-pub const YARVINSN_trace_opt_reverse: ruby_vminsn_type = 153;
-pub const YARVINSN_trace_topn: ruby_vminsn_type = 154;
-pub const YARVINSN_trace_setn: ruby_vminsn_type = 155;
-pub const YARVINSN_trace_adjuststack: ruby_vminsn_type = 156;
-pub const YARVINSN_trace_defined: ruby_vminsn_type = 157;
-pub const YARVINSN_trace_definedivar: ruby_vminsn_type = 158;
-pub const YARVINSN_trace_checkmatch: ruby_vminsn_type = 159;
-pub const YARVINSN_trace_checkkeyword: ruby_vminsn_type = 160;
-pub const YARVINSN_trace_checktype: ruby_vminsn_type = 161;
-pub const YARVINSN_trace_defineclass: ruby_vminsn_type = 162;
-pub const YARVINSN_trace_definemethod: ruby_vminsn_type = 163;
-pub const YARVINSN_trace_definesmethod: ruby_vminsn_type = 164;
-pub const YARVINSN_trace_send: ruby_vminsn_type = 165;
-pub const YARVINSN_trace_sendforward: ruby_vminsn_type = 166;
-pub const YARVINSN_trace_opt_send_without_block: ruby_vminsn_type = 167;
-pub const YARVINSN_trace_objtostring: ruby_vminsn_type = 168;
-pub const YARVINSN_trace_opt_ary_freeze: ruby_vminsn_type = 169;
-pub const YARVINSN_trace_opt_hash_freeze: ruby_vminsn_type = 170;
-pub const YARVINSN_trace_opt_str_freeze: ruby_vminsn_type = 171;
-pub const YARVINSN_trace_opt_nil_p: ruby_vminsn_type = 172;
-pub const YARVINSN_trace_opt_str_uminus: ruby_vminsn_type = 173;
-pub const YARVINSN_trace_opt_duparray_send: ruby_vminsn_type = 174;
-pub const YARVINSN_trace_opt_newarray_send: ruby_vminsn_type = 175;
-pub const YARVINSN_trace_invokesuper: ruby_vminsn_type = 176;
-pub const YARVINSN_trace_invokesuperforward: ruby_vminsn_type = 177;
-pub const YARVINSN_trace_invokeblock: ruby_vminsn_type = 178;
-pub const YARVINSN_trace_leave: ruby_vminsn_type = 179;
-pub const YARVINSN_trace_throw: ruby_vminsn_type = 180;
-pub const YARVINSN_trace_jump: ruby_vminsn_type = 181;
-pub const YARVINSN_trace_branchif: ruby_vminsn_type = 182;
-pub const YARVINSN_trace_branchunless: ruby_vminsn_type = 183;
-pub const YARVINSN_trace_branchnil: ruby_vminsn_type = 184;
-pub const YARVINSN_trace_once: ruby_vminsn_type = 185;
-pub const YARVINSN_trace_opt_case_dis: ruby_vminsn_type = 186;
-pub const YARVINSN_trace_opt_plus: ruby_vminsn_type = 187;
-pub const YARVINSN_trace_opt_minus: ruby_vminsn_type = 188;
-pub const YARVINSN_trace_opt_mult: ruby_vminsn_type = 189;
-pub const YARVINSN_trace_opt_div: ruby_vminsn_type = 190;
-pub const YARVINSN_trace_opt_mod: ruby_vminsn_type = 191;
-pub const YARVINSN_trace_opt_eq: ruby_vminsn_type = 192;
-pub const YARVINSN_trace_opt_neq: ruby_vminsn_type = 193;
-pub const YARVINSN_trace_opt_lt: ruby_vminsn_type = 194;
-pub const YARVINSN_trace_opt_le: ruby_vminsn_type = 195;
-pub const YARVINSN_trace_opt_gt: ruby_vminsn_type = 196;
-pub const YARVINSN_trace_opt_ge: ruby_vminsn_type = 197;
-pub const YARVINSN_trace_opt_ltlt: ruby_vminsn_type = 198;
-pub const YARVINSN_trace_opt_and: ruby_vminsn_type = 199;
-pub const YARVINSN_trace_opt_or: ruby_vminsn_type = 200;
-pub const YARVINSN_trace_opt_aref: ruby_vminsn_type = 201;
-pub const YARVINSN_trace_opt_aset: ruby_vminsn_type = 202;
-pub const YARVINSN_trace_opt_aset_with: ruby_vminsn_type = 203;
-pub const YARVINSN_trace_opt_aref_with: ruby_vminsn_type = 204;
-pub const YARVINSN_trace_opt_length: ruby_vminsn_type = 205;
-pub const YARVINSN_trace_opt_size: ruby_vminsn_type = 206;
-pub const YARVINSN_trace_opt_empty_p: ruby_vminsn_type = 207;
-pub const YARVINSN_trace_opt_succ: ruby_vminsn_type = 208;
-pub const YARVINSN_trace_opt_not: ruby_vminsn_type = 209;
-pub const YARVINSN_trace_opt_regexpmatch2: ruby_vminsn_type = 210;
-pub const YARVINSN_trace_invokebuiltin: ruby_vminsn_type = 211;
-pub const YARVINSN_trace_opt_invokebuiltin_delegate: ruby_vminsn_type = 212;
-pub const YARVINSN_trace_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 213;
-pub const YARVINSN_trace_getlocal_WC_0: ruby_vminsn_type = 214;
-pub const YARVINSN_trace_getlocal_WC_1: ruby_vminsn_type = 215;
-pub const YARVINSN_trace_setlocal_WC_0: ruby_vminsn_type = 216;
-pub const YARVINSN_trace_setlocal_WC_1: ruby_vminsn_type = 217;
-pub const YARVINSN_trace_putobject_INT2FIX_0_: ruby_vminsn_type = 218;
-pub const YARVINSN_trace_putobject_INT2FIX_1_: ruby_vminsn_type = 219;
-pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 220;
pub type ruby_vminsn_type = u32;
pub type rb_iseq_callback = ::std::option::Option<
unsafe extern "C" fn(arg1: *const rb_iseq_t, arg2: *mut ::std::os::raw::c_void),
@@ -996,4 +998,6 @@ unsafe extern "C" {
line: ::std::os::raw::c_int,
);
pub fn rb_RCLASS_ORIGIN(c: VALUE) -> VALUE;
}
@@ -4,7 +4,7 @@
use crate::{
cruby::*,
get_option,
- options::DumpHIR
};
use std::collections::{HashMap, HashSet};
@@ -77,6 +77,18 @@ pub struct CallInfo {
name: String,
}
#[derive(Debug, Clone)]
pub enum Insn {
PutSelf,
@@ -125,6 +137,17 @@ pub enum Insn {
// Control flow instructions
Return { val: InsnId },
}
#[derive(Default, Debug)]
@@ -515,6 +538,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
let mut visited = HashSet::new();
let iseq_size = unsafe { get_iseq_encoded_size(iseq) };
while let Some((incoming_state, block, mut insn_idx)) = queue.pop_front() {
if visited.contains(&block) { continue; }
visited.insert(block);
@@ -657,10 +681,19 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
state.setn(n, top);
}
- YARVINSN_opt_plus => {
let right = state.pop()?;
let left = state.pop()?;
- state.push(fun.push_insn(block, Insn::Send { self_val: left, call_info: CallInfo { name: "+".into() }, args: vec![right] }));
}
YARVINSN_opt_div => {
let right = state.pop()?;
@@ -13,6 +13,7 @@ mod backend;
#[cfg(feature = "disasm")]
mod disasm;
mod options;
use codegen::gen_function;
use options::{debug, get_option, Options};
@@ -5,7 +5,7 @@ use std::{ffi::CStr, os::raw::c_char};
// Threshold==1 means compile on first execution
#[unsafe(no_mangle)]
#[allow(non_upper_case_globals)]
-pub static mut rb_zjit_call_threshold: u64 = 1;
#[derive(Clone, Copy, Debug)]
pub struct Options {
@@ -0,0 +1,122 @@