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

ruby-changes:73298

From: Alan <ko1@a...>
Date: Tue, 30 Aug 2022 01:08:04 +0900 (JST)
Subject: [ruby-changes:73298] 4d811d7a2b (master): Fix code invalidation while OOM and OOM simulation (https://github.com/Shopify/ruby/pull/395)

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

From 4d811d7a2b92d110e3e70cb77e5f499acfa7112a Mon Sep 17 00:00:00 2001
From: Alan Wu <XrXr@u...>
Date: Wed, 10 Aug 2022 17:22:55 -0400
Subject: Fix code invalidation while OOM and OOM simulation
 (https://github.com/Shopify/ruby/pull/395)

`YJIT.simulate_oom!` used to leave one byte of space in the code block,
so our test didn't expose a problem with asserting that the write
position is in bounds in `CodeBlock::set_pos`. We do the following when
patching code:
  1. save current write position
  2. seek to middle of the code block and patch
  3. restore old write position
The bounds check fails on (3) when the code block is already filled up.

Leaving one byte of space also meant that when we write that byte, we
need to fill the entire code region with trapping instruction in
`VirtualMem`, which made the OOM tests unnecessarily slow.

Remove the incorrect bounds check and stop leaving space in the code
block when simulating OOM.
---
 bootstraptest/test_yjit.rb |  9 +++++++++
 yjit/src/asm/mod.rs        | 12 ++++++------
 yjit/src/yjit.rs           |  4 ++--
 3 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index d44fe25800..89d7c9a038 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -2901,11 +2901,20 @@ assert_equal 'new', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L2901
     foo
   end
 
+  def bar
+    :bar
+  end
+
+
   test
   test
 
   RubyVM::YJIT.simulate_oom! if defined?(RubyVM::YJIT)
 
+  # Old simulat_omm! leaves one byte of space and this fills it up
+  bar
+  bar
+
   def foo
     :new
   end
diff --git a/yjit/src/asm/mod.rs b/yjit/src/asm/mod.rs
index 0e05eb5783..fef4518816 100644
--- a/yjit/src/asm/mod.rs
+++ b/yjit/src/asm/mod.rs
@@ -121,10 +121,10 @@ impl CodeBlock { https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/mod.rs#L121
 
     // Set the current write position
     pub fn set_pos(&mut self, pos: usize) {
-        // Assert here since while CodeBlock functions do bounds checking, there is
-        // nothing stopping users from taking out an out-of-bounds pointer and
-        // doing bad accesses with it.
-        assert!(pos < self.mem_size);
+        // No bounds check here since we can be out of bounds
+        // when the code block fills up. We want to be able to
+        // restore to the filled up state after patching something
+        // in the middle.
         self.write_pos = pos;
     }
 
@@ -152,12 +152,12 @@ impl CodeBlock { https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/mod.rs#L152
         self.set_pos(pos);
     }
 
-    // Get a direct pointer into the executable memory block
+    /// Get a (possibly dangling) direct pointer into the executable memory block
     pub fn get_ptr(&self, offset: usize) -> CodePtr {
         self.mem_block.start_ptr().add_bytes(offset)
     }
 
-    // Get a direct pointer to the current write position
+    /// Get a (possibly dangling) direct pointer to the current write position
     pub fn get_write_ptr(&mut self) -> CodePtr {
         self.get_ptr(self.write_pos)
     }
diff --git a/yjit/src/yjit.rs b/yjit/src/yjit.rs
index bfa9188d3e..5cd23f066f 100644
--- a/yjit/src/yjit.rs
+++ b/yjit/src/yjit.rs
@@ -91,8 +91,8 @@ pub extern "C" fn rb_yjit_simulate_oom_bang(_ec: EcPtr, _ruby_self: VALUE) -> VA https://github.com/ruby/ruby/blob/trunk/yjit/src/yjit.rs#L91
     if cfg!(debug_assertions) {
         let cb = CodegenGlobals::get_inline_cb();
         let ocb = CodegenGlobals::get_outlined_cb().unwrap();
-        cb.set_pos(cb.get_mem_size() - 1);
-        ocb.set_pos(ocb.get_mem_size() - 1);
+        cb.set_pos(cb.get_mem_size());
+        ocb.set_pos(ocb.get_mem_size());
     }
 
     return Qnil;
-- 
cgit v1.2.1


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

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