From de1836d26130514a409449895a89332dd21b81ae Mon Sep 17 00:00:00 2001 From: Maxime Chevalier-Boisvert Date: Thu, 4 Aug 2022 16:46:36 -0400 Subject: [PATCH] Fix block invalidation with new backend. Enable more btests on x86 (https://github.com/Shopify/ruby/pull/359) --- bootstraptest/test_yjit_new_backend.rb | 68 ++++++++++++++++---------- yjit/src/core.rs | 15 +++--- 2 files changed, 51 insertions(+), 32 deletions(-) diff --git a/bootstraptest/test_yjit_new_backend.rb b/bootstraptest/test_yjit_new_backend.rb index fe7e1078c8762e..685bdd18d969f7 100644 --- a/bootstraptest/test_yjit_new_backend.rb +++ b/bootstraptest/test_yjit_new_backend.rb @@ -4,6 +4,31 @@ # To look up Ruby snippets using specific instructions, see: # https://kddnewton.com/yarv/ +# Microbenchmark with a loop, opt_lt +assert_equal '55', %q{ + def foo(n) + i = 0 + s = 0 + while i < n do + i += 1 + s += i + end + s + end + foo(10) +} + +# Small recursive microbenchmark +assert_equal '21', %q{ + def fib(n) + if n < 2 + return n + end + return fib(n-1) + fib(n-2) + end + fib(8) +} + assert_equal '1', %q{ def foo() 1 @@ -312,6 +337,24 @@ def bar [Foo.new.foo, bar] } +# BOP redefinition works on Integer#< +assert_equal 'false', %q{ + def less_than x + x < 10 + end + + less_than 2 + less_than 2 + + class Integer + def < x + false + end + end + + less_than 2 +} + # Test that object references in generated code get marked and moved assert_equal "good", %q{ def bar @@ -333,28 +376,3 @@ def foo foo } - -# Microbenchmark with a loop, opt_lt -assert_equal '55', %q{ - def foo(n) - i = 0 - s = 0 - while i < n do - i += 1 - s += i - end - s - end - foo(10) -} - -# Small recursive microbenchmark -assert_equal '21', %q{ - def fib(n) - if n < 2 - return n - end - return fib(n-1) + fib(n-2) - end - fib(8) -} diff --git a/yjit/src/core.rs b/yjit/src/core.rs index 3b33360b90c6d0..1bc3d738ef4edf 100644 --- a/yjit/src/core.rs +++ b/yjit/src/core.rs @@ -2021,7 +2021,7 @@ pub fn invalidate_block_version(blockref: &BlockRef) { // machine code that some other thread is running. let block = blockref.borrow(); - let cb = CodegenGlobals::get_inline_cb(); + let mut cb = CodegenGlobals::get_inline_cb(); let ocb = CodegenGlobals::get_outlined_cb(); verify_blockid(block.blockid); @@ -2069,11 +2069,13 @@ pub fn invalidate_block_version(blockref: &BlockRef) { // if (block.start_addr >= cb_get_ptr(cb, yjit_codepage_frozen_bytes)) // Don't patch frozen code region // Patch in a jump to block.entry_exit. + let cur_pos = cb.get_write_ptr(); cb.set_write_ptr(block_start); - //jmp_ptr(cb, block_entry_exit); - todo!("jmp_ptr with new assembler"); + let mut asm = Assembler::new(); + asm.jmp(block_entry_exit.into()); + asm.compile(&mut cb); assert!( cb.get_write_ptr() < block_end, @@ -2154,13 +2156,12 @@ pub fn invalidate_block_version(blockref: &BlockRef) { // change this in the future when we support optional parameters because // they enter the function with a non-zero PC if block.blockid.idx == 0 { + // TODO: + // We could reset the exec counter to zero in rb_iseq_reset_jit_func() + // so that we eventually compile a new entry point when useful unsafe { rb_iseq_reset_jit_func(block.blockid.iseq) }; } - // TODO: - // May want to recompile a new entry point (for interpreter entry blocks) - // This isn't necessary for correctness - // FIXME: // Call continuation addresses on the stack can also be atomically replaced by jumps going to the stub.