diff options
author | Takashi Kokubun <takashikkbn@gmail.com> | 2023-12-07 14:53:05 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-07 22:53:05 +0000 |
commit | ac5fd58700b5576bfdd89ffe06dd4302b6721e5f (patch) | |
tree | ecfcd1027b4fb3f0dea5153206322b95f054d0bc /yjit | |
parent | 2755cb1b2fbc4a5f08ca56345b5945bd452da74e (diff) | |
download | ruby-ac5fd58700b5576bfdd89ffe06dd4302b6721e5f.tar.gz |
YJIT: Fix on-stack ISEQ comparison for auto_compact (#9164)
Diffstat (limited to 'yjit')
-rw-r--r-- | yjit/src/core.rs | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/yjit/src/core.rs b/yjit/src/core.rs index 8e8d246a3a..f84286bd2f 100644 --- a/yjit/src/core.rs +++ b/yjit/src/core.rs @@ -1095,17 +1095,24 @@ pub fn for_each_on_stack_iseq_payload<F: FnMut(&IseqPayload)>(mut callback: F) { /// Iterate over all NOT on-stack ISEQ payloads pub fn for_each_off_stack_iseq_payload<F: FnMut(&mut IseqPayload)>(mut callback: F) { - let mut on_stack_iseqs: Vec<IseqPtr> = vec![]; - for_each_on_stack_iseq(|iseq| { - on_stack_iseqs.push(iseq); - }); - for_each_iseq(|iseq| { + // Get all ISEQs on the heap. Note that rb_objspace_each_objects() runs GC first, + // which could move ISEQ pointers when GC.auto_compact = true. + // So for_each_on_stack_iseq() must be called after this, which doesn't run GC. + let mut iseqs: Vec<IseqPtr> = vec![]; + for_each_iseq(|iseq| iseqs.push(iseq)); + + // Get all ISEQs that are on a CFP of existing ECs. + let mut on_stack_iseqs: HashSet<IseqPtr> = HashSet::new(); + for_each_on_stack_iseq(|iseq| { on_stack_iseqs.insert(iseq); }); + + // Invoke the callback for iseqs - on_stack_iseqs + for iseq in iseqs { if !on_stack_iseqs.contains(&iseq) { if let Some(iseq_payload) = get_iseq_payload(iseq) { callback(iseq_payload); } } - }) + } } /// Free the per-iseq payload |