aboutsummaryrefslogtreecommitdiffstats
path: root/yjit/src/invariants.rs
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2022-11-07 16:49:48 -0500
committerAlan Wu <XrXr@users.noreply.github.com>2022-11-08 16:09:02 -0500
commit5d95cd99f4ed425c416cc91e8986a3402d5b557a (patch)
tree3057f421d99b3cb697d49d509617fb6d285976de /yjit/src/invariants.rs
parent1466682a23ce0d7bf1f30d8b9627b4597c037e4d (diff)
downloadruby-5d95cd99f4ed425c416cc91e8986a3402d5b557a.tar.gz
YJIT: Reset dropped_bytes when patching code
We switch to a new page when we detect dropped_bytes flipping from false to true. Previously, when we patch code for invalidation during code gc, we start with the flag being set to true, so we failed to apply patches that straddle pages. We would write out jumps half way and then stop, which left the code corrupted. Reset the flag before patching so we patch across pages properly.
Diffstat (limited to 'yjit/src/invariants.rs')
-rw-r--r--yjit/src/invariants.rs3
1 files changed, 3 insertions, 0 deletions
diff --git a/yjit/src/invariants.rs b/yjit/src/invariants.rs
index 0d8577924c..cd3214feae 100644
--- a/yjit/src/invariants.rs
+++ b/yjit/src/invariants.rs
@@ -558,6 +558,7 @@ pub extern "C" fn rb_yjit_tracing_invalidate_all() {
// Apply patches
let old_pos = cb.get_write_pos();
+ let old_dropped_bytes = cb.has_dropped_bytes();
let mut patches = CodegenGlobals::take_global_inval_patches();
patches.sort_by_cached_key(|patch| patch.inline_patch_pos.raw_ptr());
let mut last_patch_end = std::ptr::null();
@@ -568,10 +569,12 @@ pub extern "C" fn rb_yjit_tracing_invalidate_all() {
asm.jmp(patch.outlined_target_pos.into());
cb.set_write_ptr(patch.inline_patch_pos);
+ cb.set_dropped_bytes(false);
asm.compile(cb);
last_patch_end = cb.get_write_ptr().raw_ptr();
}
cb.set_pos(old_pos);
+ cb.set_dropped_bytes(old_dropped_bytes);
// Freeze invalidated part of the codepage. We only want to wait for
// running instances of the code to exit from now on, so we shouldn't