diff options
author | Alan Wu <XrXr@users.noreply.github.com> | 2022-11-07 16:49:48 -0500 |
---|---|---|
committer | Alan Wu <XrXr@users.noreply.github.com> | 2022-11-08 16:09:02 -0500 |
commit | 5d95cd99f4ed425c416cc91e8986a3402d5b557a (patch) | |
tree | 3057f421d99b3cb697d49d509617fb6d285976de /yjit/src/invariants.rs | |
parent | 1466682a23ce0d7bf1f30d8b9627b4597c037e4d (diff) | |
download | ruby-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.rs | 3 |
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 |