summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compile.c4
-rw-r--r--iseq.c55
-rw-r--r--rjit_c.rb1
-rw-r--r--vm_callinfo.h26
-rw-r--r--vm_core.h2
-rw-r--r--vm_insnhelper.c30
-rw-r--r--vm_trace.c10
-rw-r--r--yjit/src/cruby_bindings.inc.rs1
8 files changed, 114 insertions, 15 deletions
@@ -3646,6 +3646,10 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
if (IS_TRACE(iobj->link.next)) {
if (IS_NEXT_INSN_ID(iobj->link.next, leave)) {
iobj->insn_id = BIN(opt_invokebuiltin_delegate_leave);
}
}
}
@@ -3550,9 +3550,32 @@ rb_iseq_trace_set(const rb_iseq_t *iseq, rb_event_flag_t turnon_events)
}
}
-bool rb_vm_call_ivar_attrset_p(const vm_call_handler ch);
void rb_vm_cc_general(const struct rb_callcache *cc);
static int
clear_attr_ccs_i(void *vstart, void *vend, size_t stride, void *data)
{
@@ -3560,11 +3583,7 @@ clear_attr_ccs_i(void *vstart, void *vend, size_t stride, void *data)
for (; v != (VALUE)vend; v += stride) {
void *ptr = asan_poisoned_object_p(v);
asan_unpoison_object(v, false);
-
- if (imemo_type_p(v, imemo_callcache) && rb_vm_call_ivar_attrset_p(((const struct rb_callcache *)v)->call_)) {
- rb_vm_cc_general((struct rb_callcache *)v);
- }
-
asan_poison_object_if(ptr, v);
}
return 0;
@@ -3577,6 +3596,25 @@ rb_clear_attr_ccs(void)
}
static int
trace_set_i(void *vstart, void *vend, size_t stride, void *data)
{
rb_event_flag_t turnon_events = *(rb_event_flag_t *)data;
@@ -3589,8 +3627,9 @@ trace_set_i(void *vstart, void *vend, size_t stride, void *data)
if (rb_obj_is_iseq(v)) {
rb_iseq_trace_set(rb_iseq_check((rb_iseq_t *)v), turnon_events);
}
- else if (imemo_type_p(v, imemo_callcache) && rb_vm_call_ivar_attrset_p(((const struct rb_callcache *)v)->call_)) {
- rb_vm_cc_general((struct rb_callcache *)v);
}
asan_poison_object_if(ptr, v);
@@ -952,6 +952,7 @@ module RubyVM::RJIT # :nodoc: all
),
method_missing_reason: self.method_missing_reason,
v: self.VALUE,
), Primitive.cexpr!("OFFSETOF((*((struct rb_callcache *)NULL)), aux_)")],
)
end
@@ -290,6 +290,7 @@ struct rb_callcache {
} attr;
const enum method_missing_reason method_missing_reason; /* used by method_missing */
VALUE v;
} aux_;
};
@@ -439,6 +440,9 @@ vm_cc_valid_p(const struct rb_callcache *cc, const rb_callable_method_entry_t *c
/* callcache: mutate */
static inline void
vm_cc_call_set(const struct rb_callcache *cc, vm_call_handler call)
{
@@ -458,6 +462,13 @@ vm_cc_attr_index_set(const struct rb_callcache *cc, attr_index_t index, shape_id
VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
VM_ASSERT(cc != vm_cc_empty());
*attr_value = (attr_index_t)(index + 1) | ((uintptr_t)(dest_shape_id) << SHAPE_FLAG_SHIFT);
}
static inline void
@@ -481,6 +492,21 @@ vm_cc_method_missing_reason_set(const struct rb_callcache *cc, enum method_missi
}
static inline void
vm_cc_invalidate(const struct rb_callcache *cc)
{
VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
@@ -371,6 +371,8 @@ enum rb_builtin_attr {
BUILTIN_ATTR_LEAF = 0x01,
// The iseq does not allocate objects.
BUILTIN_ATTR_NO_GC = 0x02,
};
typedef VALUE (*rb_jit_func_t)(struct rb_execution_context_struct *, struct rb_control_frame_struct *);
@@ -2789,6 +2789,17 @@ vm_call_iseq_setup_kwparm_nokwarg(rb_execution_context_t *ec, rb_control_frame_t
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(cc), 0, param, local);
}
static inline int
vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling,
const rb_iseq_t *iseq, VALUE *argv, int param_size, int local_size)
@@ -2808,7 +2819,18 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling,
VM_ASSERT(ci == calling->ci);
VM_ASSERT(cc == calling->cc);
- CC_SET_FASTPATH(cc, vm_call_iseq_setup_func(ci, param_size, local_size), cacheable_ci && vm_call_iseq_optimizable_p(ci, cc));
return 0;
}
else if (rb_iseq_only_optparam_p(iseq)) {
@@ -3507,12 +3529,6 @@ vm_call_attrset(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_c
return vm_call_attrset_direct(ec, cfp, calling->cc, calling->recv);
}
-bool
-rb_vm_call_ivar_attrset_p(const vm_call_handler ch)
-{
- return (ch == vm_call_ivar || ch == vm_call_attrset);
-}
-
static inline VALUE
vm_call_bmethod_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const VALUE *argv)
{
@@ -93,6 +93,7 @@ rb_hook_list_free(rb_hook_list_t *hooks)
/* ruby_vm_event_flags management */
void rb_clear_attr_ccs(void);
static void
update_global_event_hook(rb_event_flag_t prev_events, rb_event_flag_t new_events)
@@ -102,6 +103,8 @@ update_global_event_hook(rb_event_flag_t prev_events, rb_event_flag_t new_events
bool first_time_iseq_events_p = new_iseq_events & ~enabled_iseq_events;
bool enable_c_call = (prev_events & RUBY_EVENT_C_CALL) == 0 && (new_events & RUBY_EVENT_C_CALL);
bool enable_c_return = (prev_events & RUBY_EVENT_C_RETURN) == 0 && (new_events & RUBY_EVENT_C_RETURN);
// Modify ISEQs or CCs to enable tracing
if (first_time_iseq_events_p) {
@@ -112,6 +115,9 @@ update_global_event_hook(rb_event_flag_t prev_events, rb_event_flag_t new_events
else if (enable_c_call || enable_c_return) {
rb_clear_attr_ccs();
}
ruby_vm_event_flags = new_events;
ruby_vm_event_enabled_global_flags |= new_events;
@@ -1258,6 +1264,10 @@ rb_tracepoint_enable_for_target(VALUE tpval, VALUE target, VALUE target_line)
n += rb_iseq_add_local_tracepoint_recursively(iseq, tp->events, tpval, line, target_bmethod);
rb_hash_aset(tp->local_target_set, (VALUE)iseq, Qtrue);
if (n == 0) {
rb_raise(rb_eArgError, "can not enable any hooks");
@@ -664,6 +664,7 @@ pub struct iseq_inline_cvar_cache_entry {
}
pub const BUILTIN_ATTR_LEAF: rb_builtin_attr = 1;
pub const BUILTIN_ATTR_NO_GC: rb_builtin_attr = 2;
pub type rb_builtin_attr = u32;
#[repr(C)]
#[derive(Debug, Copy, Clone)]