Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added b/a
Empty file.
12 changes: 12 additions & 0 deletions compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -2213,11 +2213,17 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
struct rb_kwarg_call_data *cd_kw = &kw_calls[ISEQ_COMPILE_DATA(iseq)->ci_kw_index++];
cd_kw->ci_kw = *((struct rb_call_info_with_kwarg *)source_ci);
cd = (struct rb_call_data *)cd_kw;
cd->cc.orig_argc = cd->ci.orig_argc;
cd->cc.flag = cd->ci.flag;
cd->cc.mid = cd->ci.mid;
assert(ISEQ_COMPILE_DATA(iseq)->ci_kw_index <= body->ci_kw_size);
}
else {
cd = &body->call_data[ISEQ_COMPILE_DATA(iseq)->ci_index++];
cd->ci = *source_ci;
cd->cc.orig_argc = cd->ci.orig_argc;
cd->cc.flag = cd->ci.flag;
cd->cc.mid = cd->ci.mid;
assert(ISEQ_COMPILE_DATA(iseq)->ci_index <= body->ci_size);
}

Expand Down Expand Up @@ -10320,6 +10326,9 @@ ibf_load_ci_entries(const struct ibf_load *load,
calls[i].ci.mid = ibf_load_id(load, mid_index);
calls[i].ci.flag = (unsigned int)ibf_load_small_value(load, &reading_pos);
calls[i].ci.orig_argc = (int)ibf_load_small_value(load, &reading_pos);
calls[i].cc.flag = calls[i].ci.flag;
calls[i].cc.orig_argc = calls[i].ci.orig_argc;
calls[i].cc.mid = calls[i].ci.mid;
}

for (i = 0; i < ci_kw_size; i++) {
Expand All @@ -10328,6 +10337,9 @@ ibf_load_ci_entries(const struct ibf_load *load,
kw_calls[i].ci_kw.ci.mid = ibf_load_id(load, mid_index);
kw_calls[i].ci_kw.ci.flag = (unsigned int)ibf_load_small_value(load, &reading_pos);
kw_calls[i].ci_kw.ci.orig_argc = (int)ibf_load_small_value(load, &reading_pos);
kw_calls[i].cc.flag = kw_calls[i].ci_kw.ci.flag;
kw_calls[i].cc.orig_argc = kw_calls[i].ci_kw.ci.orig_argc;
kw_calls[i].cc.mid = kw_calls[i].ci_kw.ci.mid;

int keyword_len = (int)ibf_load_small_value(load, &reading_pos);

Expand Down
4 changes: 2 additions & 2 deletions insns.def
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ send
// attr rb_snum_t sp_inc = sp_inc_of_sendish(&cd->ci);
// attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci);
{
VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), &cd->ci, blockiseq, false);
VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), &cd->cc, blockiseq, false);
val = vm_sendish(ec, GET_CFP(), cd, bh, vm_search_method_wrap);

if (val == Qundef) {
Expand Down Expand Up @@ -884,7 +884,7 @@ invokesuper
// attr rb_snum_t sp_inc = sp_inc_of_sendish(&cd->ci);
// attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci);
{
VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), &cd->ci, blockiseq, true);
VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), &cd->cc, blockiseq, true);
val = vm_sendish(ec, GET_CFP(), cd, bh, vm_search_super_method);

