Skip to content

Commit 328d203

Browse files
committed
ZJIT: Remove dead CMEs from Invariants
1 parent 63483e7 commit 328d203

File tree

4 files changed

+27
-0
lines changed

4 files changed

+27
-0
lines changed

vm_method.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,17 @@ rb_free_method_entry_vm_weak_references(const rb_method_entry_t *me)
859859
void
860860
rb_free_method_entry(const rb_method_entry_t *me)
861861
{
862+
#if USE_ZJIT
863+
if (METHOD_ENTRY_CACHED(me)) {
864+
rb_zjit_cme_free((const rb_callable_method_entry_t *)me);
865+
}
866+
#endif
867+
868+
#if USE_YJIT
869+
// YJIT rb_yjit_root_mark() roots CMEs in `Invariants`,
870+
// to remove from `Invariants` here.
871+
#endif
872+
862873
rb_method_definition_release(me->def);
863874
}
864875

zjit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ void rb_zjit_profile_insn(uint32_t insn, rb_execution_context_t *ec);
1818
void rb_zjit_profile_enable(const rb_iseq_t *iseq);
1919
void rb_zjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop);
2020
void rb_zjit_cme_invalidate(const rb_callable_method_entry_t *cme);
21+
void rb_zjit_cme_free(const rb_callable_method_entry_t *cme);
2122
void rb_zjit_invalidate_no_ep_escape(const rb_iseq_t *iseq);
2223
void rb_zjit_constant_state_changed(ID id);
2324
void rb_zjit_iseq_mark(void *payload);

zjit/src/gc.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,16 @@ pub extern "C" fn rb_zjit_iseq_free(iseq: IseqPtr) {
139139
invariants.forget_iseq(iseq);
140140
}
141141

142+
/// GC callback for finalizing a CME
143+
#[unsafe(no_mangle)]
144+
pub extern "C" fn rb_zjit_cme_free(cme: *const rb_callable_method_entry_struct) {
145+
if !ZJITState::has_instance() {
146+
return;
147+
}
148+
let invariants = ZJITState::get_invariants();
149+
invariants.forget_cme(cme);
150+
}
151+
142152
/// GC callback for updating object references after all object moves
143153
#[unsafe(no_mangle)]
144154
pub extern "C" fn rb_zjit_root_update_references() {

zjit/src/invariants.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ impl Invariants {
8080
self.no_ep_escape_iseq_patch_points.remove(&iseq);
8181
}
8282

83+
/// Forget a CME when freeing it. See [Self::forget_iseq] for reasoning.
84+
pub fn forget_cme(&mut self, cme: *const rb_callable_method_entry_t) {
85+
self.cme_patch_points.remove(&cme);
86+
}
87+
8388
/// Update ISEQ references in Invariants::ep_escape_iseqs
8489
fn update_ep_escape_iseqs(&mut self) {
8590
let updated = std::mem::take(&mut self.ep_escape_iseqs)

0 commit comments

Comments
 (0)