[前][次][番号順一覧][スレッド一覧]

ruby-changes:73260

From: Alan <ko1@a...>
Date: Tue, 30 Aug 2022 01:05:15 +0900 (JST)
Subject: [ruby-changes:73260] a375784275 (master): Use new assembler to support global invalidation on A64

https://git.ruby-lang.org/ruby.git/commit/?id=a375784275

From a3757842752e78a5f53b5dfcdcf9601c037f8c76 Mon Sep 17 00:00:00 2001
From: Alan Wu <XrXr@u...>
Date: Mon, 8 Aug 2022 14:49:46 -0400
Subject: Use new assembler to support global invalidation on A64

Previously, we patched in an x64 JMP even on A64, which resulted in
invalid machine code. Use the new assembler to generate a jump instead.

Add an assert to make sure patches don't step on each other since it's
less clear cut on A64, where the size of the jump varies depending on
its placement relative to the target.

Fixes a lot of tests that use `set_trace_func` in `test_insns.rb`.

PR: https://github.com/Shopify/ruby/pull/379
---
 yjit/src/invariants.rs | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/yjit/src/invariants.rs b/yjit/src/invariants.rs
index 6329c70f87..9cdef0d8bb 100644
--- a/yjit/src/invariants.rs
+++ b/yjit/src/invariants.rs
@@ -528,8 +528,6 @@ pub extern "C" fn rb_yjit_tracing_invalidate_all() { https://github.com/ruby/ruby/blob/trunk/yjit/src/invariants.rs#L528
         return;
     }
 
-    use crate::asm::x86_64::jmp_ptr;
-
     // Stop other ractors since we are going to patch machine code.
     with_vm_lock(src_loc!(), || {
         // Make it so all live block versions are no longer valid branch targets
@@ -561,13 +559,18 @@ pub extern "C" fn rb_yjit_tracing_invalidate_all() { https://github.com/ruby/ruby/blob/trunk/yjit/src/invariants.rs#L559
 
         // Apply patches
         let old_pos = cb.get_write_pos();
-        let patches = CodegenGlobals::take_global_inval_patches();
+        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();
         for patch in &patches {
-            cb.set_write_ptr(patch.inline_patch_pos);
-            jmp_ptr(cb, patch.outlined_target_pos);
+            assert!(last_patch_end <= patch.inline_patch_pos.raw_ptr(), "patches should not overlap");
 
-            // FIXME: Can't easily check we actually wrote out the JMP at the moment.
-            // assert!(!cb.has_dropped_bytes(), "patches should have space and jump offsets should fit in JMP rel32");
+            let mut asm = crate::backend::ir::Assembler::new();
+            asm.jmp(patch.outlined_target_pos.into());
+
+            cb.set_write_ptr(patch.inline_patch_pos);
+            asm.compile(cb);
+            last_patch_end = cb.get_write_ptr().raw_ptr();
         }
         cb.set_pos(old_pos);
 
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]