@@ -2352,9 +2352,9 @@ vm_search_method_slowpath0(VALUE cd_owner, struct rb_call_data *cd, VALUE klass)
23522352 return cc ;
23532353}
23542354
2355- ALWAYS_INLINE (static const struct rb_callcache * vm_search_method_fastpath (VALUE cd_owner , struct rb_call_data * cd , VALUE klass ));
2355+ ALWAYS_INLINE (static const struct rb_callcache * vm_search_method_fastpath (const struct rb_control_frame_struct * reg_cfp , struct rb_call_data * cd , VALUE klass ));
23562356static const struct rb_callcache *
2357- vm_search_method_fastpath (VALUE cd_owner , struct rb_call_data * cd , VALUE klass )
2357+ vm_search_method_fastpath (const struct rb_control_frame_struct * reg_cfp , struct rb_call_data * cd , VALUE klass )
23582358{
23592359 const struct rb_callcache * cc = cd -> cc ;
23602360
@@ -2376,24 +2376,28 @@ vm_search_method_fastpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass)
23762376 }
23772377#endif
23782378
2379- return vm_search_method_slowpath0 (cd_owner , cd , klass );
2379+ return vm_search_method_slowpath0 (( VALUE ) reg_cfp -> iseq , cd , klass );
23802380}
23812381
23822382static const struct rb_callable_method_entry_struct *
2383- vm_search_method (VALUE cd_owner , struct rb_call_data * cd , VALUE recv )
2383+ vm_search_method (struct rb_control_frame_struct * reg_cfp , struct rb_call_data * cd , VALUE recv )
23842384{
23852385 VALUE klass = CLASS_OF (recv );
23862386 VM_ASSERT (klass != Qfalse );
23872387 VM_ASSERT (RBASIC_CLASS (klass ) == 0 || rb_obj_is_kind_of (klass , rb_cClass ));
23882388
2389- const struct rb_callcache * cc = vm_search_method_fastpath (cd_owner , cd , klass );
2389+ const struct rb_callcache * cc = vm_search_method_fastpath (reg_cfp , cd , klass );
23902390 return vm_cc_cme (cc );
23912391}
23922392
23932393const struct rb_callable_method_entry_struct *
23942394rb_zjit_vm_search_method (VALUE cd_owner , struct rb_call_data * cd , VALUE recv )
23952395{
2396- return vm_search_method (cd_owner , cd , recv );
2396+ // Called from ZJIT with the compile-time iseq, which may differ from
2397+ // the iseq on the current CFP. Use the slowpath to avoid stale caches.
2398+ VALUE klass = CLASS_OF (recv );
2399+ const struct rb_callcache * cc = vm_search_method_slowpath0 (cd_owner , cd , klass );
2400+ return vm_cc_cme (cc );
23972401}
23982402
23992403#if __has_attribute (transparent_union )
@@ -2453,10 +2457,10 @@ check_method_basic_definition(const rb_callable_method_entry_t *me)
24532457}
24542458
24552459static inline int
2456- vm_method_cfunc_is (const rb_iseq_t * iseq , CALL_DATA cd , VALUE recv , cfunc_type func )
2460+ vm_method_cfunc_is (struct rb_control_frame_struct * reg_cfp , CALL_DATA cd , VALUE recv , cfunc_type func )
24572461{
2458- VM_ASSERT (iseq != NULL );
2459- const struct rb_callable_method_entry_struct * cme = vm_search_method (( VALUE ) iseq , cd , recv );
2462+ VM_ASSERT (reg_cfp != NULL );
2463+ const struct rb_callable_method_entry_struct * cme = vm_search_method (reg_cfp , cd , recv );
24602464 return check_cfunc (cme , func );
24612465}
24622466
@@ -2469,11 +2473,16 @@ rb_zjit_cme_is_cfunc(const rb_callable_method_entry_t *me, const cfunc_type func
24692473int
24702474rb_vm_method_cfunc_is (const rb_iseq_t * iseq , CALL_DATA cd , VALUE recv , cfunc_type func )
24712475{
2472- return vm_method_cfunc_is (iseq , cd , recv , func );
2476+ // Called from ZJIT with the compile-time iseq, which may differ from
2477+ // the iseq on the current CFP. Use the slowpath to avoid stale caches.
2478+ VALUE klass = CLASS_OF (recv );
2479+ const struct rb_callcache * cc = vm_search_method_slowpath0 ((VALUE )iseq , cd , klass );
2480+ const struct rb_callable_method_entry_struct * cme = vm_cc_cme (cc );
2481+ return check_cfunc (cme , func );
24732482}
24742483
24752484#define check_cfunc (me , func ) check_cfunc(me, make_cfunc_type(func))
2476- #define vm_method_cfunc_is (iseq , cd , recv , func ) vm_method_cfunc_is(iseq , cd, recv, make_cfunc_type(func))
2485+ #define vm_method_cfunc_is (reg_cfp , cd , recv , func ) vm_method_cfunc_is(reg_cfp , cd, recv, make_cfunc_type(func))
24772486
24782487#define EQ_UNREDEFINED_P (t ) BASIC_OP_UNREDEFINED_P(BOP_EQ, t##_REDEFINED_OP_FLAG)
24792488
@@ -2542,14 +2551,14 @@ opt_equality_specialized(VALUE recv, VALUE obj)
25422551}
25432552
25442553static VALUE
2545- opt_equality (const rb_iseq_t * cd_owner , VALUE recv , VALUE obj , CALL_DATA cd )
2554+ opt_equality (struct rb_control_frame_struct * reg_cfp , VALUE recv , VALUE obj , CALL_DATA cd )
25462555{
2547- VM_ASSERT (cd_owner != NULL );
2556+ VM_ASSERT (reg_cfp != NULL );
25482557
25492558 VALUE val = opt_equality_specialized (recv , obj );
25502559 if (!UNDEF_P (val )) return val ;
25512560
2552- if (!vm_method_cfunc_is (cd_owner , cd , recv , rb_obj_equal )) {
2561+ if (!vm_method_cfunc_is (reg_cfp , cd , recv , rb_obj_equal )) {
25532562 return Qundef ;
25542563 }
25552564 else {
@@ -5171,7 +5180,7 @@ vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *c
51715180 RB_OBJ_WRITE (reg_cfp -> iseq , & cd -> cc , cc );
51725181 }
51735182 else {
5174- cc = vm_search_method_fastpath (( VALUE ) reg_cfp -> iseq , cd , klass );
5183+ cc = vm_search_method_fastpath (reg_cfp , cd , klass );
51755184 const rb_callable_method_entry_t * cached_cme = vm_cc_cme (cc );
51765185
51775186 // define_method can cache for different method id
@@ -6123,7 +6132,7 @@ vm_sendish(
61236132
61246133 switch (method_explorer ) {
61256134 case mexp_search_method :
6126- calling .cc = cc = vm_search_method_fastpath (( VALUE ) reg_cfp -> iseq , cd , CLASS_OF (recv ));
6135+ calling .cc = cc = vm_search_method_fastpath (reg_cfp , cd , CLASS_OF (recv ));
61276136 val = vm_cc_call (cc )(ec , GET_CFP (), & calling );
61286137 break ;
61296138 case mexp_search_super :
@@ -6230,14 +6239,14 @@ VALUE rb_mod_to_s(VALUE);
62306239VALUE rb_mod_name (VALUE );
62316240
62326241static VALUE
6233- vm_objtostring (const rb_iseq_t * iseq , VALUE recv , CALL_DATA cd )
6242+ vm_objtostring (struct rb_control_frame_struct * reg_cfp , VALUE recv , CALL_DATA cd )
62346243{
62356244 int type = TYPE (recv );
62366245 if (type == T_STRING ) {
62376246 return recv ;
62386247 }
62396248
6240- const struct rb_callable_method_entry_struct * cme = vm_search_method (( VALUE ) iseq , cd , recv );
6249+ const struct rb_callable_method_entry_struct * cme = vm_search_method (reg_cfp , cd , recv );
62416250
62426251 switch (type ) {
62436252 case T_SYMBOL :
@@ -6288,9 +6297,9 @@ vm_objtostring(const rb_iseq_t *iseq, VALUE recv, CALL_DATA cd)
62886297// ZJIT implementation is using the C function
62896298// and needs to call a non-static function
62906299VALUE
6291- rb_vm_objtostring (const rb_iseq_t * iseq , VALUE recv , CALL_DATA cd )
6300+ rb_vm_objtostring (struct rb_control_frame_struct * reg_cfp , VALUE recv , CALL_DATA cd )
62926301{
6293- return vm_objtostring (iseq , recv , cd );
6302+ return vm_objtostring (reg_cfp , recv , cd );
62946303}
62956304
62966305static VALUE
@@ -6841,10 +6850,10 @@ vm_opt_mod(VALUE recv, VALUE obj)
68416850}
68426851
68436852static VALUE
6844- vm_opt_neq (const rb_iseq_t * iseq , CALL_DATA cd , CALL_DATA cd_eq , VALUE recv , VALUE obj )
6853+ vm_opt_neq (struct rb_control_frame_struct * reg_cfp , CALL_DATA cd , CALL_DATA cd_eq , VALUE recv , VALUE obj )
68456854{
6846- if (vm_method_cfunc_is (iseq , cd , recv , rb_obj_not_equal )) {
6847- VALUE val = opt_equality (iseq , recv , obj , cd_eq );
6855+ if (vm_method_cfunc_is (reg_cfp , cd , recv , rb_obj_not_equal )) {
6856+ VALUE val = opt_equality (reg_cfp , recv , obj , cd_eq );
68486857
68496858 if (!UNDEF_P (val )) {
68506859 return RBOOL (!RTEST (val ));
@@ -7096,13 +7105,13 @@ vm_opt_empty_p(VALUE recv)
70967105VALUE rb_false (VALUE obj );
70977106
70987107static VALUE
7099- vm_opt_nil_p (const rb_iseq_t * iseq , CALL_DATA cd , VALUE recv )
7108+ vm_opt_nil_p (struct rb_control_frame_struct * reg_cfp , CALL_DATA cd , VALUE recv )
71007109{
71017110 if (NIL_P (recv ) &&
71027111 BASIC_OP_UNREDEFINED_P (BOP_NIL_P , NIL_REDEFINED_OP_FLAG )) {
71037112 return Qtrue ;
71047113 }
7105- else if (vm_method_cfunc_is (iseq , cd , recv , rb_false )) {
7114+ else if (vm_method_cfunc_is (reg_cfp , cd , recv , rb_false )) {
71067115 return Qfalse ;
71077116 }
71087117 else {
@@ -7158,9 +7167,9 @@ vm_opt_succ(VALUE recv)
71587167}
71597168
71607169static VALUE
7161- vm_opt_not (const rb_iseq_t * iseq , CALL_DATA cd , VALUE recv )
7170+ vm_opt_not (struct rb_control_frame_struct * reg_cfp , CALL_DATA cd , VALUE recv )
71627171{
7163- if (vm_method_cfunc_is (iseq , cd , recv , rb_obj_not )) {
7172+ if (vm_method_cfunc_is (reg_cfp , cd , recv , rb_obj_not )) {
71647173 return RBOOL (!RTEST (recv ));
71657174 }
71667175 else {
0 commit comments