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.erb20
1 files changed, 13 insertions, 7 deletions
diff --git a/tool/ruby_vm/views/mjit_compile.inc.erb b/tool/ruby_vm/views/mjit_compile.inc.erb
index 77dd7f442b..f6d52d692e 100644
--- a/tool/ruby_vm/views/mjit_compile.inc.erb
+++ b/tool/ruby_vm/views/mjit_compile.inc.erb
@@ -50,16 +50,22 @@ switch (insn) {
% case insn.name
% when 'opt_send_without_block', 'send'
<%= render 'mjit_compile_send', locals: { insn: insn } -%>
-% when 'opt_aref' # experimental. TODO: increase insns and make the list automatically by finding DISPATCH_ORIGINAL_INSN
-<%= render 'mjit_compile_send', locals: { insn: opt_send_without_block } -%>
+% when 'opt_aref', 'opt_aset', 'opt_mod' # TODO: automatically find them with CALL_SIMPLE_METHOD
+% # To avoid cancel, just emit `opt_send_without_block` instead of `opt_*` insn if call cache is populated.
+% cc_index = insn.opes.index { |o| o.fetch(:type) == 'CALL_CACHE' }
+ if (has_valid_method_type(status->cc_entries + ((CALL_CACHE)operands[<%= cc_index %>] - body->cc_entries))) {
+<%= render 'mjit_compile_send', locals: { insn: opt_send_without_block } -%>
+<%= render 'mjit_compile_insn', locals: { insn: opt_send_without_block } -%>
+ break;
+ }
% when 'getinstancevariable', 'setinstancevariable'
<%= render 'mjit_compile_ivar', locals: { insn: insn } -%>
% when 'leave'
- 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;
- }
+ 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
%
% # Main insn implementation generated by insns.def