summaryrefslogtreecommitdiff
path: root/yjit
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2022-11-07 07:48:26 -0800
committerGitHub <noreply@github.com>2022-11-07 10:48:26 -0500
commit7442cb461b32de2eec3b37f52d80752d30627de0 (patch)
tree48fe9af80917b233f4fde081f03d6869bacfc99e /yjit
parentca0b59267352dd23bc53b5cb6f09aacd0025f536 (diff)
YJIT: Free pages after ObjectSpace API usages (#6676)
Notes
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
Diffstat (limited to 'yjit')
-rw-r--r--yjit/src/asm/mod.rs28
1 files changed, 15 insertions, 13 deletions
diff --git a/yjit/src/asm/mod.rs b/yjit/src/asm/mod.rs
index 3d7de7cd79..497f7687ed 100644
--- a/yjit/src/asm/mod.rs
+++ b/yjit/src/asm/mod.rs
@@ -563,23 +563,14 @@ impl CodeBlock {
pages_in_use[*page] = true;
}
});
- // Outlined code generated by CodegenGlobals::init() should also be kept.
- for page in CodegenGlobals::get_ocb_pages() {
- pages_in_use[*page] = true;
- }
-
- // Let VirtuamMem free the pages
- let mut freed_pages: Vec<usize> = pages_in_use.iter().enumerate()
- .filter(|&(_, &in_use)| !in_use).map(|(page, _)| page).collect();
- self.free_pages(&freed_pages);
// Avoid accumulating freed pages for future code GC
for_each_off_stack_iseq_payload(|iseq_payload: &mut IseqPayload| {
iseq_payload.pages.clear();
});
-
- // Append virtual pages in case RubyVM::YJIT.code_gc is manually triggered.
- let mut virtual_pages: Vec<usize> = (self.num_mapped_pages()..self.num_virtual_pages()).collect();
- freed_pages.append(&mut virtual_pages);
+ // Outlined code generated by CodegenGlobals::init() should also be kept.
+ for page in CodegenGlobals::get_ocb_pages() {
+ pages_in_use[*page] = true;
+ }
// Invalidate everything to have more compact code after code GC.
// This currently patches every ISEQ, which works, but in the future,
@@ -591,6 +582,17 @@ impl CodeBlock {
// can be safely reset to pass the frozen bytes check on invalidation.
CodegenGlobals::set_inline_frozen_bytes(0);
+ // Let VirtuamMem free the pages
+ let mut freed_pages: Vec<usize> = pages_in_use.iter().enumerate()
+ .filter(|&(_, &in_use)| !in_use).map(|(page, _)| page).collect();
+ // ObjectSpace API may trigger Ruby's GC, which marks gc_offsets in JIT code.
+ // So this should be called after for_each_*_iseq_payload and rb_yjit_tracing_invalidate_all.
+ self.free_pages(&freed_pages);
+
+ // Append virtual pages in case RubyVM::YJIT.code_gc is manually triggered.
+ let mut virtual_pages: Vec<usize> = (self.num_mapped_pages()..self.num_virtual_pages()).collect();
+ freed_pages.append(&mut virtual_pages);
+
if let Some(&first_page) = freed_pages.first() {
let mut cb = CodegenGlobals::get_inline_cb();
cb.write_pos = cb.get_page_pos(first_page);