Skip to content

Commit ad85148

Browse files
committed
ZJIT: Support invalidating method redefinition
This commit adds support for the MethodRedefined invariant to be invalidated when a method is redefined. Changes: - Added CME pointer to the MethodRedefined invariant in HIR - Updated all places where MethodRedefined invariants are created to include the CME pointer - Added handling for MethodRedefined invariants in gen_patch_point to call track_cme_assumption, which registers the patch point for invalidation when rb_zjit_cme_invalidate is called This ensures that when a method is redefined, all JIT code that depends on that method will be properly invalidated.
1 parent 05f51cf commit ad85148

File tree

6 files changed

+168
-69
lines changed

6 files changed

+168
-69
lines changed

test/ruby/test_zjit.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,31 @@ def test
10661066
}, call_threshold: 2
10671067
end
10681068

1069+
# ZJIT currently only generates a MethodRedefined patch point when the method
1070+
# is called on the top-level self.
1071+
def test_method_redefinition_with_top_self
1072+
assert_runs '["original", "redefined"]', %q{
1073+
def foo
1074+
"original"
1075+
end
1076+
1077+
def test = foo
1078+
1079+
test; test
1080+
1081+
result1 = test
1082+
1083+
# Redefine the method
1084+
def foo
1085+
"redefined"
1086+
end
1087+
1088+
result2 = test
1089+
1090+
[result1, result2]
1091+
}, call_threshold: 2
1092+
end
1093+
10691094
def test_module_name_with_guard_passes
10701095
assert_compiles '"Integer"', %q{
10711096
def test(mod)

vm_method.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ vm_cme_invalidate(rb_callable_method_entry_t *cme)
122122
RB_DEBUG_COUNTER_INC(cc_cme_invalidate);
123123

124124
rb_yjit_cme_invalidate(cme);
125+
rb_zjit_cme_invalidate(cme);
125126
}
126127

127128
static int

zjit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ void rb_zjit_compile_iseq(const rb_iseq_t *iseq, rb_execution_context_t *ec, boo
1212
void rb_zjit_profile_insn(enum ruby_vminsn_type insn, rb_execution_context_t *ec);
1313
void rb_zjit_profile_enable(const rb_iseq_t *iseq);
1414
void rb_zjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop);
15+
void rb_zjit_cme_invalidate(const rb_callable_method_entry_t *cme);
1516
void rb_zjit_invalidate_ep_is_bp(const rb_iseq_t *iseq);
1617
void rb_zjit_iseq_mark(void *payload);
1718
void rb_zjit_iseq_update_references(void *payload);
@@ -21,6 +22,7 @@ static inline void rb_zjit_compile_iseq(const rb_iseq_t *iseq, rb_execution_cont
2122
static inline void rb_zjit_profile_insn(enum ruby_vminsn_type insn, rb_execution_context_t *ec) {}
2223
static inline void rb_zjit_profile_enable(const rb_iseq_t *iseq) {}
2324
static inline void rb_zjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop) {}
25+
static inline void rb_zjit_cme_invalidate(const rb_callable_method_entry_t *cme) {}
2426
static inline void rb_zjit_invalidate_ep_is_bp(const rb_iseq_t *iseq) {}
2527
#endif // #if USE_YJIT
2628

zjit/src/codegen.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::rc::Rc;
33

44
use crate::asm::Label;
55
use crate::backend::current::{Reg, ALLOC_REGS};
6-
use crate::invariants::track_bop_assumption;
6+
use crate::invariants::{track_bop_assumption, track_cme_assumption};
77
use crate::gc::{get_or_create_iseq_payload, append_gc_offsets};
88
use crate::state::ZJITState;
99
use crate::{asm::CodeBlock, cruby::*, options::debug, virtualmem::CodePtr};
@@ -494,6 +494,10 @@ fn gen_patch_point(jit: &mut JITState, asm: &mut Assembler, invariant: &Invarian
494494
let side_exit_ptr = cb.resolve_label(label);
495495
track_bop_assumption(klass, bop, code_ptr, side_exit_ptr);
496496
}
497+
Invariant::MethodRedefined { klass: _, method: _, cme } => {
498+
let side_exit_ptr = cb.resolve_label(label);
499+
track_cme_assumption(cme, code_ptr, side_exit_ptr);
500+
}
497501
_ => {
498502
debug!("ZJIT: gen_patch_point: unimplemented invariant {invariant:?}");
499503
return;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy