From e97034c38d60fa34a99ab48dbb8f935d37e8160b Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 17 Mar 2025 16:59:19 -0700 Subject: [PATCH 1/5] Inline Class#new. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit inlines instructions for Class#new. To make this work, we added a new YARV instructions, `opt_new`. `opt_new` checks whether or not the `new` method is the default allocator method. If it is, it allocates the object, and pushes the instance on the stack. If not, the instruction jumps to the "slow path" method call instructions. Old instructions: ``` > ruby --dump=insns -e'Object.new' == disasm: #@-e:1 (1,0)-(1,10)> 0000 opt_getconstant_path ( 1)[Li] 0002 opt_send_without_block 0004 leave ``` New instructions: ``` > ./miniruby --dump=insns -e'Object.new' == disasm: #@-e:1 (1,0)-(1,10)> 0000 opt_getconstant_path ( 1)[Li] 0002 putnil 0003 swap 0004 opt_new , 11 0007 opt_send_without_block 0009 jump 14 0011 opt_send_without_block 0013 swap 0014 pop 0015 leave ``` This commit speeds up basic object allocation (`Foo.new`) by 60%, but classes that take keyword parameters see an even bigger benefit because no hash is allocated when instantiating the object (3x to 6x faster). Here is an example that uses `Hash.new(capacity: 0)`: ``` > hyperfine "ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end'" "./ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end'" Benchmark 1: ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end' Time (mean ± σ): 1.082 s ± 0.004 s [User: 1.074 s, System: 0.008 s] Range (min … max): 1.076 s … 1.088 s 10 runs Benchmark 2: ./ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end' Time (mean ± σ): 627.9 ms ± 3.5 ms [User: 622.7 ms, System: 4.8 ms] Range (min … max): 622.7 ms … 633.2 ms 10 runs Summary ./ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end' ran 1.72 ± 0.01 times faster than ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end' ``` This commit changes the backtrace for `initialize`: ``` aaron@tc ~/g/ruby (inline-new)> cat test.rb class Foo def initialize puts caller end end def hello Foo.new end hello aaron@tc ~/g/ruby (inline-new)> ruby -v test.rb ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [arm64-darwin24] test.rb:8:in 'Class#new' test.rb:8:in 'Object#hello' test.rb:11:in '
' aaron@tc ~/g/ruby (inline-new)> ./miniruby -v test.rb ruby 3.5.0dev (2025-03-28T23:59:40Z inline-new c4157884e4) +PRISM [arm64-darwin24] test.rb:8:in 'Object#hello' test.rb:11:in '
' ``` It also increases memory usage for calls to `new` by 122 bytes: ``` aaron@tc ~/g/ruby (inline-new)> cat test.rb require "objspace" class Foo def initialize puts caller end end def hello Foo.new end puts ObjectSpace.memsize_of(RubyVM::InstructionSequence.of(method(:hello))) aaron@tc ~/g/ruby (inline-new)> make runruby RUBY_ON_BUG='gdb -x ./.gdbinit -p' ./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -- --disable-gems ./test.rb 656 aaron@tc ~/g/ruby (inline-new)> ruby -v test.rb ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [arm64-darwin24] 544 ``` Thanks to @ko1 for coming up with this idea! Co-Authored-By: John Hawthorn --- debug_counter.h | 3 + insns.def | 24 +++ lib/erb/compiler.rb | 12 +- prism_compile.c | 47 +++- test/erb/test_erb.rb | 6 + test/objspace/test_objspace.rb | 4 +- test/ruby/test_settracefunc.rb | 2 +- yjit/bindgen/src/main.rs | 2 + yjit/src/codegen.rs | 65 ++++++ yjit/src/cruby_bindings.inc.rs | 382 +++++++++++++++++---------------- 10 files changed, 355 insertions(+), 192 deletions(-) diff --git a/debug_counter.h b/debug_counter.h index 481a0727e686b8..c4ee26534f3d85 100644 --- a/debug_counter.h +++ b/debug_counter.h @@ -316,6 +316,9 @@ RB_DEBUG_COUNTER(obj_imemo_callinfo) RB_DEBUG_COUNTER(obj_imemo_callcache) RB_DEBUG_COUNTER(obj_imemo_constcache) +RB_DEBUG_COUNTER(opt_new_hit) +RB_DEBUG_COUNTER(opt_new_miss) + /* ar_table */ RB_DEBUG_COUNTER(artable_hint_hit) RB_DEBUG_COUNTER(artable_hint_miss) diff --git a/insns.def b/insns.def index c963960ac38d26..e66124628315ad 100644 --- a/insns.def +++ b/insns.def @@ -905,6 +905,30 @@ opt_send_without_block } } +/* Jump if "new" method has been defined by user */ +DEFINE_INSN +opt_new +(CALL_DATA cd, OFFSET dst) +() +() +// attr bool leaf = false; +{ + VALUE argc = vm_ci_argc(cd->ci); + VALUE val = TOPN(argc); + + if (vm_method_cfunc_is(GET_ISEQ(), cd, val, rb_class_new_instance_pass_kw)) { + RB_DEBUG_COUNTER_INC(opt_new_hit); + val = rb_obj_alloc(val); + TOPN(argc) = val; + RUBY_ASSERT(TOPN(argc + 1) == Qnil); + TOPN(argc + 1) = val; + } + else { + RB_DEBUG_COUNTER_INC(opt_new_miss); + JUMP(dst); + } +} + /* Convert object to string using to_s or equivalent. */ DEFINE_INSN objtostring diff --git a/lib/erb/compiler.rb b/lib/erb/compiler.rb index 74947a9a5ff8e9..08b5eb4ee1d220 100644 --- a/lib/erb/compiler.rb +++ b/lib/erb/compiler.rb @@ -472,7 +472,17 @@ def detect_magic_comment(s, enc = nil) return enc, frozen end + # :stopdoc: + WARNING_UPLEVEL = Class.new { + attr_reader :c + def initialize from + @c = caller.length - from.length + end + }.new(caller(0)).c + private_constant :WARNING_UPLEVEL + # :startdoc: + def warn_invalid_trim_mode(mode, uplevel:) - warn "Invalid ERB trim mode: #{mode.inspect} (trim_mode: nil, 0, 1, 2, or String composed of '%' and/or '-', '>', '<>')", uplevel: uplevel + 1 + warn "Invalid ERB trim mode: #{mode.inspect} (trim_mode: nil, 0, 1, 2, or String composed of '%' and/or '-', '>', '<>')", uplevel: uplevel + WARNING_UPLEVEL end end diff --git a/prism_compile.c b/prism_compile.c index 3242cc3f2dc45c..3688a1e515c6bf 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -3620,6 +3620,9 @@ pm_compile_call(rb_iseq_t *iseq, const pm_call_node_t *call_node, LINK_ANCHOR *c if (message_loc->start == NULL) message_loc = &call_node->base.location; const pm_node_location_t location = PM_LOCATION_START_LOCATION(scope_node->parser, message_loc, call_node->base.node_id); + + LINK_ELEMENT *opt_new_prelude = LAST_ELEMENT(ret); + LABEL *else_label = NEW_LABEL(location.line); LABEL *end_label = NEW_LABEL(location.line); LABEL *retry_end_l = NEW_LABEL(location.line); @@ -3714,7 +3717,49 @@ pm_compile_call(rb_iseq_t *iseq, const pm_call_node_t *call_node, LINK_ANCHOR *c PUSH_INSN(ret, location, splatkw); } - PUSH_SEND_R(ret, location, method_id, INT2FIX(orig_argc), block_iseq, INT2FIX(flags), kw_arg); + LABEL *not_basic_new = NEW_LABEL(location.line); + LABEL *not_basic_new_finish = NEW_LABEL(location.line); + + bool inline_new = ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction && + method_id == rb_intern("new") && + call_node->block == NULL; + + if (inline_new) { + if (LAST_ELEMENT(ret) == opt_new_prelude) { + PUSH_INSN(ret, location, putnil); + PUSH_INSN(ret, location, swap); + } + else { + ELEM_INSERT_NEXT(opt_new_prelude, &new_insn_body(iseq, location.line, location.node_id, BIN(swap), 0)->link); + ELEM_INSERT_NEXT(opt_new_prelude, &new_insn_body(iseq, location.line, location.node_id, BIN(putnil), 0)->link); + } + + // Jump unless the receiver uses the "basic" implementation of "new" + VALUE ci; + if (flags & VM_CALL_FORWARDING) { + ci = (VALUE)new_callinfo(iseq, method_id, orig_argc + 1, flags, kw_arg, 0); + } + else { + ci = (VALUE)new_callinfo(iseq, method_id, orig_argc, flags, kw_arg, 0); + } + + PUSH_INSN2(ret, location, opt_new, ci, not_basic_new); + LABEL_REF(not_basic_new); + // optimized path + PUSH_SEND_R(ret, location, rb_intern("initialize"), INT2FIX(orig_argc), block_iseq, INT2FIX(flags | VM_CALL_FCALL), kw_arg); + PUSH_INSNL(ret, location, jump, not_basic_new_finish); + + PUSH_LABEL(ret, not_basic_new); + // Fall back to normal send + PUSH_SEND_R(ret, location, method_id, INT2FIX(orig_argc), block_iseq, INT2FIX(flags), kw_arg); + PUSH_INSN(ret, location, swap); + + PUSH_LABEL(ret, not_basic_new_finish); + PUSH_INSN(ret, location, pop); + } + else { + PUSH_SEND_R(ret, location, method_id, INT2FIX(orig_argc), block_iseq, INT2FIX(flags), kw_arg); + } if (block_iseq && ISEQ_BODY(block_iseq)->catch_table) { pm_compile_retry_end_label(iseq, ret, retry_end_l); diff --git a/test/erb/test_erb.rb b/test/erb/test_erb.rb index 555345a1401a6d..24f6cc5d8944e0 100644 --- a/test/erb/test_erb.rb +++ b/test/erb/test_erb.rb @@ -251,6 +251,12 @@ def test_explicit_trim_line_with_carriage_return assert_equal("line\r\n" * 3, erb.result) end + def test_safe_level_warning + assert_warning(/#{__FILE__}:#{__LINE__ + 1}/) do + @erb.new("", 1) + end + end + def test_invalid_trim_mode pend if RUBY_ENGINE == 'truffleruby' diff --git a/test/objspace/test_objspace.rb b/test/objspace/test_objspace.rb index e1aa57e46e2b62..39fa72e7dd879b 100644 --- a/test/objspace/test_objspace.rb +++ b/test/objspace/test_objspace.rb @@ -203,8 +203,8 @@ def test_trace_object_allocations assert_equal(line1, ObjectSpace.allocation_sourceline(o1)) assert_equal(__FILE__, ObjectSpace.allocation_sourcefile(o1)) assert_equal(c1, ObjectSpace.allocation_generation(o1)) - assert_equal(Class.name, ObjectSpace.allocation_class_path(o1)) - assert_equal(:new, ObjectSpace.allocation_method_id(o1)) + assert_equal(self.class.name, ObjectSpace.allocation_class_path(o1)) + assert_equal(__method__, ObjectSpace.allocation_method_id(o1)) assert_equal(__FILE__, ObjectSpace.allocation_sourcefile(o2)) assert_equal(line2, ObjectSpace.allocation_sourceline(o2)) diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb index 55c07abbea2d48..fac6dd818533d0 100644 --- a/test/ruby/test_settracefunc.rb +++ b/test/ruby/test_settracefunc.rb @@ -1999,7 +1999,7 @@ def m TracePoint.new(:c_call, &capture_events).enable{ c.new } - assert_equal [:c_call, :itself, :initialize], events[1] + assert_equal [:c_call, :itself, :initialize], events[0] events.clear o = Class.new{ diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index 8376b593b2270b..9305a50cc9f1a1 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -389,6 +389,8 @@ fn main() { // From internal/object.h .allowlist_function("rb_class_allocate_instance") .allowlist_function("rb_obj_equal") + .allowlist_function("rb_class_new_instance_pass_kw") + .allowlist_function("rb_obj_alloc") // From gc.h and internal/gc.h .allowlist_function("rb_obj_info") diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 97ea3877aadfbe..0d74f2a3fbc224 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -4873,6 +4873,70 @@ fn gen_throw( Some(EndBlock) } +fn gen_opt_new( + jit: &mut JITState, + asm: &mut Assembler, +) -> Option { + let cd = jit.get_arg(0).as_ptr(); + let jump_offset = jit.get_arg(1).as_i32(); + + if !jit.at_compile_target() { + return jit.defer_compilation(asm); + } + + let ci = unsafe { get_call_data_ci(cd) }; // info about the call site + let mid = unsafe { vm_ci_mid(ci) }; + let argc: i32 = unsafe { vm_ci_argc(ci) }.try_into().unwrap(); + + let recv_idx = argc; + let comptime_recv = jit.peek_at_stack(&asm.ctx, recv_idx as isize); + + // This is a singleton class + let comptime_recv_klass = comptime_recv.class_of(); + + let recv = asm.stack_opnd(recv_idx); + + perf_call!("opt_new: ", jit_guard_known_klass( + jit, + asm, + comptime_recv_klass, + recv, + recv.into(), + comptime_recv, + SEND_MAX_DEPTH, + Counter::guard_send_klass_megamorphic, + )); + + // We now know that it's always comptime_recv_klass + if jit.assume_expected_cfunc(asm, comptime_recv_klass, mid, rb_class_new_instance_pass_kw as _) { + // Fast path + // call rb_class_alloc to actually allocate + jit_prepare_non_leaf_call(jit, asm); + let obj = asm.ccall(rb_obj_alloc as _, vec![comptime_recv.into()]); + + // Get a reference to the stack location where we need to save the + // return instance. + let result = asm.stack_opnd(recv_idx + 1); + let recv = asm.stack_opnd(recv_idx); + + // Replace the receiver for the upcoming initialize call + asm.ctx.set_opnd_mapping(recv.into(), TempMapping::MapToStack(Type::UnknownHeap)); + asm.mov(recv, obj); + + // Save the allocated object for return + asm.ctx.set_opnd_mapping(result.into(), TempMapping::MapToStack(Type::UnknownHeap)); + asm.mov(result, obj); + + jump_to_next_insn(jit, asm) + } else { + // general case + + // Get the branch target instruction offsets + let jump_idx = jit.next_insn_idx() as i32 + jump_offset; + return end_block_with_jump(jit, asm, jump_idx as u16); + } +} + fn gen_jump( jit: &mut JITState, asm: &mut Assembler, @@ -10699,6 +10763,7 @@ fn get_gen_fn(opcode: VALUE) -> Option { YARVINSN_branchnil => Some(gen_branchnil), YARVINSN_throw => Some(gen_throw), YARVINSN_jump => Some(gen_jump), + YARVINSN_opt_new => Some(gen_opt_new), YARVINSN_getblockparamproxy => Some(gen_getblockparamproxy), YARVINSN_getblockparam => Some(gen_getblockparam), diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index 82485dadfb2ead..c373c2357d9334 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -785,193 +785,195 @@ pub const YARVINSN_definesmethod: ruby_vminsn_type = 54; pub const YARVINSN_send: ruby_vminsn_type = 55; pub const YARVINSN_sendforward: ruby_vminsn_type = 56; pub const YARVINSN_opt_send_without_block: ruby_vminsn_type = 57; -pub const YARVINSN_objtostring: ruby_vminsn_type = 58; -pub const YARVINSN_opt_ary_freeze: ruby_vminsn_type = 59; -pub const YARVINSN_opt_hash_freeze: ruby_vminsn_type = 60; -pub const YARVINSN_opt_str_freeze: ruby_vminsn_type = 61; -pub const YARVINSN_opt_nil_p: ruby_vminsn_type = 62; -pub const YARVINSN_opt_str_uminus: ruby_vminsn_type = 63; -pub const YARVINSN_opt_duparray_send: ruby_vminsn_type = 64; -pub const YARVINSN_opt_newarray_send: ruby_vminsn_type = 65; -pub const YARVINSN_invokesuper: ruby_vminsn_type = 66; -pub const YARVINSN_invokesuperforward: ruby_vminsn_type = 67; -pub const YARVINSN_invokeblock: ruby_vminsn_type = 68; -pub const YARVINSN_leave: ruby_vminsn_type = 69; -pub const YARVINSN_throw: ruby_vminsn_type = 70; -pub const YARVINSN_jump: ruby_vminsn_type = 71; -pub const YARVINSN_branchif: ruby_vminsn_type = 72; -pub const YARVINSN_branchunless: ruby_vminsn_type = 73; -pub const YARVINSN_branchnil: ruby_vminsn_type = 74; -pub const YARVINSN_once: ruby_vminsn_type = 75; -pub const YARVINSN_opt_case_dispatch: ruby_vminsn_type = 76; -pub const YARVINSN_opt_plus: ruby_vminsn_type = 77; -pub const YARVINSN_opt_minus: ruby_vminsn_type = 78; -pub const YARVINSN_opt_mult: ruby_vminsn_type = 79; -pub const YARVINSN_opt_div: ruby_vminsn_type = 80; -pub const YARVINSN_opt_mod: ruby_vminsn_type = 81; -pub const YARVINSN_opt_eq: ruby_vminsn_type = 82; -pub const YARVINSN_opt_neq: ruby_vminsn_type = 83; -pub const YARVINSN_opt_lt: ruby_vminsn_type = 84; -pub const YARVINSN_opt_le: ruby_vminsn_type = 85; -pub const YARVINSN_opt_gt: ruby_vminsn_type = 86; -pub const YARVINSN_opt_ge: ruby_vminsn_type = 87; -pub const YARVINSN_opt_ltlt: ruby_vminsn_type = 88; -pub const YARVINSN_opt_and: ruby_vminsn_type = 89; -pub const YARVINSN_opt_or: ruby_vminsn_type = 90; -pub const YARVINSN_opt_aref: ruby_vminsn_type = 91; -pub const YARVINSN_opt_aset: ruby_vminsn_type = 92; -pub const YARVINSN_opt_aset_with: ruby_vminsn_type = 93; -pub const YARVINSN_opt_aref_with: ruby_vminsn_type = 94; -pub const YARVINSN_opt_length: ruby_vminsn_type = 95; -pub const YARVINSN_opt_size: ruby_vminsn_type = 96; -pub const YARVINSN_opt_empty_p: ruby_vminsn_type = 97; -pub const YARVINSN_opt_succ: ruby_vminsn_type = 98; -pub const YARVINSN_opt_not: ruby_vminsn_type = 99; -pub const YARVINSN_opt_regexpmatch2: ruby_vminsn_type = 100; -pub const YARVINSN_invokebuiltin: ruby_vminsn_type = 101; -pub const YARVINSN_opt_invokebuiltin_delegate: ruby_vminsn_type = 102; -pub const YARVINSN_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 103; -pub const YARVINSN_getlocal_WC_0: ruby_vminsn_type = 104; -pub const YARVINSN_getlocal_WC_1: ruby_vminsn_type = 105; -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_zjit_opt_send_without_block: ruby_vminsn_type = 110; -pub const YARVINSN_zjit_opt_plus: ruby_vminsn_type = 111; -pub const YARVINSN_zjit_opt_minus: ruby_vminsn_type = 112; -pub const YARVINSN_zjit_opt_mult: ruby_vminsn_type = 113; -pub const YARVINSN_zjit_opt_div: ruby_vminsn_type = 114; -pub const YARVINSN_zjit_opt_mod: ruby_vminsn_type = 115; -pub const YARVINSN_zjit_opt_eq: ruby_vminsn_type = 116; -pub const YARVINSN_zjit_opt_neq: ruby_vminsn_type = 117; -pub const YARVINSN_zjit_opt_lt: ruby_vminsn_type = 118; -pub const YARVINSN_zjit_opt_le: ruby_vminsn_type = 119; -pub const YARVINSN_zjit_opt_gt: ruby_vminsn_type = 120; -pub const YARVINSN_zjit_opt_ge: ruby_vminsn_type = 121; -pub const YARVINSN_trace_nop: ruby_vminsn_type = 122; -pub const YARVINSN_trace_getlocal: ruby_vminsn_type = 123; -pub const YARVINSN_trace_setlocal: ruby_vminsn_type = 124; -pub const YARVINSN_trace_getblockparam: ruby_vminsn_type = 125; -pub const YARVINSN_trace_setblockparam: ruby_vminsn_type = 126; -pub const YARVINSN_trace_getblockparamproxy: ruby_vminsn_type = 127; -pub const YARVINSN_trace_getspecial: ruby_vminsn_type = 128; -pub const YARVINSN_trace_setspecial: ruby_vminsn_type = 129; -pub const YARVINSN_trace_getinstancevariable: ruby_vminsn_type = 130; -pub const YARVINSN_trace_setinstancevariable: ruby_vminsn_type = 131; -pub const YARVINSN_trace_getclassvariable: ruby_vminsn_type = 132; -pub const YARVINSN_trace_setclassvariable: ruby_vminsn_type = 133; -pub const YARVINSN_trace_opt_getconstant_path: ruby_vminsn_type = 134; -pub const YARVINSN_trace_getconstant: ruby_vminsn_type = 135; -pub const YARVINSN_trace_setconstant: ruby_vminsn_type = 136; -pub const YARVINSN_trace_getglobal: ruby_vminsn_type = 137; -pub const YARVINSN_trace_setglobal: ruby_vminsn_type = 138; -pub const YARVINSN_trace_putnil: ruby_vminsn_type = 139; -pub const YARVINSN_trace_putself: ruby_vminsn_type = 140; -pub const YARVINSN_trace_putobject: ruby_vminsn_type = 141; -pub const YARVINSN_trace_putspecialobject: ruby_vminsn_type = 142; -pub const YARVINSN_trace_putstring: ruby_vminsn_type = 143; -pub const YARVINSN_trace_putchilledstring: ruby_vminsn_type = 144; -pub const YARVINSN_trace_concatstrings: ruby_vminsn_type = 145; -pub const YARVINSN_trace_anytostring: ruby_vminsn_type = 146; -pub const YARVINSN_trace_toregexp: ruby_vminsn_type = 147; -pub const YARVINSN_trace_intern: ruby_vminsn_type = 148; -pub const YARVINSN_trace_newarray: ruby_vminsn_type = 149; -pub const YARVINSN_trace_pushtoarraykwsplat: ruby_vminsn_type = 150; -pub const YARVINSN_trace_duparray: ruby_vminsn_type = 151; -pub const YARVINSN_trace_duphash: ruby_vminsn_type = 152; -pub const YARVINSN_trace_expandarray: ruby_vminsn_type = 153; -pub const YARVINSN_trace_concatarray: ruby_vminsn_type = 154; -pub const YARVINSN_trace_concattoarray: ruby_vminsn_type = 155; -pub const YARVINSN_trace_pushtoarray: ruby_vminsn_type = 156; -pub const YARVINSN_trace_splatarray: ruby_vminsn_type = 157; -pub const YARVINSN_trace_splatkw: ruby_vminsn_type = 158; -pub const YARVINSN_trace_newhash: ruby_vminsn_type = 159; -pub const YARVINSN_trace_newrange: ruby_vminsn_type = 160; -pub const YARVINSN_trace_pop: ruby_vminsn_type = 161; -pub const YARVINSN_trace_dup: ruby_vminsn_type = 162; -pub const YARVINSN_trace_dupn: ruby_vminsn_type = 163; -pub const YARVINSN_trace_swap: ruby_vminsn_type = 164; -pub const YARVINSN_trace_opt_reverse: ruby_vminsn_type = 165; -pub const YARVINSN_trace_topn: ruby_vminsn_type = 166; -pub const YARVINSN_trace_setn: ruby_vminsn_type = 167; -pub const YARVINSN_trace_adjuststack: ruby_vminsn_type = 168; -pub const YARVINSN_trace_defined: ruby_vminsn_type = 169; -pub const YARVINSN_trace_definedivar: ruby_vminsn_type = 170; -pub const YARVINSN_trace_checkmatch: ruby_vminsn_type = 171; -pub const YARVINSN_trace_checkkeyword: ruby_vminsn_type = 172; -pub const YARVINSN_trace_checktype: ruby_vminsn_type = 173; -pub const YARVINSN_trace_defineclass: ruby_vminsn_type = 174; -pub const YARVINSN_trace_definemethod: ruby_vminsn_type = 175; -pub const YARVINSN_trace_definesmethod: ruby_vminsn_type = 176; -pub const YARVINSN_trace_send: ruby_vminsn_type = 177; -pub const YARVINSN_trace_sendforward: ruby_vminsn_type = 178; -pub const YARVINSN_trace_opt_send_without_block: ruby_vminsn_type = 179; -pub const YARVINSN_trace_objtostring: ruby_vminsn_type = 180; -pub const YARVINSN_trace_opt_ary_freeze: ruby_vminsn_type = 181; -pub const YARVINSN_trace_opt_hash_freeze: ruby_vminsn_type = 182; -pub const YARVINSN_trace_opt_str_freeze: ruby_vminsn_type = 183; -pub const YARVINSN_trace_opt_nil_p: ruby_vminsn_type = 184; -pub const YARVINSN_trace_opt_str_uminus: ruby_vminsn_type = 185; -pub const YARVINSN_trace_opt_duparray_send: ruby_vminsn_type = 186; -pub const YARVINSN_trace_opt_newarray_send: ruby_vminsn_type = 187; -pub const YARVINSN_trace_invokesuper: ruby_vminsn_type = 188; -pub const YARVINSN_trace_invokesuperforward: ruby_vminsn_type = 189; -pub const YARVINSN_trace_invokeblock: ruby_vminsn_type = 190; -pub const YARVINSN_trace_leave: ruby_vminsn_type = 191; -pub const YARVINSN_trace_throw: ruby_vminsn_type = 192; -pub const YARVINSN_trace_jump: ruby_vminsn_type = 193; -pub const YARVINSN_trace_branchif: ruby_vminsn_type = 194; -pub const YARVINSN_trace_branchunless: ruby_vminsn_type = 195; -pub const YARVINSN_trace_branchnil: ruby_vminsn_type = 196; -pub const YARVINSN_trace_once: ruby_vminsn_type = 197; -pub const YARVINSN_trace_opt_case_dispatch: ruby_vminsn_type = 198; -pub const YARVINSN_trace_opt_plus: ruby_vminsn_type = 199; -pub const YARVINSN_trace_opt_minus: ruby_vminsn_type = 200; -pub const YARVINSN_trace_opt_mult: ruby_vminsn_type = 201; -pub const YARVINSN_trace_opt_div: ruby_vminsn_type = 202; -pub const YARVINSN_trace_opt_mod: ruby_vminsn_type = 203; -pub const YARVINSN_trace_opt_eq: ruby_vminsn_type = 204; -pub const YARVINSN_trace_opt_neq: ruby_vminsn_type = 205; -pub const YARVINSN_trace_opt_lt: ruby_vminsn_type = 206; -pub const YARVINSN_trace_opt_le: ruby_vminsn_type = 207; -pub const YARVINSN_trace_opt_gt: ruby_vminsn_type = 208; -pub const YARVINSN_trace_opt_ge: ruby_vminsn_type = 209; -pub const YARVINSN_trace_opt_ltlt: ruby_vminsn_type = 210; -pub const YARVINSN_trace_opt_and: ruby_vminsn_type = 211; -pub const YARVINSN_trace_opt_or: ruby_vminsn_type = 212; -pub const YARVINSN_trace_opt_aref: ruby_vminsn_type = 213; -pub const YARVINSN_trace_opt_aset: ruby_vminsn_type = 214; -pub const YARVINSN_trace_opt_aset_with: ruby_vminsn_type = 215; -pub const YARVINSN_trace_opt_aref_with: ruby_vminsn_type = 216; -pub const YARVINSN_trace_opt_length: ruby_vminsn_type = 217; -pub const YARVINSN_trace_opt_size: ruby_vminsn_type = 218; -pub const YARVINSN_trace_opt_empty_p: ruby_vminsn_type = 219; -pub const YARVINSN_trace_opt_succ: ruby_vminsn_type = 220; -pub const YARVINSN_trace_opt_not: ruby_vminsn_type = 221; -pub const YARVINSN_trace_opt_regexpmatch2: ruby_vminsn_type = 222; -pub const YARVINSN_trace_invokebuiltin: ruby_vminsn_type = 223; -pub const YARVINSN_trace_opt_invokebuiltin_delegate: ruby_vminsn_type = 224; -pub const YARVINSN_trace_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 225; -pub const YARVINSN_trace_getlocal_WC_0: ruby_vminsn_type = 226; -pub const YARVINSN_trace_getlocal_WC_1: ruby_vminsn_type = 227; -pub const YARVINSN_trace_setlocal_WC_0: ruby_vminsn_type = 228; -pub const YARVINSN_trace_setlocal_WC_1: ruby_vminsn_type = 229; -pub const YARVINSN_trace_putobject_INT2FIX_0_: ruby_vminsn_type = 230; -pub const YARVINSN_trace_putobject_INT2FIX_1_: ruby_vminsn_type = 231; -pub const YARVINSN_trace_zjit_opt_send_without_block: ruby_vminsn_type = 232; -pub const YARVINSN_trace_zjit_opt_plus: ruby_vminsn_type = 233; -pub const YARVINSN_trace_zjit_opt_minus: ruby_vminsn_type = 234; -pub const YARVINSN_trace_zjit_opt_mult: ruby_vminsn_type = 235; -pub const YARVINSN_trace_zjit_opt_div: ruby_vminsn_type = 236; -pub const YARVINSN_trace_zjit_opt_mod: ruby_vminsn_type = 237; -pub const YARVINSN_trace_zjit_opt_eq: ruby_vminsn_type = 238; -pub const YARVINSN_trace_zjit_opt_neq: ruby_vminsn_type = 239; -pub const YARVINSN_trace_zjit_opt_lt: ruby_vminsn_type = 240; -pub const YARVINSN_trace_zjit_opt_le: ruby_vminsn_type = 241; -pub const YARVINSN_trace_zjit_opt_gt: ruby_vminsn_type = 242; -pub const YARVINSN_trace_zjit_opt_ge: ruby_vminsn_type = 243; -pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 244; +pub const YARVINSN_opt_new: ruby_vminsn_type = 58; +pub const YARVINSN_objtostring: ruby_vminsn_type = 59; +pub const YARVINSN_opt_ary_freeze: ruby_vminsn_type = 60; +pub const YARVINSN_opt_hash_freeze: ruby_vminsn_type = 61; +pub const YARVINSN_opt_str_freeze: ruby_vminsn_type = 62; +pub const YARVINSN_opt_nil_p: ruby_vminsn_type = 63; +pub const YARVINSN_opt_str_uminus: ruby_vminsn_type = 64; +pub const YARVINSN_opt_duparray_send: ruby_vminsn_type = 65; +pub const YARVINSN_opt_newarray_send: ruby_vminsn_type = 66; +pub const YARVINSN_invokesuper: ruby_vminsn_type = 67; +pub const YARVINSN_invokesuperforward: ruby_vminsn_type = 68; +pub const YARVINSN_invokeblock: ruby_vminsn_type = 69; +pub const YARVINSN_leave: ruby_vminsn_type = 70; +pub const YARVINSN_throw: ruby_vminsn_type = 71; +pub const YARVINSN_jump: ruby_vminsn_type = 72; +pub const YARVINSN_branchif: ruby_vminsn_type = 73; +pub const YARVINSN_branchunless: ruby_vminsn_type = 74; +pub const YARVINSN_branchnil: ruby_vminsn_type = 75; +pub const YARVINSN_once: ruby_vminsn_type = 76; +pub const YARVINSN_opt_case_dispatch: ruby_vminsn_type = 77; +pub const YARVINSN_opt_plus: ruby_vminsn_type = 78; +pub const YARVINSN_opt_minus: ruby_vminsn_type = 79; +pub const YARVINSN_opt_mult: ruby_vminsn_type = 80; +pub const YARVINSN_opt_div: ruby_vminsn_type = 81; +pub const YARVINSN_opt_mod: ruby_vminsn_type = 82; +pub const YARVINSN_opt_eq: ruby_vminsn_type = 83; +pub const YARVINSN_opt_neq: ruby_vminsn_type = 84; +pub const YARVINSN_opt_lt: ruby_vminsn_type = 85; +pub const YARVINSN_opt_le: ruby_vminsn_type = 86; +pub const YARVINSN_opt_gt: ruby_vminsn_type = 87; +pub const YARVINSN_opt_ge: ruby_vminsn_type = 88; +pub const YARVINSN_opt_ltlt: ruby_vminsn_type = 89; +pub const YARVINSN_opt_and: ruby_vminsn_type = 90; +pub const YARVINSN_opt_or: ruby_vminsn_type = 91; +pub const YARVINSN_opt_aref: ruby_vminsn_type = 92; +pub const YARVINSN_opt_aset: ruby_vminsn_type = 93; +pub const YARVINSN_opt_aset_with: ruby_vminsn_type = 94; +pub const YARVINSN_opt_aref_with: ruby_vminsn_type = 95; +pub const YARVINSN_opt_length: ruby_vminsn_type = 96; +pub const YARVINSN_opt_size: ruby_vminsn_type = 97; +pub const YARVINSN_opt_empty_p: ruby_vminsn_type = 98; +pub const YARVINSN_opt_succ: ruby_vminsn_type = 99; +pub const YARVINSN_opt_not: ruby_vminsn_type = 100; +pub const YARVINSN_opt_regexpmatch2: ruby_vminsn_type = 101; +pub const YARVINSN_invokebuiltin: ruby_vminsn_type = 102; +pub const YARVINSN_opt_invokebuiltin_delegate: ruby_vminsn_type = 103; +pub const YARVINSN_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 104; +pub const YARVINSN_getlocal_WC_0: ruby_vminsn_type = 105; +pub const YARVINSN_getlocal_WC_1: ruby_vminsn_type = 106; +pub const YARVINSN_setlocal_WC_0: ruby_vminsn_type = 107; +pub const YARVINSN_setlocal_WC_1: ruby_vminsn_type = 108; +pub const YARVINSN_putobject_INT2FIX_0_: ruby_vminsn_type = 109; +pub const YARVINSN_putobject_INT2FIX_1_: ruby_vminsn_type = 110; +pub const YARVINSN_zjit_opt_send_without_block: ruby_vminsn_type = 111; +pub const YARVINSN_zjit_opt_plus: ruby_vminsn_type = 112; +pub const YARVINSN_zjit_opt_minus: ruby_vminsn_type = 113; +pub const YARVINSN_zjit_opt_mult: ruby_vminsn_type = 114; +pub const YARVINSN_zjit_opt_div: ruby_vminsn_type = 115; +pub const YARVINSN_zjit_opt_mod: ruby_vminsn_type = 116; +pub const YARVINSN_zjit_opt_eq: ruby_vminsn_type = 117; +pub const YARVINSN_zjit_opt_neq: ruby_vminsn_type = 118; +pub const YARVINSN_zjit_opt_lt: ruby_vminsn_type = 119; +pub const YARVINSN_zjit_opt_le: ruby_vminsn_type = 120; +pub const YARVINSN_zjit_opt_gt: ruby_vminsn_type = 121; +pub const YARVINSN_zjit_opt_ge: ruby_vminsn_type = 122; +pub const YARVINSN_trace_nop: ruby_vminsn_type = 123; +pub const YARVINSN_trace_getlocal: ruby_vminsn_type = 124; +pub const YARVINSN_trace_setlocal: ruby_vminsn_type = 125; +pub const YARVINSN_trace_getblockparam: ruby_vminsn_type = 126; +pub const YARVINSN_trace_setblockparam: ruby_vminsn_type = 127; +pub const YARVINSN_trace_getblockparamproxy: ruby_vminsn_type = 128; +pub const YARVINSN_trace_getspecial: ruby_vminsn_type = 129; +pub const YARVINSN_trace_setspecial: ruby_vminsn_type = 130; +pub const YARVINSN_trace_getinstancevariable: ruby_vminsn_type = 131; +pub const YARVINSN_trace_setinstancevariable: ruby_vminsn_type = 132; +pub const YARVINSN_trace_getclassvariable: ruby_vminsn_type = 133; +pub const YARVINSN_trace_setclassvariable: ruby_vminsn_type = 134; +pub const YARVINSN_trace_opt_getconstant_path: ruby_vminsn_type = 135; +pub const YARVINSN_trace_getconstant: ruby_vminsn_type = 136; +pub const YARVINSN_trace_setconstant: ruby_vminsn_type = 137; +pub const YARVINSN_trace_getglobal: ruby_vminsn_type = 138; +pub const YARVINSN_trace_setglobal: ruby_vminsn_type = 139; +pub const YARVINSN_trace_putnil: ruby_vminsn_type = 140; +pub const YARVINSN_trace_putself: ruby_vminsn_type = 141; +pub const YARVINSN_trace_putobject: ruby_vminsn_type = 142; +pub const YARVINSN_trace_putspecialobject: ruby_vminsn_type = 143; +pub const YARVINSN_trace_putstring: ruby_vminsn_type = 144; +pub const YARVINSN_trace_putchilledstring: ruby_vminsn_type = 145; +pub const YARVINSN_trace_concatstrings: ruby_vminsn_type = 146; +pub const YARVINSN_trace_anytostring: ruby_vminsn_type = 147; +pub const YARVINSN_trace_toregexp: ruby_vminsn_type = 148; +pub const YARVINSN_trace_intern: ruby_vminsn_type = 149; +pub const YARVINSN_trace_newarray: ruby_vminsn_type = 150; +pub const YARVINSN_trace_pushtoarraykwsplat: ruby_vminsn_type = 151; +pub const YARVINSN_trace_duparray: ruby_vminsn_type = 152; +pub const YARVINSN_trace_duphash: ruby_vminsn_type = 153; +pub const YARVINSN_trace_expandarray: ruby_vminsn_type = 154; +pub const YARVINSN_trace_concatarray: ruby_vminsn_type = 155; +pub const YARVINSN_trace_concattoarray: ruby_vminsn_type = 156; +pub const YARVINSN_trace_pushtoarray: ruby_vminsn_type = 157; +pub const YARVINSN_trace_splatarray: ruby_vminsn_type = 158; +pub const YARVINSN_trace_splatkw: ruby_vminsn_type = 159; +pub const YARVINSN_trace_newhash: ruby_vminsn_type = 160; +pub const YARVINSN_trace_newrange: ruby_vminsn_type = 161; +pub const YARVINSN_trace_pop: ruby_vminsn_type = 162; +pub const YARVINSN_trace_dup: ruby_vminsn_type = 163; +pub const YARVINSN_trace_dupn: ruby_vminsn_type = 164; +pub const YARVINSN_trace_swap: ruby_vminsn_type = 165; +pub const YARVINSN_trace_opt_reverse: ruby_vminsn_type = 166; +pub const YARVINSN_trace_topn: ruby_vminsn_type = 167; +pub const YARVINSN_trace_setn: ruby_vminsn_type = 168; +pub const YARVINSN_trace_adjuststack: ruby_vminsn_type = 169; +pub const YARVINSN_trace_defined: ruby_vminsn_type = 170; +pub const YARVINSN_trace_definedivar: ruby_vminsn_type = 171; +pub const YARVINSN_trace_checkmatch: ruby_vminsn_type = 172; +pub const YARVINSN_trace_checkkeyword: ruby_vminsn_type = 173; +pub const YARVINSN_trace_checktype: ruby_vminsn_type = 174; +pub const YARVINSN_trace_defineclass: ruby_vminsn_type = 175; +pub const YARVINSN_trace_definemethod: ruby_vminsn_type = 176; +pub const YARVINSN_trace_definesmethod: ruby_vminsn_type = 177; +pub const YARVINSN_trace_send: ruby_vminsn_type = 178; +pub const YARVINSN_trace_sendforward: ruby_vminsn_type = 179; +pub const YARVINSN_trace_opt_send_without_block: ruby_vminsn_type = 180; +pub const YARVINSN_trace_opt_new: ruby_vminsn_type = 181; +pub const YARVINSN_trace_objtostring: ruby_vminsn_type = 182; +pub const YARVINSN_trace_opt_ary_freeze: ruby_vminsn_type = 183; +pub const YARVINSN_trace_opt_hash_freeze: ruby_vminsn_type = 184; +pub const YARVINSN_trace_opt_str_freeze: ruby_vminsn_type = 185; +pub const YARVINSN_trace_opt_nil_p: ruby_vminsn_type = 186; +pub const YARVINSN_trace_opt_str_uminus: ruby_vminsn_type = 187; +pub const YARVINSN_trace_opt_duparray_send: ruby_vminsn_type = 188; +pub const YARVINSN_trace_opt_newarray_send: ruby_vminsn_type = 189; +pub const YARVINSN_trace_invokesuper: ruby_vminsn_type = 190; +pub const YARVINSN_trace_invokesuperforward: ruby_vminsn_type = 191; +pub const YARVINSN_trace_invokeblock: ruby_vminsn_type = 192; +pub const YARVINSN_trace_leave: ruby_vminsn_type = 193; +pub const YARVINSN_trace_throw: ruby_vminsn_type = 194; +pub const YARVINSN_trace_jump: ruby_vminsn_type = 195; +pub const YARVINSN_trace_branchif: ruby_vminsn_type = 196; +pub const YARVINSN_trace_branchunless: ruby_vminsn_type = 197; +pub const YARVINSN_trace_branchnil: ruby_vminsn_type = 198; +pub const YARVINSN_trace_once: ruby_vminsn_type = 199; +pub const YARVINSN_trace_opt_case_dispatch: ruby_vminsn_type = 200; +pub const YARVINSN_trace_opt_plus: ruby_vminsn_type = 201; +pub const YARVINSN_trace_opt_minus: ruby_vminsn_type = 202; +pub const YARVINSN_trace_opt_mult: ruby_vminsn_type = 203; +pub const YARVINSN_trace_opt_div: ruby_vminsn_type = 204; +pub const YARVINSN_trace_opt_mod: ruby_vminsn_type = 205; +pub const YARVINSN_trace_opt_eq: ruby_vminsn_type = 206; +pub const YARVINSN_trace_opt_neq: ruby_vminsn_type = 207; +pub const YARVINSN_trace_opt_lt: ruby_vminsn_type = 208; +pub const YARVINSN_trace_opt_le: ruby_vminsn_type = 209; +pub const YARVINSN_trace_opt_gt: ruby_vminsn_type = 210; +pub const YARVINSN_trace_opt_ge: ruby_vminsn_type = 211; +pub const YARVINSN_trace_opt_ltlt: ruby_vminsn_type = 212; +pub const YARVINSN_trace_opt_and: ruby_vminsn_type = 213; +pub const YARVINSN_trace_opt_or: ruby_vminsn_type = 214; +pub const YARVINSN_trace_opt_aref: ruby_vminsn_type = 215; +pub const YARVINSN_trace_opt_aset: ruby_vminsn_type = 216; +pub const YARVINSN_trace_opt_aset_with: ruby_vminsn_type = 217; +pub const YARVINSN_trace_opt_aref_with: ruby_vminsn_type = 218; +pub const YARVINSN_trace_opt_length: ruby_vminsn_type = 219; +pub const YARVINSN_trace_opt_size: ruby_vminsn_type = 220; +pub const YARVINSN_trace_opt_empty_p: ruby_vminsn_type = 221; +pub const YARVINSN_trace_opt_succ: ruby_vminsn_type = 222; +pub const YARVINSN_trace_opt_not: ruby_vminsn_type = 223; +pub const YARVINSN_trace_opt_regexpmatch2: ruby_vminsn_type = 224; +pub const YARVINSN_trace_invokebuiltin: ruby_vminsn_type = 225; +pub const YARVINSN_trace_opt_invokebuiltin_delegate: ruby_vminsn_type = 226; +pub const YARVINSN_trace_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 227; +pub const YARVINSN_trace_getlocal_WC_0: ruby_vminsn_type = 228; +pub const YARVINSN_trace_getlocal_WC_1: ruby_vminsn_type = 229; +pub const YARVINSN_trace_setlocal_WC_0: ruby_vminsn_type = 230; +pub const YARVINSN_trace_setlocal_WC_1: ruby_vminsn_type = 231; +pub const YARVINSN_trace_putobject_INT2FIX_0_: ruby_vminsn_type = 232; +pub const YARVINSN_trace_putobject_INT2FIX_1_: ruby_vminsn_type = 233; +pub const YARVINSN_trace_zjit_opt_send_without_block: ruby_vminsn_type = 234; +pub const YARVINSN_trace_zjit_opt_plus: ruby_vminsn_type = 235; +pub const YARVINSN_trace_zjit_opt_minus: ruby_vminsn_type = 236; +pub const YARVINSN_trace_zjit_opt_mult: ruby_vminsn_type = 237; +pub const YARVINSN_trace_zjit_opt_div: ruby_vminsn_type = 238; +pub const YARVINSN_trace_zjit_opt_mod: ruby_vminsn_type = 239; +pub const YARVINSN_trace_zjit_opt_eq: ruby_vminsn_type = 240; +pub const YARVINSN_trace_zjit_opt_neq: ruby_vminsn_type = 241; +pub const YARVINSN_trace_zjit_opt_lt: ruby_vminsn_type = 242; +pub const YARVINSN_trace_zjit_opt_le: ruby_vminsn_type = 243; +pub const YARVINSN_trace_zjit_opt_gt: ruby_vminsn_type = 244; +pub const YARVINSN_trace_zjit_opt_ge: ruby_vminsn_type = 245; +pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 246; 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), @@ -1049,7 +1051,13 @@ extern "C" { pub fn rb_intern2(name: *const ::std::os::raw::c_char, len: ::std::os::raw::c_long) -> ID; pub fn rb_id2name(id: ID) -> *const ::std::os::raw::c_char; pub fn rb_class2name(klass: VALUE) -> *const ::std::os::raw::c_char; + pub fn rb_class_new_instance_pass_kw( + argc: ::std::os::raw::c_int, + argv: *const VALUE, + klass: VALUE, + ) -> VALUE; pub fn rb_obj_is_kind_of(obj: VALUE, klass: VALUE) -> VALUE; + pub fn rb_obj_alloc(klass: VALUE) -> VALUE; pub fn rb_obj_frozen_p(obj: VALUE) -> VALUE; pub fn rb_backref_get() -> VALUE; pub fn rb_range_new(beg: VALUE, end: VALUE, excl: ::std::os::raw::c_int) -> VALUE; From 52acae45147638904411922f6a228f12f3e9d074 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 7 Apr 2025 13:29:58 -0700 Subject: [PATCH 2/5] update allocation location tests --- .../trace_object_allocations_spec.rb | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/spec/ruby/library/objectspace/trace_object_allocations_spec.rb b/spec/ruby/library/objectspace/trace_object_allocations_spec.rb index 612430e067d63e..0f1e2aa8b93abf 100644 --- a/spec/ruby/library/objectspace/trace_object_allocations_spec.rb +++ b/spec/ruby/library/objectspace/trace_object_allocations_spec.rb @@ -2,6 +2,20 @@ require 'objspace' describe "ObjectSpace.trace_object_allocations" do + def has_class_frame? + Class.new { + attr_reader :c + + def initialize + @c = caller_locations.first.label =~ /new/ + end + }.new.c + end + + def obj_class_path + has_class_frame? ? "Class" : nil + end + it "runs a block" do ScratchPad.clear ObjectSpace.trace_object_allocations do @@ -13,7 +27,7 @@ it "records info for allocation_class_path" do ObjectSpace.trace_object_allocations do o = Object.new - ObjectSpace.allocation_class_path(o).should == "Class" + ObjectSpace.allocation_class_path(o).should == obj_class_path a = [1, 2, 3] ObjectSpace.allocation_class_path(a).should == nil end @@ -31,7 +45,7 @@ it "records info for allocation_method_id" do ObjectSpace.trace_object_allocations do o = Object.new - ObjectSpace.allocation_method_id(o).should == :new + ObjectSpace.allocation_method_id(o).should == (has_class_frame? ? :new : nil) a = [1, 2, 3] ObjectSpace.allocation_method_id(a).should == nil end @@ -58,7 +72,7 @@ it "can be cleared using trace_object_allocations_clear" do ObjectSpace.trace_object_allocations do o = Object.new - ObjectSpace.allocation_class_path(o).should == "Class" + ObjectSpace.allocation_class_path(o).should == obj_class_path ObjectSpace.trace_object_allocations_clear ObjectSpace.allocation_class_path(o).should be_nil end @@ -69,14 +83,14 @@ ObjectSpace.trace_object_allocations do o = Object.new end - ObjectSpace.allocation_class_path(o).should == "Class" + ObjectSpace.allocation_class_path(o).should == obj_class_path end it "can be used without a block using trace_object_allocations_start and _stop" do ObjectSpace.trace_object_allocations_start begin o = Object.new - ObjectSpace.allocation_class_path(o).should == "Class" + ObjectSpace.allocation_class_path(o).should == obj_class_path a = [1, 2, 3] ObjectSpace.allocation_class_path(a).should == nil ensure @@ -91,14 +105,14 @@ ensure ObjectSpace.trace_object_allocations_stop end - ObjectSpace.allocation_class_path(o).should == "Class" + ObjectSpace.allocation_class_path(o).should == obj_class_path end it "can be nested" do ObjectSpace.trace_object_allocations do ObjectSpace.trace_object_allocations do o = Object.new - ObjectSpace.allocation_class_path(o).should == "Class" + ObjectSpace.allocation_class_path(o).should == obj_class_path end end end @@ -109,7 +123,7 @@ ObjectSpace.trace_object_allocations_start begin o = Object.new - ObjectSpace.allocation_class_path(o).should == "Class" + ObjectSpace.allocation_class_path(o).should == obj_class_path ensure ObjectSpace.trace_object_allocations_stop end @@ -122,7 +136,7 @@ ObjectSpace.trace_object_allocations_start begin o = Object.new - ObjectSpace.allocation_class_path(o).should == "Class" + ObjectSpace.allocation_class_path(o).should == obj_class_path ObjectSpace.trace_object_allocations_stop ensure ObjectSpace.trace_object_allocations_stop From 36c0e2dc7c4017e909acee4bf99f5539549ae058 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 7 Apr 2025 15:09:16 -0700 Subject: [PATCH 3/5] Add parse.y implementation --- compile.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/compile.c b/compile.c index a319d3cbb101ab..615200b30eb2ee 100644 --- a/compile.c +++ b/compile.c @@ -9380,6 +9380,7 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co INIT_ANCHOR(recv); INIT_ANCHOR(args); + #if OPT_SUPPORT_JOKE if (nd_type_p(node, NODE_VCALL)) { ID id_bitblt; @@ -9475,6 +9476,17 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co } ADD_SEQ(ret, recv); + + bool inline_new = ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction && + mid == rb_intern("new") && + parent_block == NULL && + !(flag & VM_CALL_ARGS_BLOCKARG); + + if (inline_new) { + ADD_INSN(ret, node, putnil); + ADD_INSN(ret, node, swap); + } + ADD_SEQ(ret, args); debugp_param("call args argc", argc); @@ -9491,7 +9503,36 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co if ((flag & VM_CALL_ARGS_BLOCKARG) && (flag & VM_CALL_KW_SPLAT) && !(flag & VM_CALL_KW_SPLAT_MUT)) { ADD_INSN(ret, line_node, splatkw); } - ADD_SEND_R(ret, line_node, mid, argc, parent_block, INT2FIX(flag), keywords); + + LABEL *not_basic_new = NEW_LABEL(nd_line(node)); + LABEL *not_basic_new_finish = NEW_LABEL(nd_line(node)); + + if (inline_new) { + // Jump unless the receiver uses the "basic" implementation of "new" + VALUE ci; + if (flag & VM_CALL_FORWARDING) { + ci = (VALUE)new_callinfo(iseq, mid, NUM2INT(argc) + 1, flag, keywords, 0); + } + else { + ci = (VALUE)new_callinfo(iseq, mid, NUM2INT(argc), flag, keywords, 0); + } + ADD_INSN2(ret, node, opt_new, ci, not_basic_new); + LABEL_REF(not_basic_new); + + // optimized path + ADD_SEND_R(ret, line_node, rb_intern("initialize"), argc, parent_block, INT2FIX(flag | VM_CALL_FCALL), keywords); + ADD_INSNL(ret, line_node, jump, not_basic_new_finish); + + ADD_LABEL(ret, not_basic_new); + // Fall back to normal send + ADD_SEND_R(ret, line_node, mid, argc, parent_block, INT2FIX(flag), keywords); + ADD_INSN(ret, line_node, swap); + + ADD_LABEL(ret, not_basic_new_finish); + ADD_INSN(ret, line_node, pop); + } else { + ADD_SEND_R(ret, line_node, mid, argc, parent_block, INT2FIX(flag), keywords); + } qcall_branch_end(iseq, ret, else_label, branches, node, line_node); if (popped) { From 1a0896f354f9cc9e1d9e0a4cd077898f9ad699fe Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 7 Apr 2025 15:28:53 -0700 Subject: [PATCH 4/5] Deopt if iseq trace events are enabled --- insns.def | 2 +- test/ruby/test_settracefunc.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/insns.def b/insns.def index e66124628315ad..b0c74df2207dfe 100644 --- a/insns.def +++ b/insns.def @@ -916,7 +916,7 @@ opt_new VALUE argc = vm_ci_argc(cd->ci); VALUE val = TOPN(argc); - if (vm_method_cfunc_is(GET_ISEQ(), cd, val, rb_class_new_instance_pass_kw)) { + if (vm_method_cfunc_is(GET_ISEQ(), cd, val, rb_class_new_instance_pass_kw) && !(ruby_vm_event_flags & ISEQ_TRACE_EVENTS)) { RB_DEBUG_COUNTER_INC(opt_new_hit); val = rb_obj_alloc(val); TOPN(argc) = val; diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb index fac6dd818533d0..55c07abbea2d48 100644 --- a/test/ruby/test_settracefunc.rb +++ b/test/ruby/test_settracefunc.rb @@ -1999,7 +1999,7 @@ def m TracePoint.new(:c_call, &capture_events).enable{ c.new } - assert_equal [:c_call, :itself, :initialize], events[0] + assert_equal [:c_call, :itself, :initialize], events[1] events.clear o = Class.new{ From fffde57c46f6662bc2fcd85bb54c4922567cafbf Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 25 Apr 2025 12:20:00 -0700 Subject: [PATCH 5/5] maybe fix bindgen --- zjit/src/cruby_bindings.inc.rs | 376 +++++++++++++++++---------------- 1 file changed, 189 insertions(+), 187 deletions(-) diff --git a/zjit/src/cruby_bindings.inc.rs b/zjit/src/cruby_bindings.inc.rs index 1a7dc070af6564..1ad2c63875b5ae 100644 --- a/zjit/src/cruby_bindings.inc.rs +++ b/zjit/src/cruby_bindings.inc.rs @@ -541,193 +541,195 @@ pub const YARVINSN_definesmethod: ruby_vminsn_type = 54; pub const YARVINSN_send: ruby_vminsn_type = 55; pub const YARVINSN_sendforward: ruby_vminsn_type = 56; pub const YARVINSN_opt_send_without_block: ruby_vminsn_type = 57; -pub const YARVINSN_objtostring: ruby_vminsn_type = 58; -pub const YARVINSN_opt_ary_freeze: ruby_vminsn_type = 59; -pub const YARVINSN_opt_hash_freeze: ruby_vminsn_type = 60; -pub const YARVINSN_opt_str_freeze: ruby_vminsn_type = 61; -pub const YARVINSN_opt_nil_p: ruby_vminsn_type = 62; -pub const YARVINSN_opt_str_uminus: ruby_vminsn_type = 63; -pub const YARVINSN_opt_duparray_send: ruby_vminsn_type = 64; -pub const YARVINSN_opt_newarray_send: ruby_vminsn_type = 65; -pub const YARVINSN_invokesuper: ruby_vminsn_type = 66; -pub const YARVINSN_invokesuperforward: ruby_vminsn_type = 67; -pub const YARVINSN_invokeblock: ruby_vminsn_type = 68; -pub const YARVINSN_leave: ruby_vminsn_type = 69; -pub const YARVINSN_throw: ruby_vminsn_type = 70; -pub const YARVINSN_jump: ruby_vminsn_type = 71; -pub const YARVINSN_branchif: ruby_vminsn_type = 72; -pub const YARVINSN_branchunless: ruby_vminsn_type = 73; -pub const YARVINSN_branchnil: ruby_vminsn_type = 74; -pub const YARVINSN_once: ruby_vminsn_type = 75; -pub const YARVINSN_opt_case_dispatch: ruby_vminsn_type = 76; -pub const YARVINSN_opt_plus: ruby_vminsn_type = 77; -pub const YARVINSN_opt_minus: ruby_vminsn_type = 78; -pub const YARVINSN_opt_mult: ruby_vminsn_type = 79; -pub const YARVINSN_opt_div: ruby_vminsn_type = 80; -pub const YARVINSN_opt_mod: ruby_vminsn_type = 81; -pub const YARVINSN_opt_eq: ruby_vminsn_type = 82; -pub const YARVINSN_opt_neq: ruby_vminsn_type = 83; -pub const YARVINSN_opt_lt: ruby_vminsn_type = 84; -pub const YARVINSN_opt_le: ruby_vminsn_type = 85; -pub const YARVINSN_opt_gt: ruby_vminsn_type = 86; -pub const YARVINSN_opt_ge: ruby_vminsn_type = 87; -pub const YARVINSN_opt_ltlt: ruby_vminsn_type = 88; -pub const YARVINSN_opt_and: ruby_vminsn_type = 89; -pub const YARVINSN_opt_or: ruby_vminsn_type = 90; -pub const YARVINSN_opt_aref: ruby_vminsn_type = 91; -pub const YARVINSN_opt_aset: ruby_vminsn_type = 92; -pub const YARVINSN_opt_aset_with: ruby_vminsn_type = 93; -pub const YARVINSN_opt_aref_with: ruby_vminsn_type = 94; -pub const YARVINSN_opt_length: ruby_vminsn_type = 95; -pub const YARVINSN_opt_size: ruby_vminsn_type = 96; -pub const YARVINSN_opt_empty_p: ruby_vminsn_type = 97; -pub const YARVINSN_opt_succ: ruby_vminsn_type = 98; -pub const YARVINSN_opt_not: ruby_vminsn_type = 99; -pub const YARVINSN_opt_regexpmatch2: ruby_vminsn_type = 100; -pub const YARVINSN_invokebuiltin: ruby_vminsn_type = 101; -pub const YARVINSN_opt_invokebuiltin_delegate: ruby_vminsn_type = 102; -pub const YARVINSN_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 103; -pub const YARVINSN_getlocal_WC_0: ruby_vminsn_type = 104; -pub const YARVINSN_getlocal_WC_1: ruby_vminsn_type = 105; -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_zjit_opt_send_without_block: ruby_vminsn_type = 110; -pub const YARVINSN_zjit_opt_plus: ruby_vminsn_type = 111; -pub const YARVINSN_zjit_opt_minus: ruby_vminsn_type = 112; -pub const YARVINSN_zjit_opt_mult: ruby_vminsn_type = 113; -pub const YARVINSN_zjit_opt_div: ruby_vminsn_type = 114; -pub const YARVINSN_zjit_opt_mod: ruby_vminsn_type = 115; -pub const YARVINSN_zjit_opt_eq: ruby_vminsn_type = 116; -pub const YARVINSN_zjit_opt_neq: ruby_vminsn_type = 117; -pub const YARVINSN_zjit_opt_lt: ruby_vminsn_type = 118; -pub const YARVINSN_zjit_opt_le: ruby_vminsn_type = 119; -pub const YARVINSN_zjit_opt_gt: ruby_vminsn_type = 120; -pub const YARVINSN_zjit_opt_ge: ruby_vminsn_type = 121; -pub const YARVINSN_trace_nop: ruby_vminsn_type = 122; -pub const YARVINSN_trace_getlocal: ruby_vminsn_type = 123; -pub const YARVINSN_trace_setlocal: ruby_vminsn_type = 124; -pub const YARVINSN_trace_getblockparam: ruby_vminsn_type = 125; -pub const YARVINSN_trace_setblockparam: ruby_vminsn_type = 126; -pub const YARVINSN_trace_getblockparamproxy: ruby_vminsn_type = 127; -pub const YARVINSN_trace_getspecial: ruby_vminsn_type = 128; -pub const YARVINSN_trace_setspecial: ruby_vminsn_type = 129; -pub const YARVINSN_trace_getinstancevariable: ruby_vminsn_type = 130; -pub const YARVINSN_trace_setinstancevariable: ruby_vminsn_type = 131; -pub const YARVINSN_trace_getclassvariable: ruby_vminsn_type = 132; -pub const YARVINSN_trace_setclassvariable: ruby_vminsn_type = 133; -pub const YARVINSN_trace_opt_getconstant_path: ruby_vminsn_type = 134; -pub const YARVINSN_trace_getconstant: ruby_vminsn_type = 135; -pub const YARVINSN_trace_setconstant: ruby_vminsn_type = 136; -pub const YARVINSN_trace_getglobal: ruby_vminsn_type = 137; -pub const YARVINSN_trace_setglobal: ruby_vminsn_type = 138; -pub const YARVINSN_trace_putnil: ruby_vminsn_type = 139; -pub const YARVINSN_trace_putself: ruby_vminsn_type = 140; -pub const YARVINSN_trace_putobject: ruby_vminsn_type = 141; -pub const YARVINSN_trace_putspecialobject: ruby_vminsn_type = 142; -pub const YARVINSN_trace_putstring: ruby_vminsn_type = 143; -pub const YARVINSN_trace_putchilledstring: ruby_vminsn_type = 144; -pub const YARVINSN_trace_concatstrings: ruby_vminsn_type = 145; -pub const YARVINSN_trace_anytostring: ruby_vminsn_type = 146; -pub const YARVINSN_trace_toregexp: ruby_vminsn_type = 147; -pub const YARVINSN_trace_intern: ruby_vminsn_type = 148; -pub const YARVINSN_trace_newarray: ruby_vminsn_type = 149; -pub const YARVINSN_trace_pushtoarraykwsplat: ruby_vminsn_type = 150; -pub const YARVINSN_trace_duparray: ruby_vminsn_type = 151; -pub const YARVINSN_trace_duphash: ruby_vminsn_type = 152; -pub const YARVINSN_trace_expandarray: ruby_vminsn_type = 153; -pub const YARVINSN_trace_concatarray: ruby_vminsn_type = 154; -pub const YARVINSN_trace_concattoarray: ruby_vminsn_type = 155; -pub const YARVINSN_trace_pushtoarray: ruby_vminsn_type = 156; -pub const YARVINSN_trace_splatarray: ruby_vminsn_type = 157; -pub const YARVINSN_trace_splatkw: ruby_vminsn_type = 158; -pub const YARVINSN_trace_newhash: ruby_vminsn_type = 159; -pub const YARVINSN_trace_newrange: ruby_vminsn_type = 160; -pub const YARVINSN_trace_pop: ruby_vminsn_type = 161; -pub const YARVINSN_trace_dup: ruby_vminsn_type = 162; -pub const YARVINSN_trace_dupn: ruby_vminsn_type = 163; -pub const YARVINSN_trace_swap: ruby_vminsn_type = 164; -pub const YARVINSN_trace_opt_reverse: ruby_vminsn_type = 165; -pub const YARVINSN_trace_topn: ruby_vminsn_type = 166; -pub const YARVINSN_trace_setn: ruby_vminsn_type = 167; -pub const YARVINSN_trace_adjuststack: ruby_vminsn_type = 168; -pub const YARVINSN_trace_defined: ruby_vminsn_type = 169; -pub const YARVINSN_trace_definedivar: ruby_vminsn_type = 170; -pub const YARVINSN_trace_checkmatch: ruby_vminsn_type = 171; -pub const YARVINSN_trace_checkkeyword: ruby_vminsn_type = 172; -pub const YARVINSN_trace_checktype: ruby_vminsn_type = 173; -pub const YARVINSN_trace_defineclass: ruby_vminsn_type = 174; -pub const YARVINSN_trace_definemethod: ruby_vminsn_type = 175; -pub const YARVINSN_trace_definesmethod: ruby_vminsn_type = 176; -pub const YARVINSN_trace_send: ruby_vminsn_type = 177; -pub const YARVINSN_trace_sendforward: ruby_vminsn_type = 178; -pub const YARVINSN_trace_opt_send_without_block: ruby_vminsn_type = 179; -pub const YARVINSN_trace_objtostring: ruby_vminsn_type = 180; -pub const YARVINSN_trace_opt_ary_freeze: ruby_vminsn_type = 181; -pub const YARVINSN_trace_opt_hash_freeze: ruby_vminsn_type = 182; -pub const YARVINSN_trace_opt_str_freeze: ruby_vminsn_type = 183; -pub const YARVINSN_trace_opt_nil_p: ruby_vminsn_type = 184; -pub const YARVINSN_trace_opt_str_uminus: ruby_vminsn_type = 185; -pub const YARVINSN_trace_opt_duparray_send: ruby_vminsn_type = 186; -pub const YARVINSN_trace_opt_newarray_send: ruby_vminsn_type = 187; -pub const YARVINSN_trace_invokesuper: ruby_vminsn_type = 188; -pub const YARVINSN_trace_invokesuperforward: ruby_vminsn_type = 189; -pub const YARVINSN_trace_invokeblock: ruby_vminsn_type = 190; -pub const YARVINSN_trace_leave: ruby_vminsn_type = 191; -pub const YARVINSN_trace_throw: ruby_vminsn_type = 192; -pub const YARVINSN_trace_jump: ruby_vminsn_type = 193; -pub const YARVINSN_trace_branchif: ruby_vminsn_type = 194; -pub const YARVINSN_trace_branchunless: ruby_vminsn_type = 195; -pub const YARVINSN_trace_branchnil: ruby_vminsn_type = 196; -pub const YARVINSN_trace_once: ruby_vminsn_type = 197; -pub const YARVINSN_trace_opt_case_dispatch: ruby_vminsn_type = 198; -pub const YARVINSN_trace_opt_plus: ruby_vminsn_type = 199; -pub const YARVINSN_trace_opt_minus: ruby_vminsn_type = 200; -pub const YARVINSN_trace_opt_mult: ruby_vminsn_type = 201; -pub const YARVINSN_trace_opt_div: ruby_vminsn_type = 202; -pub const YARVINSN_trace_opt_mod: ruby_vminsn_type = 203; -pub const YARVINSN_trace_opt_eq: ruby_vminsn_type = 204; -pub const YARVINSN_trace_opt_neq: ruby_vminsn_type = 205; -pub const YARVINSN_trace_opt_lt: ruby_vminsn_type = 206; -pub const YARVINSN_trace_opt_le: ruby_vminsn_type = 207; -pub const YARVINSN_trace_opt_gt: ruby_vminsn_type = 208; -pub const YARVINSN_trace_opt_ge: ruby_vminsn_type = 209; -pub const YARVINSN_trace_opt_ltlt: ruby_vminsn_type = 210; -pub const YARVINSN_trace_opt_and: ruby_vminsn_type = 211; -pub const YARVINSN_trace_opt_or: ruby_vminsn_type = 212; -pub const YARVINSN_trace_opt_aref: ruby_vminsn_type = 213; -pub const YARVINSN_trace_opt_aset: ruby_vminsn_type = 214; -pub const YARVINSN_trace_opt_aset_with: ruby_vminsn_type = 215; -pub const YARVINSN_trace_opt_aref_with: ruby_vminsn_type = 216; -pub const YARVINSN_trace_opt_length: ruby_vminsn_type = 217; -pub const YARVINSN_trace_opt_size: ruby_vminsn_type = 218; -pub const YARVINSN_trace_opt_empty_p: ruby_vminsn_type = 219; -pub const YARVINSN_trace_opt_succ: ruby_vminsn_type = 220; -pub const YARVINSN_trace_opt_not: ruby_vminsn_type = 221; -pub const YARVINSN_trace_opt_regexpmatch2: ruby_vminsn_type = 222; -pub const YARVINSN_trace_invokebuiltin: ruby_vminsn_type = 223; -pub const YARVINSN_trace_opt_invokebuiltin_delegate: ruby_vminsn_type = 224; -pub const YARVINSN_trace_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 225; -pub const YARVINSN_trace_getlocal_WC_0: ruby_vminsn_type = 226; -pub const YARVINSN_trace_getlocal_WC_1: ruby_vminsn_type = 227; -pub const YARVINSN_trace_setlocal_WC_0: ruby_vminsn_type = 228; -pub const YARVINSN_trace_setlocal_WC_1: ruby_vminsn_type = 229; -pub const YARVINSN_trace_putobject_INT2FIX_0_: ruby_vminsn_type = 230; -pub const YARVINSN_trace_putobject_INT2FIX_1_: ruby_vminsn_type = 231; -pub const YARVINSN_trace_zjit_opt_send_without_block: ruby_vminsn_type = 232; -pub const YARVINSN_trace_zjit_opt_plus: ruby_vminsn_type = 233; -pub const YARVINSN_trace_zjit_opt_minus: ruby_vminsn_type = 234; -pub const YARVINSN_trace_zjit_opt_mult: ruby_vminsn_type = 235; -pub const YARVINSN_trace_zjit_opt_div: ruby_vminsn_type = 236; -pub const YARVINSN_trace_zjit_opt_mod: ruby_vminsn_type = 237; -pub const YARVINSN_trace_zjit_opt_eq: ruby_vminsn_type = 238; -pub const YARVINSN_trace_zjit_opt_neq: ruby_vminsn_type = 239; -pub const YARVINSN_trace_zjit_opt_lt: ruby_vminsn_type = 240; -pub const YARVINSN_trace_zjit_opt_le: ruby_vminsn_type = 241; -pub const YARVINSN_trace_zjit_opt_gt: ruby_vminsn_type = 242; -pub const YARVINSN_trace_zjit_opt_ge: ruby_vminsn_type = 243; -pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 244; +pub const YARVINSN_opt_new: ruby_vminsn_type = 58; +pub const YARVINSN_objtostring: ruby_vminsn_type = 59; +pub const YARVINSN_opt_ary_freeze: ruby_vminsn_type = 60; +pub const YARVINSN_opt_hash_freeze: ruby_vminsn_type = 61; +pub const YARVINSN_opt_str_freeze: ruby_vminsn_type = 62; +pub const YARVINSN_opt_nil_p: ruby_vminsn_type = 63; +pub const YARVINSN_opt_str_uminus: ruby_vminsn_type = 64; +pub const YARVINSN_opt_duparray_send: ruby_vminsn_type = 65; +pub const YARVINSN_opt_newarray_send: ruby_vminsn_type = 66; +pub const YARVINSN_invokesuper: ruby_vminsn_type = 67; +pub const YARVINSN_invokesuperforward: ruby_vminsn_type = 68; +pub const YARVINSN_invokeblock: ruby_vminsn_type = 69; +pub const YARVINSN_leave: ruby_vminsn_type = 70; +pub const YARVINSN_throw: ruby_vminsn_type = 71; +pub const YARVINSN_jump: ruby_vminsn_type = 72; +pub const YARVINSN_branchif: ruby_vminsn_type = 73; +pub const YARVINSN_branchunless: ruby_vminsn_type = 74; +pub const YARVINSN_branchnil: ruby_vminsn_type = 75; +pub const YARVINSN_once: ruby_vminsn_type = 76; +pub const YARVINSN_opt_case_dispatch: ruby_vminsn_type = 77; +pub const YARVINSN_opt_plus: ruby_vminsn_type = 78; +pub const YARVINSN_opt_minus: ruby_vminsn_type = 79; +pub const YARVINSN_opt_mult: ruby_vminsn_type = 80; +pub const YARVINSN_opt_div: ruby_vminsn_type = 81; +pub const YARVINSN_opt_mod: ruby_vminsn_type = 82; +pub const YARVINSN_opt_eq: ruby_vminsn_type = 83; +pub const YARVINSN_opt_neq: ruby_vminsn_type = 84; +pub const YARVINSN_opt_lt: ruby_vminsn_type = 85; +pub const YARVINSN_opt_le: ruby_vminsn_type = 86; +pub const YARVINSN_opt_gt: ruby_vminsn_type = 87; +pub const YARVINSN_opt_ge: ruby_vminsn_type = 88; +pub const YARVINSN_opt_ltlt: ruby_vminsn_type = 89; +pub const YARVINSN_opt_and: ruby_vminsn_type = 90; +pub const YARVINSN_opt_or: ruby_vminsn_type = 91; +pub const YARVINSN_opt_aref: ruby_vminsn_type = 92; +pub const YARVINSN_opt_aset: ruby_vminsn_type = 93; +pub const YARVINSN_opt_aset_with: ruby_vminsn_type = 94; +pub const YARVINSN_opt_aref_with: ruby_vminsn_type = 95; +pub const YARVINSN_opt_length: ruby_vminsn_type = 96; +pub const YARVINSN_opt_size: ruby_vminsn_type = 97; +pub const YARVINSN_opt_empty_p: ruby_vminsn_type = 98; +pub const YARVINSN_opt_succ: ruby_vminsn_type = 99; +pub const YARVINSN_opt_not: ruby_vminsn_type = 100; +pub const YARVINSN_opt_regexpmatch2: ruby_vminsn_type = 101; +pub const YARVINSN_invokebuiltin: ruby_vminsn_type = 102; +pub const YARVINSN_opt_invokebuiltin_delegate: ruby_vminsn_type = 103; +pub const YARVINSN_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 104; +pub const YARVINSN_getlocal_WC_0: ruby_vminsn_type = 105; +pub const YARVINSN_getlocal_WC_1: ruby_vminsn_type = 106; +pub const YARVINSN_setlocal_WC_0: ruby_vminsn_type = 107; +pub const YARVINSN_setlocal_WC_1: ruby_vminsn_type = 108; +pub const YARVINSN_putobject_INT2FIX_0_: ruby_vminsn_type = 109; +pub const YARVINSN_putobject_INT2FIX_1_: ruby_vminsn_type = 110; +pub const YARVINSN_zjit_opt_send_without_block: ruby_vminsn_type = 111; +pub const YARVINSN_zjit_opt_plus: ruby_vminsn_type = 112; +pub const YARVINSN_zjit_opt_minus: ruby_vminsn_type = 113; +pub const YARVINSN_zjit_opt_mult: ruby_vminsn_type = 114; +pub const YARVINSN_zjit_opt_div: ruby_vminsn_type = 115; +pub const YARVINSN_zjit_opt_mod: ruby_vminsn_type = 116; +pub const YARVINSN_zjit_opt_eq: ruby_vminsn_type = 117; +pub const YARVINSN_zjit_opt_neq: ruby_vminsn_type = 118; +pub const YARVINSN_zjit_opt_lt: ruby_vminsn_type = 119; +pub const YARVINSN_zjit_opt_le: ruby_vminsn_type = 120; +pub const YARVINSN_zjit_opt_gt: ruby_vminsn_type = 121; +pub const YARVINSN_zjit_opt_ge: ruby_vminsn_type = 122; +pub const YARVINSN_trace_nop: ruby_vminsn_type = 123; +pub const YARVINSN_trace_getlocal: ruby_vminsn_type = 124; +pub const YARVINSN_trace_setlocal: ruby_vminsn_type = 125; +pub const YARVINSN_trace_getblockparam: ruby_vminsn_type = 126; +pub const YARVINSN_trace_setblockparam: ruby_vminsn_type = 127; +pub const YARVINSN_trace_getblockparamproxy: ruby_vminsn_type = 128; +pub const YARVINSN_trace_getspecial: ruby_vminsn_type = 129; +pub const YARVINSN_trace_setspecial: ruby_vminsn_type = 130; +pub const YARVINSN_trace_getinstancevariable: ruby_vminsn_type = 131; +pub const YARVINSN_trace_setinstancevariable: ruby_vminsn_type = 132; +pub const YARVINSN_trace_getclassvariable: ruby_vminsn_type = 133; +pub const YARVINSN_trace_setclassvariable: ruby_vminsn_type = 134; +pub const YARVINSN_trace_opt_getconstant_path: ruby_vminsn_type = 135; +pub const YARVINSN_trace_getconstant: ruby_vminsn_type = 136; +pub const YARVINSN_trace_setconstant: ruby_vminsn_type = 137; +pub const YARVINSN_trace_getglobal: ruby_vminsn_type = 138; +pub const YARVINSN_trace_setglobal: ruby_vminsn_type = 139; +pub const YARVINSN_trace_putnil: ruby_vminsn_type = 140; +pub const YARVINSN_trace_putself: ruby_vminsn_type = 141; +pub const YARVINSN_trace_putobject: ruby_vminsn_type = 142; +pub const YARVINSN_trace_putspecialobject: ruby_vminsn_type = 143; +pub const YARVINSN_trace_putstring: ruby_vminsn_type = 144; +pub const YARVINSN_trace_putchilledstring: ruby_vminsn_type = 145; +pub const YARVINSN_trace_concatstrings: ruby_vminsn_type = 146; +pub const YARVINSN_trace_anytostring: ruby_vminsn_type = 147; +pub const YARVINSN_trace_toregexp: ruby_vminsn_type = 148; +pub const YARVINSN_trace_intern: ruby_vminsn_type = 149; +pub const YARVINSN_trace_newarray: ruby_vminsn_type = 150; +pub const YARVINSN_trace_pushtoarraykwsplat: ruby_vminsn_type = 151; +pub const YARVINSN_trace_duparray: ruby_vminsn_type = 152; +pub const YARVINSN_trace_duphash: ruby_vminsn_type = 153; +pub const YARVINSN_trace_expandarray: ruby_vminsn_type = 154; +pub const YARVINSN_trace_concatarray: ruby_vminsn_type = 155; +pub const YARVINSN_trace_concattoarray: ruby_vminsn_type = 156; +pub const YARVINSN_trace_pushtoarray: ruby_vminsn_type = 157; +pub const YARVINSN_trace_splatarray: ruby_vminsn_type = 158; +pub const YARVINSN_trace_splatkw: ruby_vminsn_type = 159; +pub const YARVINSN_trace_newhash: ruby_vminsn_type = 160; +pub const YARVINSN_trace_newrange: ruby_vminsn_type = 161; +pub const YARVINSN_trace_pop: ruby_vminsn_type = 162; +pub const YARVINSN_trace_dup: ruby_vminsn_type = 163; +pub const YARVINSN_trace_dupn: ruby_vminsn_type = 164; +pub const YARVINSN_trace_swap: ruby_vminsn_type = 165; +pub const YARVINSN_trace_opt_reverse: ruby_vminsn_type = 166; +pub const YARVINSN_trace_topn: ruby_vminsn_type = 167; +pub const YARVINSN_trace_setn: ruby_vminsn_type = 168; +pub const YARVINSN_trace_adjuststack: ruby_vminsn_type = 169; +pub const YARVINSN_trace_defined: ruby_vminsn_type = 170; +pub const YARVINSN_trace_definedivar: ruby_vminsn_type = 171; +pub const YARVINSN_trace_checkmatch: ruby_vminsn_type = 172; +pub const YARVINSN_trace_checkkeyword: ruby_vminsn_type = 173; +pub const YARVINSN_trace_checktype: ruby_vminsn_type = 174; +pub const YARVINSN_trace_defineclass: ruby_vminsn_type = 175; +pub const YARVINSN_trace_definemethod: ruby_vminsn_type = 176; +pub const YARVINSN_trace_definesmethod: ruby_vminsn_type = 177; +pub const YARVINSN_trace_send: ruby_vminsn_type = 178; +pub const YARVINSN_trace_sendforward: ruby_vminsn_type = 179; +pub const YARVINSN_trace_opt_send_without_block: ruby_vminsn_type = 180; +pub const YARVINSN_trace_opt_new: ruby_vminsn_type = 181; +pub const YARVINSN_trace_objtostring: ruby_vminsn_type = 182; +pub const YARVINSN_trace_opt_ary_freeze: ruby_vminsn_type = 183; +pub const YARVINSN_trace_opt_hash_freeze: ruby_vminsn_type = 184; +pub const YARVINSN_trace_opt_str_freeze: ruby_vminsn_type = 185; +pub const YARVINSN_trace_opt_nil_p: ruby_vminsn_type = 186; +pub const YARVINSN_trace_opt_str_uminus: ruby_vminsn_type = 187; +pub const YARVINSN_trace_opt_duparray_send: ruby_vminsn_type = 188; +pub const YARVINSN_trace_opt_newarray_send: ruby_vminsn_type = 189; +pub const YARVINSN_trace_invokesuper: ruby_vminsn_type = 190; +pub const YARVINSN_trace_invokesuperforward: ruby_vminsn_type = 191; +pub const YARVINSN_trace_invokeblock: ruby_vminsn_type = 192; +pub const YARVINSN_trace_leave: ruby_vminsn_type = 193; +pub const YARVINSN_trace_throw: ruby_vminsn_type = 194; +pub const YARVINSN_trace_jump: ruby_vminsn_type = 195; +pub const YARVINSN_trace_branchif: ruby_vminsn_type = 196; +pub const YARVINSN_trace_branchunless: ruby_vminsn_type = 197; +pub const YARVINSN_trace_branchnil: ruby_vminsn_type = 198; +pub const YARVINSN_trace_once: ruby_vminsn_type = 199; +pub const YARVINSN_trace_opt_case_dispatch: ruby_vminsn_type = 200; +pub const YARVINSN_trace_opt_plus: ruby_vminsn_type = 201; +pub const YARVINSN_trace_opt_minus: ruby_vminsn_type = 202; +pub const YARVINSN_trace_opt_mult: ruby_vminsn_type = 203; +pub const YARVINSN_trace_opt_div: ruby_vminsn_type = 204; +pub const YARVINSN_trace_opt_mod: ruby_vminsn_type = 205; +pub const YARVINSN_trace_opt_eq: ruby_vminsn_type = 206; +pub const YARVINSN_trace_opt_neq: ruby_vminsn_type = 207; +pub const YARVINSN_trace_opt_lt: ruby_vminsn_type = 208; +pub const YARVINSN_trace_opt_le: ruby_vminsn_type = 209; +pub const YARVINSN_trace_opt_gt: ruby_vminsn_type = 210; +pub const YARVINSN_trace_opt_ge: ruby_vminsn_type = 211; +pub const YARVINSN_trace_opt_ltlt: ruby_vminsn_type = 212; +pub const YARVINSN_trace_opt_and: ruby_vminsn_type = 213; +pub const YARVINSN_trace_opt_or: ruby_vminsn_type = 214; +pub const YARVINSN_trace_opt_aref: ruby_vminsn_type = 215; +pub const YARVINSN_trace_opt_aset: ruby_vminsn_type = 216; +pub const YARVINSN_trace_opt_aset_with: ruby_vminsn_type = 217; +pub const YARVINSN_trace_opt_aref_with: ruby_vminsn_type = 218; +pub const YARVINSN_trace_opt_length: ruby_vminsn_type = 219; +pub const YARVINSN_trace_opt_size: ruby_vminsn_type = 220; +pub const YARVINSN_trace_opt_empty_p: ruby_vminsn_type = 221; +pub const YARVINSN_trace_opt_succ: ruby_vminsn_type = 222; +pub const YARVINSN_trace_opt_not: ruby_vminsn_type = 223; +pub const YARVINSN_trace_opt_regexpmatch2: ruby_vminsn_type = 224; +pub const YARVINSN_trace_invokebuiltin: ruby_vminsn_type = 225; +pub const YARVINSN_trace_opt_invokebuiltin_delegate: ruby_vminsn_type = 226; +pub const YARVINSN_trace_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 227; +pub const YARVINSN_trace_getlocal_WC_0: ruby_vminsn_type = 228; +pub const YARVINSN_trace_getlocal_WC_1: ruby_vminsn_type = 229; +pub const YARVINSN_trace_setlocal_WC_0: ruby_vminsn_type = 230; +pub const YARVINSN_trace_setlocal_WC_1: ruby_vminsn_type = 231; +pub const YARVINSN_trace_putobject_INT2FIX_0_: ruby_vminsn_type = 232; +pub const YARVINSN_trace_putobject_INT2FIX_1_: ruby_vminsn_type = 233; +pub const YARVINSN_trace_zjit_opt_send_without_block: ruby_vminsn_type = 234; +pub const YARVINSN_trace_zjit_opt_plus: ruby_vminsn_type = 235; +pub const YARVINSN_trace_zjit_opt_minus: ruby_vminsn_type = 236; +pub const YARVINSN_trace_zjit_opt_mult: ruby_vminsn_type = 237; +pub const YARVINSN_trace_zjit_opt_div: ruby_vminsn_type = 238; +pub const YARVINSN_trace_zjit_opt_mod: ruby_vminsn_type = 239; +pub const YARVINSN_trace_zjit_opt_eq: ruby_vminsn_type = 240; +pub const YARVINSN_trace_zjit_opt_neq: ruby_vminsn_type = 241; +pub const YARVINSN_trace_zjit_opt_lt: ruby_vminsn_type = 242; +pub const YARVINSN_trace_zjit_opt_le: ruby_vminsn_type = 243; +pub const YARVINSN_trace_zjit_opt_gt: ruby_vminsn_type = 244; +pub const YARVINSN_trace_zjit_opt_ge: ruby_vminsn_type = 245; +pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 246; 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),