mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
Introduce a specialize instruction for Array#pack
Instructions for this code: ```ruby # frozen_string_literal: true [a].pack("C") ``` Before this commit: ``` == disasm: #<ISeq:<main>@test.rb:1 (1,0)-(3,13)> 0000 putself ( 3)[Li] 0001 opt_send_without_block <calldata!mid:a, argc:0, FCALL|VCALL|ARGS_SIMPLE> 0003 newarray 1 0005 putobject "C" 0007 opt_send_without_block <calldata!mid:pack, argc:1, ARGS_SIMPLE> 0009 leave ``` After this commit: ``` == disasm: #<ISeq:<main>@test.rb:1 (1,0)-(3,13)> 0000 putself ( 3)[Li] 0001 opt_send_without_block <calldata!mid:a, argc:0, FCALL|VCALL|ARGS_SIMPLE> 0003 putobject "C" 0005 opt_newarray_send 2, :pack 0008 leave ``` Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
This commit is contained in:
parent
e5e079e70f
commit
49fcd33e13
15 changed files with 132 additions and 5 deletions
29
compile.c
29
compile.c
|
@ -4048,6 +4048,8 @@ insn_set_specialized_instruction(rb_iseq_t *iseq, INSN *iobj, int insn_id)
|
|||
return COMPILE_OK;
|
||||
}
|
||||
|
||||
#define vm_ci_simple(ci) (vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE)
|
||||
|
||||
static int
|
||||
iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
|
||||
{
|
||||
|
@ -4059,24 +4061,43 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
|
|||
INSN *niobj = (INSN *)iobj->link.next;
|
||||
if (IS_INSN_ID(niobj, send)) {
|
||||
const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(niobj, 0);
|
||||
if ((vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE) && vm_ci_argc(ci) == 0) {
|
||||
if (vm_ci_simple(ci) && vm_ci_argc(ci) == 0) {
|
||||
switch (vm_ci_mid(ci)) {
|
||||
case idMax:
|
||||
case idMin:
|
||||
case idHash:
|
||||
{
|
||||
VALUE num = iobj->operands[0];
|
||||
int operand_len = insn_len(BIN(opt_newarray_send)) - 1;
|
||||
iobj->insn_id = BIN(opt_newarray_send);
|
||||
iobj->operands = compile_data_calloc2(iseq, insn_len(iobj->insn_id) - 1, sizeof(VALUE));
|
||||
iobj->operands = compile_data_calloc2(iseq, operand_len, sizeof(VALUE));
|
||||
iobj->operands[0] = num;
|
||||
iobj->operands[1] = rb_id2sym(vm_ci_mid(ci));
|
||||
iobj->operand_size = insn_len(iobj->insn_id) - 1;
|
||||
iobj->operand_size = operand_len;
|
||||
ELEM_REMOVE(&niobj->link);
|
||||
return COMPILE_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((IS_INSN_ID(niobj, putstring) ||
|
||||
(IS_INSN_ID(niobj, putobject) && RB_TYPE_P(OPERAND_AT(niobj, 0), T_STRING))) &&
|
||||
IS_NEXT_INSN_ID(&niobj->link, send)) {
|
||||
const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT((INSN *)niobj->link.next, 0);
|
||||
if (vm_ci_simple(ci) && vm_ci_argc(ci) == 1 && vm_ci_mid(ci) == idPack) {
|
||||
VALUE num = iobj->operands[0];
|
||||
int operand_len = insn_len(BIN(opt_newarray_send)) - 1;
|
||||
iobj->insn_id = BIN(opt_newarray_send);
|
||||
iobj->operands = compile_data_calloc2(iseq, operand_len, sizeof(VALUE));
|
||||
iobj->operands[0] = FIXNUM_INC(num, 1);
|
||||
iobj->operands[1] = rb_id2sym(vm_ci_mid(ci));
|
||||
iobj->operand_size = operand_len;
|
||||
ELEM_REMOVE(&iobj->link);
|
||||
ELEM_REMOVE(niobj->link.next);
|
||||
ELEM_INSERT_NEXT(&niobj->link, &iobj->link);
|
||||
return COMPILE_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_INSN_ID(iobj, send)) {
|
||||
|
@ -4084,7 +4105,7 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
|
|||
const rb_iseq_t *blockiseq = (rb_iseq_t *)OPERAND_AT(iobj, 1);
|
||||
|
||||
#define SP_INSN(opt) insn_set_specialized_instruction(iseq, iobj, BIN(opt_##opt))
|
||||
if (vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE) {
|
||||
if (vm_ci_simple(ci)) {
|
||||
switch (vm_ci_argc(ci)) {
|
||||
case 0:
|
||||
switch (vm_ci_mid(ci)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue