Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/auto_request_review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ jobs:
if: ${{ github.repository == 'ruby/ruby' && github.base_ref == 'master' }}
steps:
- name: Request review based on files changes and/or groups the author belongs to
# Using a fork until https://github.com/necojackarc/auto-request-review/pull/135 is merged
uses: k0kubun/auto-request-review@0df295a0ff5c5d302770f589497280132131c63d # master
uses: necojackarc/auto-request-review@5d3060495e58e9cb41f51de50e808d3135d5374e # master
with:
# scope: public_repo
token: ${{ secrets.MATZBOT_AUTO_REQUEST_REVIEW_TOKEN }}
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,15 @@ yjit = [ "dep:yjit" ]
zjit = [ "dep:zjit" ]

[profile.dev]
opt-level = 0
opt-level = 1 # On 0, functions use so much stack space that we get stray `SystemStackError`s
debug = true
debug-assertions = true
overflow-checks = true

[profile.test]
inherits = "dev"
opt-level = 0

[profile.dev_nodebug]
inherits = "dev"

Expand Down
2 changes: 1 addition & 1 deletion common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -1578,7 +1578,7 @@ no-test-bundled-gems-precheck:

update-default-gemspecs: $(TEST_RUNNABLE)-update-default-gemspecs
no-update-default-gemspecs:
yes-update-default-gemspecs: $(PRECHECK_BUNDLED_GEMS:yes=main)
yes-update-default-gemspecs: $(PRECHECK_BUNDLED_GEMS:yes=main) $(PROGRAM)
@$(MAKEDIRS) $(srcdir)/.bundle/specifications
@$(XRUBY) -W0 -C "$(srcdir)" -rrubygems \
-e "destdir = ARGV.shift" \
Expand Down
2 changes: 1 addition & 1 deletion cont.c
Original file line number Diff line number Diff line change
Expand Up @@ -1480,7 +1480,7 @@ rb_yjit_cancel_jit_return(void *leave_exit, void *leave_exception)

const rb_control_frame_t *cfp = cont->ec->cfp;
while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(cont->ec, cfp)) {
if (CFP_JIT_RETURN(cfp) && cfp->jit_return != leave_exception) {
if (cfp->jit_return && cfp->jit_return != leave_exception) {
((rb_control_frame_t *)cfp)->jit_return = leave_exit;
}
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
Expand Down
3 changes: 0 additions & 3 deletions test/.excludes-zjit/TestOpenURI.rb

This file was deleted.

3 changes: 0 additions & 3 deletions test/.excludes-zjit/TestOpenURIProxy.rb

This file was deleted.

3 changes: 0 additions & 3 deletions test/.excludes-zjit/TestOpenURISSL.rb

This file was deleted.

2 changes: 2 additions & 0 deletions test/open-uri/test_open-uri.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ def test_read_timeout
sock.print "Content-Length: 4\r\n\r\n"
sleep 1
sock.print "ab\r\n"
rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ECONNABORTED
# expected when client times out and closes the connection
ensure
sock.close
end
Expand Down
2 changes: 1 addition & 1 deletion test/ruby/test_struct.rb
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ def test_named_structs_are_not_rooted
omit 'skip on riscv64-linux CI machine. See https://github.com/ruby/ruby/pull/13422' if ENV['RUBY_DEBUG'] == 'ci' && /riscv64-linux/ =~ RUBY_DESCRIPTION

# [Bug #20311]
assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true)
assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true, limit: 2.2)
code = proc do
Struct.new("A")
Struct.send(:remove_const, :A)
Expand Down
13 changes: 6 additions & 7 deletions test/ruby/test_thread.rb
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@ def test_handle_interrupt_invalid_argument

def for_test_handle_interrupt_with_return
Thread.handle_interrupt(Object => :never){
Thread.current.raise RuntimeError.new("have to be rescured")
Thread.current.raise RuntimeError.new("have to be rescued")
return
}
rescue
Expand All @@ -815,7 +815,7 @@ def test_handle_interrupt_with_break
assert_nothing_raised do
begin
Thread.handle_interrupt(Object => :never){
Thread.current.raise RuntimeError.new("have to be rescured")
Thread.current.raise RuntimeError.new("have to be rescued")
break
}
rescue
Expand Down Expand Up @@ -1592,10 +1592,9 @@ def frame_for_deadlock_test_2
INPUT
end

# [Bug #21342]
def test_unlock_locked_mutex_with_collected_fiber
bug21127 = '[ruby-core:120930] [Bug #21127]'
assert_ruby_status([], "#{<<~"begin;"}\n#{<<~'end;'}", bug21127)
bug21342 = '[ruby-core:122121] [Bug #21342]'
assert_ruby_status([], "#{<<~"begin;"}\n#{<<~'end;'}", bug21342)
begin;
5.times do
m = Mutex.new
Expand Down Expand Up @@ -1667,7 +1666,7 @@ def test_mn_threads_sub_millisecond_sleep

# [Bug #21926]
def test_thread_join_during_finalizers
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}", timeout: 30)
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}", timeout: 60)
begin;
require 'open3'

Expand All @@ -1690,7 +1689,7 @@ def self.make_finalizer(stdin, stdout, stderr, wait_thread)
end
end

50.times { ProcessWrapper.new }
20.times { ProcessWrapper.new }
GC.stress = true
1000.times { Object.new }
end;
Expand Down
4 changes: 2 additions & 2 deletions vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2852,7 +2852,7 @@ zjit_materialize_frames(rb_control_frame_t *cfp)
if (!rb_zjit_enabled_p) return;

while (true) {
if (CFP_JIT_RETURN(cfp)) {
if (CFP_ZJIT_FRAME(cfp)) {
const zjit_jit_frame_t *jit_frame = (const zjit_jit_frame_t *)cfp->jit_return;
cfp->pc = jit_frame->pc;
cfp->_iseq = (rb_iseq_t *)jit_frame->iseq;
Expand Down Expand Up @@ -3671,7 +3671,7 @@ rb_execution_context_update(rb_execution_context_t *ec)
while (cfp != limit_cfp) {
const VALUE *ep = cfp->ep;
cfp->self = rb_gc_location(cfp->self);
if (CFP_JIT_RETURN(cfp)) {
if (CFP_ZJIT_FRAME(cfp)) {
rb_zjit_jit_frame_update_references((zjit_jit_frame_t *)cfp->jit_return);
// block_code must always be relocated. For ISEQ frames, the JIT caller
// may have written it (gen_block_handler_specval) for passing blocks.
Expand Down
2 changes: 1 addition & 1 deletion vm_insnhelper.c
Original file line number Diff line number Diff line change
Expand Up @@ -3219,7 +3219,7 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling,
if (UNLIKELY(!ISEQ_BODY(iseq)->param.flags.use_block &&
calling->block_handler != VM_BLOCK_HANDLER_NONE &&
!(vm_ci_flag(calling->cd->ci) & (VM_CALL_OPT_SEND | VM_CALL_SUPER)))) {
warn_unused_block(vm_cc_cme(cc), iseq, (void *)ec->cfp->pc);
warn_unused_block(vm_cc_cme(cc), iseq, (void *)CFP_PC(ec->cfp));
}

if (LIKELY(!(vm_ci_flag(ci) & VM_CALL_KW_SPLAT))) {
Expand Down
2 changes: 1 addition & 1 deletion yjit.c
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ rb_yjit_set_exception_return(rb_control_frame_t *cfp, void *leave_exit, void *le
// If it's a FINISH frame, just normally exit with a non-Qundef value.
cfp->jit_return = leave_exit;
}
else if (CFP_JIT_RETURN(cfp)) {
else if (cfp->jit_return) {
while (!VM_FRAME_FINISHED_P(cfp)) {
if (cfp->jit_return == leave_exit) {
// Unlike jit_exec(), leave_exit is not safe on a non-FINISH frame on
Expand Down
6 changes: 3 additions & 3 deletions zjit.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ enum zjit_poison_values {
// YJIT also uses jit_return (as a return address), so this must only return
// non-NULL when ZJIT is enabled and has set jit_return to a JITFrame pointer.
static inline void *
CFP_JIT_RETURN(const rb_control_frame_t *cfp)
CFP_ZJIT_FRAME(const rb_control_frame_t *cfp)
{
if (!rb_zjit_enabled_p) return NULL;
#if USE_ZJIT
Expand All @@ -87,7 +87,7 @@ CFP_JIT_RETURN(const rb_control_frame_t *cfp)
static inline const VALUE*
CFP_PC(const rb_control_frame_t *cfp)
{
if (CFP_JIT_RETURN(cfp)) {
if (CFP_ZJIT_FRAME(cfp)) {
return ((const zjit_jit_frame_t *)cfp->jit_return)->pc;
}
return cfp->pc;
Expand All @@ -96,7 +96,7 @@ CFP_PC(const rb_control_frame_t *cfp)
static inline const rb_iseq_t*
CFP_ISEQ(const rb_control_frame_t *cfp)
{
if (CFP_JIT_RETURN(cfp)) {
if (CFP_ZJIT_FRAME(cfp)) {
return ((const zjit_jit_frame_t *)cfp->jit_return)->iseq;
}
return cfp->_iseq;
Expand Down
27 changes: 27 additions & 0 deletions zjit/src/codegen_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5544,3 +5544,30 @@ fn test_send_block_to_method_not_using_block() {
test
"), @"42");
}

#[test]
fn test_send_block_unused_warning_emitted_from_jit() {
// When ZJIT compiles a send with a block as a dynamic dispatch fallback
// (gen_send -> rb_vm_send), warn_unused_block uses cfp->pc for the dedup
// key. We save cfp->pc before calling rb_vm_send so the key is stable
// and won't spuriously collide with prior entries in the dedup table.
assert_snapshot!(inspect(r#"
$warnings = []
module Warning
def warn(message, category: nil)
$warnings << message
end
end

def m_unused_block_warn_test = 42

def test
$VERBOSE = true
m_unused_block_warn_test {}
$warnings.any? { |w| w.include?("may be ignored") }
end

test
test
"#), @"true");
}
6 changes: 3 additions & 3 deletions zjit/src/cruby.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1228,13 +1228,13 @@ pub mod test_utils {
// "Fun" double pointer dance to get a thin function pointer to pass through C
unsafe extern "C" fn callback_wrapper(data: VALUE) -> VALUE {
// SAFETY: shorter lifetime than the data local in the caller frame
let callback: &mut &mut dyn FnMut() = unsafe { std::mem::transmute(data) };
callback();
let callback: *mut &mut dyn FnMut() = std::ptr::with_exposed_provenance_mut(data.0);
unsafe { (*callback)() };
Qnil
}

let mut state: c_int = 0;
unsafe { super::rb_protect(Some(callback_wrapper), VALUE((&mut data) as *mut _ as usize), &mut state) };
unsafe { super::rb_protect(Some(callback_wrapper), VALUE((&raw mut data).expose_provenance()), &mut state) };
if state != 0 {
unsafe { rb_zjit_print_exception(); }
assert_eq!(0, state, "Exceptional unwind in callback. Ruby exception?");
Expand Down