summaryrefslogtreecommitdiff
path: root/yjit
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2022-10-26 08:29:12 -0700
committerGitHub <noreply@github.com>2022-10-26 11:29:12 -0400
commitfa0adbad92fc1216ba0d1757fe40f0453e3a6574 (patch)
treede7822bc44789f830d8dac936225c5b71b96ca09 /yjit
parent0dc2e1a764ba2a18d3646f11f272b05395b01201 (diff)
YJIT: Invalidate i-cache for the other cb on next_page (#6631)
* YJIT: Invalidate i-cache for the other cb on next_page * YJIT: Invalidate only what's written by jmp_ptr * YJIT: Move the code to the arm64 backend
Notes
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
Diffstat (limited to 'yjit')
-rw-r--r--yjit/src/backend/arm64/mod.rs19
1 files changed, 18 insertions, 1 deletions
diff --git a/yjit/src/backend/arm64/mod.rs b/yjit/src/backend/arm64/mod.rs
index 7aeb1435d2..0c784c0bea 100644
--- a/yjit/src/backend/arm64/mod.rs
+++ b/yjit/src/backend/arm64/mod.rs
@@ -708,6 +708,23 @@ impl Assembler
}
}
+ /// Call emit_jmp_ptr and immediately invalidate the written range.
+ /// This is needed when next_page also moves other_cb that is not invalidated
+ /// by compile_with_regs. Doing it here allows you to avoid invalidating a lot
+ /// more than necessary when other_cb jumps from a position early in the page.
+ /// This invalidates a small range of cb twice, but we accept the small cost.
+ fn emit_jmp_ptr_with_invalidation(cb: &mut CodeBlock, dst_ptr: CodePtr) {
+ #[cfg(not(test))]
+ let start = cb.get_write_ptr();
+ emit_jmp_ptr(cb, dst_ptr);
+ #[cfg(not(test))]
+ {
+ let end = cb.get_write_ptr();
+ use crate::cruby::rb_yjit_icache_invalidate;
+ unsafe { rb_yjit_icache_invalidate(start.raw_ptr() as _, end.raw_ptr() as _) };
+ }
+ }
+
// dbg!(&self.insns);
// List of GC offsets
@@ -1018,7 +1035,7 @@ impl Assembler
};
// On failure, jump to the next page and retry the current insn
- if !had_dropped_bytes && cb.has_dropped_bytes() && cb.next_page(src_ptr, emit_jmp_ptr) {
+ if !had_dropped_bytes && cb.has_dropped_bytes() && cb.next_page(src_ptr, emit_jmp_ptr_with_invalidation) {
// Reset cb states before retrying the current Insn
cb.set_label_state(old_label_state);
} else {