Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -13080,7 +13080,8 @@ inline_iseqs(VALUE *code, size_t pos, iseq_value_itr_t * func, void *_ctx, rb_vm
const struct rb_iseq_constant_body *const body = callee_iseq->body;

// Is the cache still valid?
ADD_INSN1(code_list_root, &dummy_line_node, jump_if_cache_miss, cd);
LABEL * cache_miss_label = NEW_LABEL(0);
ADD_INSN2(code_list_root, &dummy_line_node, jump_if_cache_miss, cd, cache_miss_label);

size_t size = body->iseq_size;
VALUE * callee_code = body->iseq_encoded;
Expand Down Expand Up @@ -13109,6 +13110,10 @@ inline_iseqs(VALUE *code, size_t pos, iseq_value_itr_t * func, void *_ctx, rb_vm
n += inline_iseqs(callee_code, n, NULL, _ctx, translator);
}

ADD_LABEL(code_list_root, cache_miss_label);
iseq->body->ci_size++;
ADD_INSN1(code_list_root, &dummy_line_node, opt_send_without_block, cd->ci);

ADD_LABEL(code_list_root, leave_label);

st_free_table(ctx->labels);
Expand Down Expand Up @@ -13311,6 +13316,8 @@ rb_inline_callee_iseqs(const rb_iseq_t * original_iseq)
}

fprintf(stderr, "original size: %d new size %d\n", original_iseq->body->local_table_size, info.max_locals);
iseq->body->original_iseq = original_iseq;
RB_OBJ_WRITTEN(iseq, Qundef, original_iseq);

CHECK(iseq_setup_insn(iseq, code_list_root));
iseq_setup(iseq, code_list_root);
Expand All @@ -13333,4 +13340,3 @@ rb_inline_callee_iseqs(const rb_iseq_t * original_iseq)

return iseq;
}

10 changes: 5 additions & 5 deletions insns.def
Original file line number Diff line number Diff line change
Expand Up @@ -786,24 +786,24 @@ opt_send_without_block
/* Invoke method without block */
DEFINE_INSN
jump_if_cache_miss
(CALL_DATA cd)
(CALL_DATA cd, OFFSET dst)
()
()
{
VALUE recv = TOPN(vm_ci_argc(cd->ci));

if (LIKELY(vm_cc_class_check(cd->cc, CLASS_OF(recv)))) {
if (LIKELY(!METHOD_ENTRY_INVALIDATED(vm_cc_cme(cd->cc)))) {
RB_DEBUG_COUNTER_INC(mc_inline_hit);
fprintf(stderr, "hit!\n");
}
else {
rb_bug("guard miss 1!\n");
rb_bug("guard miss 1!\n");
JUMP(dst);
}
}
else {
rb_bug("guard miss 2!\n");
printf("cache miss!\n");
RB_DEBUG_COUNTER_INC(mc_inline_miss_klass);
JUMP(dst);
}
}

Expand Down
4 changes: 3 additions & 1 deletion iseq.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,9 @@ rb_iseq_mark(const rb_iseq_t *iseq)
if (FL_TEST((VALUE)iseq, ISEQ_MARKABLE_ISEQ)) {
rb_iseq_each_value(iseq, each_insn_value, NULL);
}

if (body->param.flags.inlined_iseq) {
rb_gc_mark(body->original_iseq);
}
rb_gc_mark_movable(body->variable.coverage);
rb_gc_mark_movable(body->variable.pc2branchindex);
rb_gc_mark_movable(body->variable.script_lines);
Expand Down
68 changes: 68 additions & 0 deletions test/inlining/test_inlining.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# frozen_string_literal: false
require 'test/unit'

class TestInlining < Test::Unit::TestCase
def foo(a); a + 1; end
def bar; foo(9); end

def test_enable_inlining
reader, writer = IO.pipe
Process.waitpid fork {
reader.close
RubyVM.enable_inlining!

3.times do
bar
end

disasm = RubyVM::InstructionSequence.disasm(method(:bar))
writer.write(Marshal.dump(disasm))
}

writer.close
disasm = Marshal.load(reader.read)

expected_disasm = <<~HEREDOC
0000 putself
0001 putobject 9
0003 jump_if_cache_miss <calldata!mid:foo, argc:1, FCALL|ARGS_SIMPLE>, 16
0006 setlocal_WC_0 ?@0
0008 pop
0009 getlocal_WC_0 ?@0
0011 putobject_INT2FIX_1_
0012 opt_plus <calldata!mid:+, argc:1, ARGS_SIMPLE>
0014 jump 18
0016 opt_send_without_block <calldata!mid:foo, argc:1, FCALL|ARGS_SIMPLE>
0018 leave
HEREDOC

assert_match(expected_disasm, disasm)
end

def test_disable_inlining
reader, writer = IO.pipe
Process.waitpid fork {
reader.close
RubyVM.disable_inlining!

3.times do
bar
end

disasm = RubyVM::InstructionSequence.disasm(method(:bar))
writer.write(Marshal.dump(disasm))
}

writer.close
disasm = Marshal.load(reader.read)

expected_disasm = <<~HEREDOC
0000 putself ( 6)[LiCa]
0001 putobject 9
0003 opt_send_without_block <calldata!mid:foo, argc:1, FCALL|ARGS_SIMPLE>
0005 leave [Re]
HEREDOC

assert_match(expected_disasm, disasm)
end
end
16 changes: 16 additions & 0 deletions test3.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class A
def foo
self.class
end
end

def bar(a)
a.foo
end

a = A.new
p bar(a)
bar(a)

puts RubyVM::InstructionSequence.disasm(method(:bar))
p bar(a)
1 change: 1 addition & 0 deletions vm_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ struct rb_iseq_constant_body {
#endif

rb_yjit_block_array_array_t yjit_blocks; // empty, or has a size equal to iseq_size
rb_iseq_t *original_iseq;
};

/* T_IMEMO/iseq */
Expand Down