Skip to content

Commit 9bfbf20

Browse files
authored
Merge pull request ruby#131 from Shopify/yjit-callfunc
Use `jit_func` as YJIT's entry point
2 parents f82e359 + c718de0 commit 9bfbf20

22 files changed

Lines changed: 171 additions & 431 deletions

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,3 @@ lcov*.info
228228
/rb_mjit_header.h
229229
/mjit_config.h
230230
/include/ruby-*/*/rb_mjit_min_header-*.h
231-
232-
# YJIT
233-
/yjit_hooks.inc

bootstraptest/test_yjit.rb

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,56 @@
1+
# Check that global tracepoints work
2+
assert_equal 'true', %q{
3+
def foo
4+
1
5+
end
6+
7+
foo
8+
foo
9+
foo
10+
11+
called = false
12+
13+
tp = TracePoint.new(:return) { |event|
14+
if event.method_id == :foo
15+
called = true
16+
end
17+
}
18+
tp.enable
19+
foo
20+
tp.disable
21+
called
22+
}
23+
24+
# Check that local tracepoints work
25+
assert_equal 'true', %q{
26+
def foo
27+
1
28+
end
29+
30+
foo
31+
foo
32+
foo
33+
34+
called = false
35+
36+
tp = TracePoint.new(:return) { |_| called = true }
37+
tp.enable(target: method(:foo))
38+
foo
39+
tp.disable
40+
called
41+
}
42+
43+
# Make sure that optional param methods return the correct value
44+
assert_equal '1', %q{
45+
def m(ary = [])
46+
yield(ary)
47+
end
48+
49+
# Warm the JIT with a 0 param call
50+
2.times { m { } }
51+
m(1) { |v| v }
52+
}
53+
154
# Test for topn
255
assert_equal 'array', %q{
356
def threequals(a)

common.mk

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,8 +1087,6 @@ incs: $(INSNS) {$(VPATH)}node_name.inc {$(VPATH)}known_errors.inc \
10871087

10881088
insns: $(INSNS)
10891089

1090-
yjit_hooks.inc: vm.$(OBJEXT)
1091-
10921090
id.h: $(tooldir)/generic_erb.rb $(srcdir)/template/id.h.tmpl $(srcdir)/defs/id.def
10931091
$(ECHO) generating $@
10941092
$(Q) $(BASERUBY) $(tooldir)/generic_erb.rb --output=$@ \
@@ -16810,7 +16808,6 @@ yjit_compile.$(OBJEXT): {$(VPATH)}vm_sync.h
1681016808
yjit_compile.$(OBJEXT): {$(VPATH)}yjit.h
1681116809
yjit_compile.$(OBJEXT): {$(VPATH)}yjit_asm.h
1681216810
yjit_compile.$(OBJEXT): {$(VPATH)}yjit_compile.c
16813-
yjit_compile.$(OBJEXT): {$(VPATH)}yjit_hooks.inc
1681416811
yjit_compile.$(OBJEXT): {$(VPATH)}yjit_utils.h
1681516812
yjit_core.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
1681616813
yjit_core.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
@@ -17206,7 +17203,6 @@ yjit_iface.$(OBJEXT): {$(VPATH)}yjit.rbinc
1720617203
yjit_iface.$(OBJEXT): {$(VPATH)}yjit_asm.h
1720717204
yjit_iface.$(OBJEXT): {$(VPATH)}yjit_codegen.h
1720817205
yjit_iface.$(OBJEXT): {$(VPATH)}yjit_core.h
17209-
yjit_iface.$(OBJEXT): {$(VPATH)}yjit_hooks.inc
1721017206
yjit_iface.$(OBJEXT): {$(VPATH)}yjit_iface.c
1721117207
yjit_iface.$(OBJEXT): {$(VPATH)}yjit_iface.h
1721217208
yjit_utils.$(OBJEXT): {$(VPATH)}yjit_asm.h

iseq.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3278,6 +3278,8 @@ rb_iseq_trace_flag_cleared(const rb_iseq_t *iseq, size_t pos)
32783278
encoded_iseq_trace_instrument(&iseq_encoded[pos], 0, false);
32793279
}
32803280

3281+
typedef VALUE (*jit_func_t)(struct rb_execution_context_struct *, struct rb_control_frame_struct *);
3282+
32813283
static int
32823284
iseq_add_local_tracepoint(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VALUE tpval, unsigned int target_line)
32833285
{
@@ -3288,6 +3290,11 @@ iseq_add_local_tracepoint(const rb_iseq_t *iseq, rb_event_flag_t turnon_events,
32883290

32893291
VM_ASSERT(ISEQ_EXECUTABLE_P(iseq));
32903292

3293+
#if USE_MJIT
3294+
// Force write the jit function to NULL
3295+
*((jit_func_t *)(&body->jit_func)) = 0;
3296+
#endif
3297+
32913298
for (pc=0; pc<body->iseq_size;) {
32923299
const struct iseq_insn_info_entry *entry = get_insn_info(iseq, pc);
32933300
rb_event_flag_t pc_events = entry->events;
@@ -3423,6 +3430,10 @@ rb_iseq_trace_set(const rb_iseq_t *iseq, rb_event_flag_t turnon_events)
34233430
rb_event_flag_t pc_events = rb_iseq_event_flags(iseq, pc);
34243431
pc += encoded_iseq_trace_instrument(&iseq_encoded[pc], pc_events & enabled_events, true);
34253432
}
3433+
#if USE_MJIT
3434+
// Force write the jit function to NULL
3435+
*((jit_func_t *)(&body->jit_func)) = 0;
3436+
#endif
34263437
}
34273438
}
34283439

mjit.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,17 +149,27 @@ mjit_exec(rb_execution_context_t *ec)
149149

150150
#ifndef MJIT_HEADER
151151
if (rb_yjit_enabled_p() && !mjit_call_p && body->total_calls == rb_yjit_call_threshold()) {
152-
rb_yjit_compile_iseq(iseq, ec);
153-
return Qundef;
152+
// If we couldn't generate any code for this iseq, then return
153+
// Qundef so the interpreter will handle the call.
154+
if (!rb_yjit_compile_iseq(iseq, ec)) {
155+
return Qundef;
156+
}
154157
}
155158
#endif
156159

157-
if (!mjit_call_p)
160+
if (!(mjit_call_p || rb_yjit_enabled_p()))
158161
return Qundef;
159162

160163
RB_DEBUG_COUNTER_INC(mjit_exec);
161164

162165
mjit_func_t func = body->jit_func;
166+
167+
// YJIT tried compiling this function once before and couldn't do
168+
// it, so return Qundef so the interpreter handles it.
169+
if (rb_yjit_enabled_p() && func == 0) {
170+
return Qundef;
171+
}
172+
163173
if (UNLIKELY((uintptr_t)func <= LAST_JIT_ISEQ_FUNC)) {
164174
# ifdef MJIT_HEADER
165175
RB_DEBUG_COUNTER_INC(mjit_frame_JT2VM);
@@ -175,6 +185,8 @@ mjit_exec(rb_execution_context_t *ec)
175185
RB_DEBUG_COUNTER_INC(mjit_frame_VM2JT);
176186
# endif
177187
RB_DEBUG_COUNTER_INC(mjit_exec_call_func);
188+
// ec -> RDI
189+
// cfp -> RSI
178190
return func(ec, ec->cfp);
179191
}
180192

template/Makefile.in

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ update-known-errors:
577577
$(IFCHANGE) $(srcdir)/defs/known_errors.def -
578578

579579
INSNS = opt_sc.inc optinsn.inc optunifs.inc insns.inc insns_info.inc \
580-
vmtc.inc vm.inc mjit_compile.inc yjit_hooks.inc
580+
vmtc.inc vm.inc mjit_compile.inc
581581

582582
$(INSNS): $(srcdir)/insns.def vm_opts.h \
583583
$(srcdir)/defs/opt_operand.def $(srcdir)/defs/opt_insn_unif.def \
@@ -597,8 +597,6 @@ $(INSNS): $(srcdir)/insns.def vm_opts.h \
597597
$(tooldir)/ruby_vm/models/instructions_unifications.rb \
598598
$(tooldir)/ruby_vm/models/operands_unifications.rb \
599599
$(tooldir)/ruby_vm/models/trace_instructions.rb \
600-
$(tooldir)/ruby_vm/models/yjit.rb \
601-
$(tooldir)/ruby_vm/models/yjit/example_instructions.rb \
602600
$(tooldir)/ruby_vm/models/typemap.rb \
603601
$(tooldir)/ruby_vm/scripts/converter.rb \
604602
$(tooldir)/ruby_vm/scripts/insns2vm.rb \

test/lib/jit_support.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def eval_with_jit_without_retry(env = nil, script, verbose: 0, min_calls: 5, sav
3939
'--disable-gems', "--jit-verbose=#{verbose}",
4040
"--jit-min-calls=#{min_calls}", "--jit-max-cache=#{max_cache}",
4141
]
42+
args << '--disable-yjit'
4243
args << '--jit-wait' if wait
4344
args << '--jit-save-temps' if save_temps
4445
args << '--jit-debug' if defined?(@jit_debug) && @jit_debug

tool/ruby_vm/models/instructions.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,10 @@
1313
require_relative 'bare_instructions'
1414
require_relative 'operands_unifications'
1515
require_relative 'instructions_unifications'
16-
require_relative 'yjit'
1716

1817
RubyVM::Instructions = RubyVM::BareInstructions.to_a + \
1918
RubyVM::OperandsUnifications.to_a + \
20-
RubyVM::InstructionsUnifications.to_a + \
21-
RubyVM::YJIT::ExampleInstructions.to_a
19+
RubyVM::InstructionsUnifications.to_a
2220

2321

2422
require_relative 'trace_instructions'

0 commit comments

Comments
 (0)