if (val == Qundef) {
Expand Down
12 changes: 7 additions & 5 deletions internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -2341,7 +2341,7 @@ struct rb_call_cache {
(CACHELINE
- sizeof(rb_serial_t) /* method_state */
- sizeof(struct rb_callable_method_entry_struct *) /* me */
- sizeof(struct rb_callable_method_definition_struct *) /* def */
- sizeof(ID) /* mid */
- sizeof(enum method_missing_reason) /* aux */
- sizeof(VALUE (*)( /* call */
struct rb_execution_context_struct *e,
Expand All @@ -2353,13 +2353,15 @@ struct rb_call_cache {

/* inline cache: values */
const struct rb_callable_method_entry_struct *me;
const struct rb_method_definition_struct *def;
ID mid;

VALUE (*call)(struct rb_execution_context_struct *ec,
struct rb_control_frame_struct *cfp,
struct rb_calling_info *calling,
struct rb_call_data *cd);

/* cache call info argc and flags in the 4 byte cache line padding */
unsigned short int orig_argc;
unsigned short int flag;
union {
unsigned int index; /* used by ivar */
enum method_missing_reason method_missing_reason; /* used by method_missing */
Expand All @@ -2369,8 +2371,8 @@ STATIC_ASSERT(cachelined, sizeof(struct rb_call_cache) <= CACHELINE);
struct rb_call_info {
/* fixed at compile time */
ID mid;
unsigned int flag;
int orig_argc;
unsigned short int flag;
unsigned short int orig_argc;
};
struct rb_call_data {
struct rb_call_cache cc;
Expand Down
2 changes: 1 addition & 1 deletion mjit_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ fastpath_applied_iseq_p(const CALL_INFO ci, const CALL_CACHE cc, const rb_iseq_t
return iseq != NULL
&& !(ci->flag & VM_CALL_KW_SPLAT) && rb_simple_iseq_p(iseq) // Top of vm_callee_setup_arg. In this case, opt_pc is 0.
&& ci->orig_argc == iseq->body->param.lead_num // exclude argument_arity_error (assumption: `calling->argc == ci->orig_argc` in send insns)
&& vm_call_iseq_optimizable_p(ci, cc); // CC_SET_FASTPATH condition
&& vm_call_iseq_optimizable_p(cc); // CC_SET_FASTPATH condition
}

static int
Expand Down
2 changes: 1 addition & 1 deletion tool/ruby_vm/views/_mjit_compile_send.erb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
fprintf(f, " {\n");
fprintf(f, " struct rb_calling_info calling;\n");
% if insn.name == 'send'
fprintf(f, " calling.block_handler = vm_caller_setup_arg_block(ec, reg_cfp, (CALL_INFO)0x%"PRIxVALUE", (rb_iseq_t *)0x%"PRIxVALUE", FALSE);\n", (VALUE)ci, (VALUE)blockiseq);
fprintf(f, " calling.block_handler = vm_caller_setup_arg_block(ec, reg_cfp, (CALL_CACHE)0x%"PRIxVALUE", (rb_iseq_t *)0x%"PRIxVALUE", FALSE);\n", (VALUE)cc_copy, (VALUE)blockiseq);
% else
fprintf(f, " calling.block_handler = VM_BLOCK_HANDLER_NONE;\n");
% end
Expand Down
4 changes: 2 additions & 2 deletions vm_args.c
Original file line number Diff line number Diff line change
Expand Up @@ -1191,9 +1191,9 @@ refine_sym_proc_call(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg))

static VALUE
vm_caller_setup_arg_block(const rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
const struct rb_call_info *ci, const rb_iseq_t *blockiseq, const int is_super)
const struct rb_call_cache *cc, const rb_iseq_t *blockiseq, const int is_super)
{
if (ci->flag & VM_CALL_ARGS_BLOCKARG) {
if (cc->flag & VM_CALL_ARGS_BLOCKARG) {
VALUE block_code = *(--reg_cfp->sp);

if (NIL_P(block_code)) {
Expand Down
6 changes: 4 additions & 2 deletions vm_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,8 @@ struct rb_call_info_with_kwarg {
struct rb_calling_info {
VALUE block_handler;
VALUE recv;
int argc;
int kw_splat;
short int argc;
short int kw_splat;
};

struct rb_kwarg_call_data {
Expand Down Expand Up @@ -1095,6 +1095,7 @@ enum vm_call_flag_bits {
VM_CALL_SUPER_bit, /* super */
VM_CALL_ZSUPER_bit, /* zsuper */
VM_CALL_OPT_SEND_bit, /* internal flag */
VM_CALL_UNREFINED_bit, /* refined */
VM_CALL__END
};

Expand All @@ -1110,6 +1111,7 @@ enum vm_call_flag_bits {
#define VM_CALL_SUPER (0x01 << VM_CALL_SUPER_bit)
#define VM_CALL_ZSUPER (0x01 << VM_CALL_ZSUPER_bit)
#define VM_CALL_OPT_SEND (0x01 << VM_CALL_OPT_SEND_bit)
#define VM_CALL_UNREFINED (0x01 << VM_CALL_UNREFINED_bit)

enum vm_special_object_type {
VM_SPECIAL_OBJECT_VMCORE = 1,
Expand Down
23 changes: 11 additions & 12 deletions vm_eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,24 @@ rb_vm_call0(rb_execution_context_t *ec, VALUE recv, ID id, int argc, const VALUE
{
struct rb_calling_info calling = { Qundef, recv, argc, kw_splat, };
struct rb_call_info ci = { id, (kw_splat ? VM_CALL_KW_SPLAT : 0), argc, };
struct rb_call_cache cc = { 0, { 0, }, me, me->def, vm_call_general, { 0, }, };
struct rb_call_cache cc = { 0, { 0, }, me, id, vm_call_general, argc, ci.flag, { 0, }, };
struct rb_call_data cd = { cc, ci, };
cc.flag = ci.flag;
if (LIKELY(me->def->type != VM_METHOD_TYPE_REFINED)) cc.flag |= VM_CALL_UNREFINED;
return vm_call0_body(ec, &calling, &cd, argv);
}

static VALUE
vm_call0_cfunc_with_frame(rb_execution_context_t* ec, struct rb_calling_info *calling, struct rb_call_data *cd, const VALUE *argv)
{
const struct rb_call_info *ci = &cd->ci;
const struct rb_call_cache *cc = &cd->cc;
VALUE val;
const rb_callable_method_entry_t *me = cc->me;
const rb_method_cfunc_t *cfunc = UNALIGNED_MEMBER_PTR(me->def, body.cfunc);
int len = cfunc->argc;
VALUE recv = calling->recv;
int argc = calling->argc;
ID mid = ci->mid;
ID mid = cc->mid;
VALUE block_handler = calling->block_handler;
int frame_flags = VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL;

Expand Down Expand Up @@ -109,7 +110,6 @@ vm_call0_cfunc(rb_execution_context_t *ec, struct rb_calling_info *calling, stru
static VALUE
vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, struct rb_call_data *cd, const VALUE *argv)
{
const struct rb_call_info *ci = &cd->ci;
struct rb_call_cache *cc = &cd->cc;

VALUE ret;
Expand Down Expand Up @@ -180,15 +180,15 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, struc
}
else if (cc->me->def->body.refined.orig_me) {
cc->me = refined_method_callable_without_refinement(cc->me);
goto again;
goto again;
}

super_class = RCLASS_SUPER(super_class);

if (!super_class || !(cc->me = rb_callable_method_entry(super_class, ci->mid))) {
enum method_missing_reason ex = (type == VM_METHOD_TYPE_ZSUPER) ? MISSING_SUPER : 0;
ret = method_missing(calling->recv, ci->mid, calling->argc, argv, ex, calling->kw_splat);
goto success;
if (!super_class || !(cc->me = rb_callable_method_entry(super_class, cc->mid))) {
enum method_missing_reason ex = (type == VM_METHOD_TYPE_ZSUPER) ? MISSING_SUPER : 0;
ret = method_missing(calling->recv, cc->mid, calling->argc, argv, ex, calling->kw_splat);
goto success;
}
RUBY_VM_CHECK_INTS(ec);
goto again;
Expand All @@ -199,7 +199,7 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, struc
case VM_METHOD_TYPE_MISSING:
{
vm_passed_block_handler_set(ec, calling->block_handler);
return method_missing(calling->recv, ci->mid, calling->argc,
return method_missing(calling->recv, cc->mid, calling->argc,
argv, MISSING_NOENTRY, calling->kw_splat);
}
case VM_METHOD_TYPE_OPTIMIZED:
Expand Down Expand Up @@ -1006,10 +1006,9 @@ rb_funcallv_public_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_sp
VALUE
rb_funcallv_with_cc(struct rb_call_data *cd, VALUE recv, ID mid, int argc, const VALUE *argv)
{
const struct rb_call_info *ci = &cd->ci;
struct rb_call_cache *cc = &cd->cc;

if (LIKELY(ci->mid == mid)) {
if (LIKELY(cc->mid == mid)) {
vm_search_method(cd, recv);

if (LIKELY(! UNDEFINED_METHOD_ENTRY_P(cc->me))) {
Expand Down
Loading