1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Allow method caching of protected FCALLs

This commit is contained in:
John Hawthorn 2022-03-11 11:48:02 -08:00
parent a580dd7737
commit 9312f4bf62
Notes: git 2022-06-22 10:34:16 +09:00
3 changed files with 11 additions and 7 deletions

View file

@ -75,7 +75,6 @@ typedef struct rb_callable_method_entry_struct { /* same fields with rb_method_e
#define METHOD_ENTRY_CACHED_SET(me) ((me)->flags |= IMEMO_FL_USER4) #define METHOD_ENTRY_CACHED_SET(me) ((me)->flags |= IMEMO_FL_USER4)
#define METHOD_ENTRY_INVALIDATED(me) ((me)->flags & IMEMO_FL_USER5) #define METHOD_ENTRY_INVALIDATED(me) ((me)->flags & IMEMO_FL_USER5)
#define METHOD_ENTRY_INVALIDATED_SET(me) ((me)->flags |= IMEMO_FL_USER5) #define METHOD_ENTRY_INVALIDATED_SET(me) ((me)->flags |= IMEMO_FL_USER5)
#define METHOD_ENTRY_CACHEABLE(me) !(METHOD_ENTRY_VISI(me) == METHOD_VISI_PROTECTED)
static inline void static inline void
METHOD_ENTRY_VISI_SET(rb_method_entry_t *me, rb_method_visibility_t visi) METHOD_ENTRY_VISI_SET(rb_method_entry_t *me, rb_method_visibility_t visi)

View file

@ -2534,12 +2534,12 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling,
if (LIKELY(!(vm_ci_flag(ci) & VM_CALL_TAILCALL))) { if (LIKELY(!(vm_ci_flag(ci) & VM_CALL_TAILCALL))) {
CC_SET_FASTPATH(cc, vm_call_iseq_setup_normal_opt_start, CC_SET_FASTPATH(cc, vm_call_iseq_setup_normal_opt_start,
!IS_ARGS_SPLAT(ci) && !IS_ARGS_KEYWORD(ci) && !IS_ARGS_SPLAT(ci) && !IS_ARGS_KEYWORD(ci) &&
cacheable_ci && METHOD_ENTRY_CACHEABLE(vm_cc_cme(cc))); cacheable_ci && vm_call_cacheable(ci, cc));
} }
else { else {
CC_SET_FASTPATH(cc, vm_call_iseq_setup_tailcall_opt_start, CC_SET_FASTPATH(cc, vm_call_iseq_setup_tailcall_opt_start,
!IS_ARGS_SPLAT(ci) && !IS_ARGS_KEYWORD(ci) && !IS_ARGS_SPLAT(ci) && !IS_ARGS_KEYWORD(ci) &&
cacheable_ci && METHOD_ENTRY_CACHEABLE(vm_cc_cme(cc))); cacheable_ci && vm_call_cacheable(ci, cc));
} }
/* initialize opt vars for self-references */ /* initialize opt vars for self-references */
@ -2567,7 +2567,7 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling,
args_setup_kw_parameters(ec, iseq, ci_kws, ci_kw_len, ci_keywords, klocals); args_setup_kw_parameters(ec, iseq, ci_kws, ci_kw_len, ci_keywords, klocals);
CC_SET_FASTPATH(cc, vm_call_iseq_setup_kwparm_kwarg, CC_SET_FASTPATH(cc, vm_call_iseq_setup_kwparm_kwarg,
cacheable_ci && METHOD_ENTRY_CACHEABLE(vm_cc_cme(cc))); cacheable_ci && vm_call_cacheable(ci, cc));
return 0; return 0;
} }
@ -2580,7 +2580,7 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling,
if (klocals[kw_param->num] == INT2FIX(0)) { if (klocals[kw_param->num] == INT2FIX(0)) {
/* copy from default_values */ /* copy from default_values */
CC_SET_FASTPATH(cc, vm_call_iseq_setup_kwparm_nokwarg, CC_SET_FASTPATH(cc, vm_call_iseq_setup_kwparm_nokwarg,
cacheable_ci && METHOD_ENTRY_CACHEABLE(vm_cc_cme(cc))); cacheable_ci && vm_call_cacheable(ci, cc));
} }
return 0; return 0;

View file

@ -252,13 +252,18 @@ THROW_DATA_CONSUMED_SET(struct vm_throw_data *obj)
#define IS_ARGS_KW_OR_KW_SPLAT(ci) (vm_ci_flag(ci) & (VM_CALL_KWARG | VM_CALL_KW_SPLAT)) #define IS_ARGS_KW_OR_KW_SPLAT(ci) (vm_ci_flag(ci) & (VM_CALL_KWARG | VM_CALL_KW_SPLAT))
#define IS_ARGS_KW_SPLAT_MUT(ci) (vm_ci_flag(ci) & VM_CALL_KW_SPLAT_MUT) #define IS_ARGS_KW_SPLAT_MUT(ci) (vm_ci_flag(ci) & VM_CALL_KW_SPLAT_MUT)
static inline bool
vm_call_cacheable(const struct rb_callinfo *ci, const struct rb_callcache *cc)
{
return (vm_ci_flag(ci) & VM_CALL_FCALL) ||
METHOD_ENTRY_VISI(vm_cc_cme(cc)) != METHOD_VISI_PROTECTED;
}
/* If this returns true, an optimized function returned by `vm_call_iseq_setup_func` /* If this returns true, an optimized function returned by `vm_call_iseq_setup_func`
can be used as a fastpath. */ can be used as a fastpath. */
static inline bool static inline bool
vm_call_iseq_optimizable_p(const struct rb_callinfo *ci, const struct rb_callcache *cc) vm_call_iseq_optimizable_p(const struct rb_callinfo *ci, const struct rb_callcache *cc)
{ {
return !IS_ARGS_SPLAT(ci) && !IS_ARGS_KEYWORD(ci) && return !IS_ARGS_SPLAT(ci) && !IS_ARGS_KEYWORD(ci) && vm_call_cacheable(ci, cc);
METHOD_ENTRY_CACHEABLE(vm_cc_cme(cc));
} }
#endif /* RUBY_INSNHELPER_H */ #endif /* RUBY_INSNHELPER_H */