Every piece the Happy Eyeballs Version 2 path needed from pthread, pipe(2) and select(2) now has a Windows counterpart, so a host that answers with both families no longer waits for the IPv6 attempt to time out there. MinGW stays out, since its pthread emulation was never tested against this path, and its tests are omitted instead of passing by connecting sequentially.
Co-Authored-By: Claude Opus 5 <[email protected]>
Winsock has no EAI_ADDRFAMILY, and its getsockopt(2) takes a char * where the option value is an int. Neither compiles as written once the fast fallback is built for Windows.
Co-Authored-By: Claude Opus 5 <[email protected]>
Winsock reports a failed non-blocking connect(2) through the exceptfds of select(2) alone, so the fast fallback never learned that an attempt had been refused. Only Windows fills the set, so select(2) behaves as before elsewhere.
[Bug #18661]
Co-Authored-By: Claude Opus 5 <[email protected]>
rb_w32_select_with_thread() polls the read end of a pipe, so the resolution threads can report through one there too. The waiter goes through nonblock_set() because the Windows fcntl() has no F_GETFL.
Co-Authored-By: Claude Opus 5 <[email protected]>
The connection attempts race each other non-blocking, and TCPSocket.new wrapped the winner as it was. Windows creates every other socket blocking, and a read parked on a non-blocking one there cannot be interrupted by IO#close. POSIX sockets start out non-blocking, so leave them alone and test that they stay so.
Co-Authored-By: Claude Opus 5 <[email protected]>
cl.exe does not implement variable length arrays, and none of these ever holds more than the two address families the fast fallback resolves. The hints array only needed one live element at a time, so fill the entry in place instead.
Co-Authored-By: Claude Opus 5 <[email protected]>
Windows has neither SIGPIPE nor pthread_sigmask(3), so skip the masking there. The test-only resolution delay uses SleepEx() there, because Sleep() reaches rb_w32_Sleep() through the ruby DLL and waits through a Ruby thread this thread does not have.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Use rb_yjit_attached_object_is() for the compile-time attachment check.
It keeps the singleton flag test in C and returns only a boolean to Rust.
The predicate cannot raise, allocate, or take locks. Guard emission is
unchanged, and the IO exclusion stays in Rust.
longjmp() and C++ exceptions unwind JIT frames with RtlUnwindEx() as on x64, which fails with STATUS_BAD_FUNCTION_TABLE without unwind info.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
cl and clang-cl do not define __GNUC__, so rb_jit_icache_invalidate() compiled to nothing with cl and hit the #error with clang-cl, which defines __aarch64__.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This makes it so that we don't have to have a LIFO freelist like before.
Now, we hand out pages that are lower addresses in an arena instead of
handing out the latest released page. This is almost equivalent, but
should allow us to madvise larger chunks at a time and keep used pages
more tightly together.
The page pool used to thread its free lists through a word at offset 0
of each free body, with the arena back-pointer just past it and the "already
advised" flag stolen from the link's low bit. That made the head of every free
body live memory.
Now we keep the bookkeeping in the arena instead as a per-body struct holding
the freelist index, so that a free body is entirely dead memory. Reclaim now
advises whole bodies, and since it can walk them in address order it issues one
call per run of physically adjacent free heap pages: a fully free arena costs one
madvise rather than 32.
Also, delete the global hot list. It has been unreachable since PAGE_POOL_HOT_MAX
went to 0. With no hot or warm tier left, cold_freelist is just the freelist.
When a Hash key is a String subclass, both generators call its to_s.
generator.c raises a TypeError in convert_string_subclass if to_s
doesn't return a String. The Java generator passed the result on, then
fell back to TypeConverter.convertToType, which returned the key itself
because it already is a String. So JSON.generate(s => 1) produced
{"test":1} on JRuby instead of raising.
Raise the same TypeError, with the same message, in castKey. The class
names go through to_s like PRIsVALUE does, so anonymous classes show as
#<Class:0x...> the way they do on CRuby.
This lets test_string_subclass_with_broken_to_s run on JRuby.
Part of https://github.com/ruby/json/issues/1123https://github.com/ruby/json/commit/cf987b116d
* ZJIT: Rewrite Integer#upto in Ruby
* Match the C implementation in Ruby Integer#upto
Use `until from > to` so that it compares the same way as the C version,
including when `to` is NaN.
Raise ArgumentError when the comparator returns nil, like `ensure_cmp`.
Add tests for both cases.
* Remove the C implementation of Integer#upto
Define Integer#upto outside with_jit so that the interpreter also uses the Ruby version, and drop :c_trace.
If `git submodule update` fails after `git reset --hard` has populated
the destination, `GitProxy#installed_to?` considers the half-finished
checkout installed. When the error is rescued during `missing_specs?`,
the subsequent resolve then skips the checkout, never builds native
extensions, and `bundle install` exits successfully.
Remove the destination when `git reset --hard` or the submodule step
after it fails, before re-raising, so the next attempt checks out again
and the error reaches the user. A failed `reset --hard` can leave a
partially written tree that `installed_to?` would misjudge the same way.
https://github.com/ruby/rubygems/commit/cf89bb0c8c
Co-authored-by: AI (Pi/Claude Fable 5.1) <[email protected]>
Methods are defined under the VM lock once a second Ractor exists, and
debug builds fail "assert_critical_section_entered == 0" in
rb_vm_check_ints if the performance warning is emitted before it is
released. Cover redefining the method directly, from a refinement, and
from a prepended module.
Since add_refined_method_entry() is called from rb_method_entry_make()
under the VM lock, it has to collect the performance warning in the
caller's method_entry_warnings like the rest of rb_method_entry_make().
Otherwise refining an optimized method that the refined class defines
itself, such as
refine(Integer) { def +(other) end }
with Warning[:performance] enabled and a second Ractor around, warns with
the lock held and trips the critical section assertion in
rb_vm_check_ints.
The struct moves up so that add_refined_method_entry() can see its
members.
rb_vm_check_redefinition_opt_method() is called from rb_method_entry_make()
under the VM lock, where it must not call rb_category_warn(): that
dispatches Warning.warn and writes to $stderr, both of which can run
arbitrary Ruby code. When called with the lock held it now collects the
method entries to warn about, and rb_add_method() and friends emit the
"Redefining 'X#y' disables interpreter and JIT optimizations" warnings
once the lock is released.
Warning.warn can run arbitrary Ruby code, so it must not be called while
the VM lock is held. Once the process is in multi-ractor mode const_set
takes the lock, and a Warning.warn that waits on another Ractor which
needs the lock deadlocks if the warning is emitted under it. Debug builds
fail "assert_critical_section_entered == 0" in rb_vm_check_ints instead.
const_tbl_update() runs under the VM lock, where it must not call
rb_warn(): that dispatches Warning.warn and writes to $stderr, both of
which can run arbitrary Ruby code. It now records what to warn about,
and its callers emit the warning once the lock is released.
Since https://github.com/ruby/ruby/pull/15579, we are now able to use UTF-8
comments in C code, so we no longer need to have UTF-8 documentation in
separate files and use RDoc :include: directives.
Marshal.load uses load_arg to store state but wasn't marking the src string or
the proc. Usually not a problem because the caller would keep the string
alive. But when a Ractor.make_shareable falls back to using Marshal then nothing
keeps the dump string alive, so if GC either frees or moves the string during
the copy, then the loader holds a dangling pointer.
This commit marks the string and the proc.
Falling back from a platform row to the ruby gem the lockfile also locks printed the warning meant for platform gems installed from a lockfile that locks only their ruby version.
https://github.com/ruby/rubygems/commit/8c3973bb84
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A frozen bundle on a Ruby ABI missing from RUBY ABIS stopped at install and at Bundler.setup, although the platform or ruby gems the lockfile locks can still be installed. validate_platforms! lets a locked ruby platform through, so treat the Ruby ABI the same way. Once `bundle lock --add-ruby-abi` locks that Ruby's content-addressed gem, the platform gem the fallback installed no longer satisfies the platform row.
https://github.com/ruby/rubygems/commit/201d53c126
Co-Authored-By: Claude Opus 5.5 <[email protected]>
LEN2FIX expanded to RB_LEN2FIX, which was never defined, so an extension using it failed to build or load.
Co-Authored-By: Claude Opus 5.5 <[email protected]>