mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
7d0144e055
for leaf_without_check_ints insns.
$ benchmark-driver -v --rbenv 'before --jit;after --jit' --repeat-count=12 --alternate --output=all benchmark.yml
before --jit: ruby 3.0.0dev (2020-12-20T05:02:18Z master 02b3555874
) +JIT [x86_64-linux]
after --jit: ruby 3.0.0dev (2020-12-20T05:36:00Z master 3f58de4eab) +JIT [x86_64-linux]
last_commit=Check mjit_call_p only when interrupted
Calculating -------------------------------------
before --jit after --jit
Optcarrot Lan_Master.nes 84.50647332260259 85.85057800433144 fps
91.17796644338372 92.09930605656054
91.29346683444497 93.01336611323687
91.50322318568884 93.07234029037433
91.66560903214686 93.22773241529644
91.82315142636172 93.37032901061119
92.15066379608260 93.83701526141679
92.37897097456643 93.86032792681507
92.53049815524908 93.91211970920320
92.78414507914283 94.09109196967890
92.90299756525958 94.40107239595325
93.70279428858790 95.01326369371263
92 lines
3.8 KiB
Text
92 lines
3.8 KiB
Text
% # -*- C -*-
|
|
% # Copyright (c) 2018 Takashi Kokubun. All rights reserved.
|
|
% #
|
|
% # This file is a part of the programming language Ruby. Permission is hereby
|
|
% # granted, to either redistribute and/or modify this file, provided that the
|
|
% # conditions mentioned in the file COPYING are met. Consult the file for
|
|
% # details.
|
|
fprintf(f, "{\n");
|
|
{
|
|
% # compiler: Prepare operands which may be used by `insn.call_attribute`
|
|
% insn.opes.each_with_index do |ope, i|
|
|
MAYBE_UNUSED(<%= ope.fetch(:decl) %>) = (<%= ope.fetch(:type) %>)operands[<%= i %>];
|
|
% end
|
|
%
|
|
% # JIT: Declare stack_size to be used in some macro of _mjit_compile_insn_body.erb
|
|
if (status->local_stack_p) {
|
|
fprintf(f, " MAYBE_UNUSED(unsigned int) stack_size = %u;\n", b->stack_size);
|
|
}
|
|
%
|
|
% # JIT: Declare variables for operands, popped values and return values
|
|
% insn.declarations.each do |decl|
|
|
fprintf(f, " <%= decl %>;\n");
|
|
% end
|
|
|
|
% # JIT: Set const expressions for `RubyVM::OperandsUnifications` insn
|
|
% insn.preamble.each do |amble|
|
|
fprintf(f, "<%= amble.expr.sub(/const \S+\s+/, '') %>\n");
|
|
% end
|
|
%
|
|
% # JIT: Initialize operands
|
|
% insn.opes.each_with_index do |ope, i|
|
|
fprintf(f, " <%= ope.fetch(:name) %> = (<%= ope.fetch(:type) %>)0x%"PRIxVALUE";", operands[<%= i %>]);
|
|
% case ope.fetch(:type)
|
|
% when 'ID'
|
|
comment_id(f, (ID)operands[<%= i %>]);
|
|
% when 'CALL_DATA'
|
|
comment_id(f, vm_ci_mid(((CALL_DATA)operands[<%= i %>])->ci));
|
|
% when 'VALUE'
|
|
if (SYMBOL_P((VALUE)operands[<%= i %>])) comment_id(f, SYM2ID((VALUE)operands[<%= i %>]));
|
|
% end
|
|
fprintf(f, "\n");
|
|
% end
|
|
%
|
|
% # JIT: Initialize popped values
|
|
% insn.pops.reverse_each.with_index.reverse_each do |pop, i|
|
|
fprintf(f, " <%= pop.fetch(:name) %> = stack[%d];\n", b->stack_size - <%= i + 1 %>);
|
|
% end
|
|
%
|
|
% # JIT: move sp and pc if necessary
|
|
<%= render 'mjit_compile_pc_and_sp', locals: { insn: insn } -%>
|
|
%
|
|
% # JIT: Print insn body in insns.def
|
|
<%= render 'mjit_compile_insn_body', locals: { insn: insn } -%>
|
|
%
|
|
% # JIT: Set return values
|
|
% insn.rets.reverse_each.with_index do |ret, i|
|
|
% # TOPN(n) = ...
|
|
fprintf(f, " stack[%d] = <%= ret.fetch(:name) %>;\n", b->stack_size + (int)<%= insn.call_attribute('sp_inc') %> - <%= i + 1 %>);
|
|
% end
|
|
%
|
|
% # JIT: We should evaluate ISeq modified for TracePoint if it's enabled. Note: This is slow.
|
|
% # leaf insn may not cancel JIT. leaf_without_check_ints is covered in RUBY_VM_CHECK_INTS of _mjit_compile_insn_body.erb.
|
|
% unless insn.always_leaf? || insn.leaf_without_check_ints?
|
|
fprintf(f, " if (UNLIKELY(!mjit_call_p)) {\n");
|
|
fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size + (int)<%= insn.call_attribute('sp_inc') %>);
|
|
if (!pc_moved_p) {
|
|
fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", next_pos);
|
|
}
|
|
fprintf(f, " RB_DEBUG_COUNTER_INC(mjit_cancel_invalidate_all);\n");
|
|
fprintf(f, " goto cancel;\n");
|
|
fprintf(f, " }\n");
|
|
% end
|
|
%
|
|
% # compiler: Move JIT compiler's internal stack pointer
|
|
b->stack_size += <%= insn.call_attribute('sp_inc') %>;
|
|
}
|
|
fprintf(f, "}\n");
|
|
%
|
|
% # compiler: If insn has conditional JUMP, the code should go to the branch not targeted by JUMP next.
|
|
% if insn.expr.expr =~ /if\s+\([^{}]+\)\s+\{[^{}]+JUMP\([^)]+\);[^{}]+\}/
|
|
if (ALREADY_COMPILED_P(status, pos + insn_len(insn))) {
|
|
fprintf(f, "goto label_%d;\n", pos + insn_len(insn));
|
|
}
|
|
else {
|
|
compile_insns(f, body, b->stack_size, pos + insn_len(insn), status);
|
|
}
|
|
% end
|
|
%
|
|
% # compiler: If insn returns (leave) or does longjmp (throw), the branch should no longer be compiled. TODO: create attr for it?
|
|
% if insn.expr.expr =~ /\sTHROW_EXCEPTION\([^)]+\);/ || insn.expr.expr =~ /\bvm_pop_frame\(/
|
|
b->finish_p = TRUE;
|
|
% end
|