Skip to content

Commit 862ddf9

Browse files
authored
Check for easy-to-handle cases of block param (#24)
In some cases, methods taking block parameters don't require extra paramter setup. They are fairly popular in railsbench.
1 parent 10fbb61 commit 862ddf9

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

bootstraptest/test_yjit.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,3 +869,27 @@ def use(array, initial)
869869
use([], 0)
870870
[use([2, 2], 38), use([14, 14, 14], 0)]
871871
}
872+
873+
# test calling method taking block param
874+
assert_equal '[Proc, 1, 2, 3, Proc]', %q{
875+
def three(a, b, c, &block)
876+
[a, b, c, block.class]
877+
end
878+
879+
def zero(&block)
880+
block.class
881+
end
882+
883+
def use_three
884+
three(1, 2, 3) {}
885+
end
886+
887+
def use_zero
888+
zero {}
889+
end
890+
891+
use_three
892+
use_zero
893+
894+
[use_zero] + use_three
895+
}

yjit_codegen.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,7 +1891,22 @@ gen_return_branch(codeblock_t* cb, uint8_t* target0, uint8_t* target1, uint8_t s
18911891
}
18921892
}
18931893

1894-
bool rb_simple_iseq_p(const rb_iseq_t *iseq);
1894+
// Returns whether the iseq only needs positional (lead) argument setup.
1895+
static bool
1896+
iseq_lead_only_arg_setup_p(const rb_iseq_t *iseq)
1897+
{
1898+
// When iseq->body->local_iseq == iseq, setup_parameters_complex()
1899+
// doesn't do anything to setup the block parameter.
1900+
bool takes_block = iseq->body->param.flags.has_block;
1901+
return (!takes_block || iseq->body->local_iseq == iseq) &&
1902+
iseq->body->param.flags.has_opt == false &&
1903+
iseq->body->param.flags.has_rest == false &&
1904+
iseq->body->param.flags.has_post == false &&
1905+
iseq->body->param.flags.has_kw == false &&
1906+
iseq->body->param.flags.has_kwrest == false &&
1907+
iseq->body->param.flags.accepts_no_kwarg == false;
1908+
}
1909+
18951910
bool rb_iseq_only_optparam_p(const rb_iseq_t *iseq);
18961911
bool rb_iseq_only_kwparam_p(const rb_iseq_t *iseq);
18971912

@@ -1909,7 +1924,9 @@ gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r
19091924
// Arity handling and optional parameter setup
19101925
int num_params = iseq->body->param.size;
19111926
uint32_t start_pc_offset = 0;
1912-
if (rb_simple_iseq_p(iseq)) {
1927+
if (iseq_lead_only_arg_setup_p(iseq)) {
1928+
num_params = iseq->body->param.lead_num;
1929+
19131930
if (num_params != argc) {
19141931
GEN_COUNTER_INC(cb, send_iseq_arity_error);
19151932
return YJIT_CANT_COMPILE;

0 commit comments

Comments
 (0)