Socket.tcp_with_fast_fallback: Pass proper addr family to getaddrinfo
Addrinfo.getaddrinfo expects Socket::AF_INET or Socket::AF_INET6 as its
third argument (family). However Socket.tcp_with_fast_fallback was
incorrectly passing :ipv4 or :ipv6.
Repro:
require 'socket'
Socket.tcp_with_fast_fallback('example.com', 80, '127.0.0.1')
Expected behavior: Returns a Socket object
Actual: Raises unknown socket domain: ipv4 (SocketError)
This is the second part of making YJIT work with parallel GC.
During GC, `rb_yjit_iseq_mark` and `rb_yjit_iseq_update_references` need
to resolve offsets in `Block::gc_obj_offsets` into absolute addresses
before reading or updating the fields. This needs the base address
stored in `VirtualMemory::region_start` which was previously behind a
`RefCell`. When multiple GC threads scan multiple iseq simultaneously
(which is possible for some GC modules such as MMTk), it will panic
because the `RefCell` is already borrowed.
We notice that some fields of `VirtualMemory`, such as `region_start`,
are never modified once `VirtualMemory` is constructed. We change the
type of the field `CodeBlock::mem_block` from `Rc<RefCell<T>>` to
`Rc<T>`, and push the `RefCell` into `VirtualMemory`. We extract
mutable fields of `VirtualMemory` into a dedicated struct
`VirtualMemoryMut`, and store them in a field `VirtualMemory::mutable`
which is a `RefCell<VirtualMemoryMut>`. After this change, methods that
access immutable fields in `VirtualMemory`, particularly `base_ptr()`
which reads `region_start`, will no longer need to borrow any `RefCell`.
Methods that access mutable fields will need to borrow
`VirtualMemory::mutable`, but the number of borrowing operations becomes
strictly fewer than before because borrowing operations previously done
in callers (such as `CodeBlock::write_mem`) are moved into methods of
`VirtualMemory` (such as `VirtualMemory::write_bytes`).
Some GC modules, notably MMTk, support parallel GC, i.e. multiple GC
threads work in parallel during a GC. Currently, when two GC threads
scan two iseq objects simultaneously when YJIT is enabled, both threads
will attempt to borrow `CodeBlock::mem_block`, which will result in
panic.
This commit makes one part of the change.
We now set the YJIT code memory to writable in bulk before the
reference-updating phase, and reset it to executable in bulk after the
reference-updating phase. Previously, YJIT lazily sets memory pages
writable while updating object references embedded in JIT-compiled
machine code, and sets the memory back to executable by calling
`mark_all_executable`. This approach is inherently unfriendly to
parallel GC because (1) it borrows `CodeBlock::mem_block`, and (2) it
sets the whole `CodeBlock` as executable which races with other GC
threads that are updating other iseq objects. It also has performance
overhead due to the frequent invocation of system calls. We now set the
permission of all the code memory in bulk before and after the reference
updating phase. Multiple GC threads can now perform raw memory writes
in parallel. We should also see performance improvement during moving
GC because of the reduced number of `mprotect` system calls.
We were only avoiding them when the RUBYGEMS_GEMDEPS variable is used.
Avoid the warnings in general, whenever the entrypoint to Bundler is
`require`.
8683faef36
RubyGems generated binstubs still provide support for this ancient
version. This makes no sense since we prevent downgrades to such old
versions.
089cdc3b77
If you abort running test suite with a quick double Ctrl-C, tmp files
will be left around, and they will interfere with the next test run.
To avoid this, make sure to clear them once at the beginning of the test
suite.
### Before
```
$ bin/parallel_rspec
16 processes for 175 specs, ~ 11 specs per process
.............................................................................................^C^C
Finished in 19.45 seconds (files took 0.42722 seconds to load)
94 examples, 0 failures
(... turbo tests backtrace ...)
$ bin/parallel_rspec
16 processes for 175 specs, ~ 11 specs per process
.F....F....F...F......^C
Failures:
(... failures' details ...)
```
### After
```
$ bin/parallel_rspec
16 processes for 175 specs, ~ 11 specs per process
.................................................................................^C^C
Finished in 18.18 seconds (files took 0.4383 seconds to load)
82 examples, 0 failures
(... turbo tests backtrace ...)
$ bin/parallel_rspec
16 processes for 175 specs, ~ 11 specs per process
................................................................................^C^C
Finished in 8.79 seconds (files took 0.45187 seconds to load)
80 examples, 0 failures
(... turbo tests backtrace ...)
```
6767a52711
This is not currently causing any issues, but I think the most correct
thing to do is that Bundler loads the extensions to RubyGems in the
first place, so that they are available from the beginning.
88faa5c7bb