summaryrefslogtreecommitdiff
path: root/tool/ruby_vm/views/mjit_compile.inc.erb
diff options
context:
space:
mode:
Diffstat (limited to 'tool/ruby_vm/views/mjit_compile.inc.erb')
-rw-r--r--tool/ruby_vm/views/mjit_compile.inc.erb17
1 files changed, 16 insertions, 1 deletions
diff --git a/tool/ruby_vm/views/mjit_compile.inc.erb b/tool/ruby_vm/views/mjit_compile.inc.erb
index 0d3678dfb5..fa2e52e480 100644
--- a/tool/ruby_vm/views/mjit_compile.inc.erb
+++ b/tool/ruby_vm/views/mjit_compile.inc.erb
@@ -63,12 +63,26 @@ switch (insn) {
}
% when 'getinstancevariable', 'setinstancevariable'
<%= render 'mjit_compile_ivar', locals: { insn: insn } -%>
-% when 'leave'
+% when 'leave', 'opt_invokebuiltin_delegate_leave'
+ {
+% # opt_invokebuiltin_delegate_leave also implements leave insn. We need to handle it here for inlining.
+% if insn.name == 'opt_invokebuiltin_delegate_leave'
+ RB_BUILTIN bf = (RB_BUILTIN)operands[0];
+ rb_num_t index = (rb_num_t)operands[0];
+ fprintf(f, "{\n");
+ fprintf(f, " VALUE val;\n");
+ fprintf(f, " RB_BUILTIN bf = (RB_BUILTIN)0x%"PRIxVALUE";\n", operands[0]);
+ fprintf(f, " rb_num_t index = (rb_num_t)0x%"PRIxVALUE";\n", operands[1]);
+ fprintf(f, <%= rstring2cstr(insn.expr.expr.lines.find { |l| l =~ / vm_invoke_builtin_delegate\(/ }).gsub("\n", '\n') %>);
+ fprintf(f, " stack[0] = val;\n");
+ fprintf(f, "}\n");
+% else
if (b->stack_size != 1) {
if (mjit_opts.warnings || mjit_opts.verbose)
fprintf(stderr, "MJIT warning: Unexpected JIT stack_size on leave: %d\n", b->stack_size);
status->success = false;
}
+% end
% # Skip vm_pop_frame for inlined call
if (status->inlined_iseqs != NULL) { // the current ISeq is NOT being inlined
% # Cancel on interrupts to make leave insn leaf
@@ -84,6 +98,7 @@ switch (insn) {
b->stack_size += <%= insn.call_attribute('sp_inc') %>;
b->finish_p = TRUE;
break;
+ }
% end
%
% # Main insn implementation generated by insns.def