544 Commits

Author SHA1 Message Date
Peter Zhu
6939f03f4c Add field handle_weak_references to TypedData
This commit adds a field handle_weak_references to rb_data_type_struct for
the callback when handling weak references. This avoids TypedData objects
from needing to expose their rb_data_type_struct and weak references function.
2026-01-04 09:02:40 -05:00
Peter Zhu
eaa83e505f Always allocate Fiber objects in Thread
Currently, root fibers of threads do not have a corresponding Ruby object
backing it by default (it does have one when an object is required, such
as when Fiber.current is called). This is a problem for the new GC weak
references design in #12606 since Thread is not declared as having weak
references but it does hold weak references (the generic ivar cache).

This commit changes it to always allocate a Fiber object for the root
fiber.
2025-12-28 08:55:38 -05:00
Peter Zhu
57637827e6 Implement cont using declare weak references 2025-12-25 09:18:17 -05:00
Peter Zhu
0c07a4246c Implement weak references on gen fields cache 2025-12-25 09:18:17 -05:00
Victor Shepelev
ec4ca91319
Small documentation adjustments for new/updated features (#15634)
* Document Range#to_set

* Update Thread#raise and Fiber#raise signatures and docs

* Add reference to String#strip to character_selectors.rdoc

* Update *nil docs when calling methods

* Enhance Array#find and #rfind docs

* Add a notice to Kernel#raise about cause:
2025-12-20 13:07:38 +02:00
Jean Boussier
e42bcd7ce7 Rename fiber_serial into ec_serial
Since it now live in the EC.
2025-12-16 09:51:07 +01:00
Jean Boussier
28b195fc67 Store the fiber_serial in the EC to allow inlining
Mutexes spend a significant amount of time in `rb_fiber_serial`
because it can't be inlined (except with LTO).
The fiber struct is opaque the so function can't be defined as inlineable.

Ideally the while fiber struct would not be opaque to the rest of
Ruby core, but it's tricky to do.

Instead we can store the fiber serial in the execution context
itself, and make its access cheaper:

```
$ hyperfine './miniruby-baseline --yjit /tmp/mut.rb' './miniruby-inline-serial --yjit /tmp/mut.rb'
Benchmark 1: ./miniruby-baseline --yjit /tmp/mut.rb
  Time (mean ± σ):      4.011 s ±  0.084 s    [User: 3.977 s, System: 0.011 s]
  Range (min … max):    3.950 s …  4.245 s    10 runs

Benchmark 2: ./miniruby-inline-serial --yjit /tmp/mut.rb
  Time (mean ± σ):      3.495 s ±  0.150 s    [User: 3.448 s, System: 0.009 s]
  Range (min … max):    3.340 s …  3.869 s    10 runs

Summary
  ./miniruby-inline-serial --yjit /tmp/mut.rb ran
    1.15 ± 0.05 times faster than ./miniruby-baseline --yjit /tmp/mut.rb
```

```ruby
i = 10_000_000
mut = Mutex.new
while i > 0
  i -= 1
  mut.synchronize { }
  mut.synchronize { }
  mut.synchronize { }
  mut.synchronize { }
  mut.synchronize { }
  mut.synchronize { }
  mut.synchronize { }
  mut.synchronize { }
  mut.synchronize { }
  mut.synchronize { }
end
```
2025-12-16 09:51:07 +01:00
Benoit Daloze
965ae7f386 Fix typo in Fiber.[] docs 2025-12-11 15:58:23 +01:00
Sharon Rosner
5f6b31c23f
Correctly handle Process.fork with an active Fiber.scheduler. (#15385)
In the child process, nullify the current fiber scheduler and set the current fiber to blocking.
2025-12-05 18:20:39 +13:00
Samuel Williams
bc9ea585be
Add rb_ec_close function to manage execution context cleanup. (#15253) 2025-12-01 04:49:31 +00:00
John Hawthorn
4263f1d718 Store fiber serial as Ractor-local 2025-11-25 13:48:35 -08:00
John Hawthorn
ff1d23eccb Use a serial to keep track of Mutex-owning Fiber
Previously this held a pointer to the Fiber itself, which requires
marking it (which was only implemented recently, prior to that it was
buggy). Using a monotonically increasing integer instead allows us to
avoid having a free function and keeps everything simpler.

My main motivations in making this change are that the root fiber lazily
allocates self, which makes the writebarrier implementation challenging
to do correctly, and wanting to avoid sending Mutexes to the remembered
set when locked by a short-lived Fiber.
2025-11-20 14:06:33 -08:00
Luke Gruber
27ff586152 We can't grab the VM Lock in free functions
This is due to the way MMTK frees objects, which is on another native thread.
Due to this, there's no `ec` so we can't grab the VM Lock.

This was causing issues in release builds of MMTK on CI like:

```
  /home/runner/work/ruby/ruby/build/ruby(sigsegv+0x46) [0x557905117ef6] ../src/signal.c:948
  /lib/x86_64-linux-gnu/libc.so.6(0x7f555f845330) [0x7f555f845330]
  /home/runner/work/ruby/ruby/build/ruby(rb_ec_thread_ptr+0x0) [0x5579051d59d5] ../src/vm_core.h:2087
  /home/runner/work/ruby/ruby/build/ruby(rb_ec_ractor_ptr) ../src/vm_core.h:2036
  /home/runner/work/ruby/ruby/build/ruby(rb_current_execution_context) ../src/vm_core.h:2105
  /home/runner/work/ruby/ruby/build/ruby(rb_current_ractor_raw) ../src/vm_core.h:2104
  /home/runner/work/ruby/ruby/build/ruby(rb_current_ractor) ../src/vm_core.h:2112
  /home/runner/work/ruby/ruby/build/ruby(rb_current_ractor) ../src/vm_core.h:2110
  /home/runner/work/ruby/ruby/build/ruby(vm_locked) ../src/vm_sync.c:15
  /home/runner/work/ruby/ruby/build/ruby(rb_vm_lock_enter_body) ../src/vm_sync.c:141
  /home/runner/work/ruby/ruby/build/ruby(rb_vm_lock_enter+0xa) [0x557905390a5a] ../src/vm_sync.h:76
  /home/runner/work/ruby/ruby/build/ruby(fiber_pool_stack_release) ../src/cont.c:777
  /home/runner/work/ruby/ruby/build/ruby(fiber_stack_release+0xe) [0x557905392075] ../src/cont.c:919
  /home/runner/work/ruby/ruby/build/ruby(cont_free) ../src/cont.c:1087
  /home/runner/work/ruby/ruby/build/ruby(fiber_free) ../src/cont.c:1180
```

This would have ran into an assertion error in a debug build but we don't run debug builds of MMTK on Github's CI.

Co-authored-by: john.hawthorn@shopify.com
2025-10-15 10:49:37 -07:00
Samuel Williams
64f508ade8
Support cause: in Thread#raise and Fiber#raise. (#13967)
* Add support for `cause:` argument to `Fiber#raise` and `Thread#raise`.

The implementation behaviour is consistent with `Kernel#raise` and
`Exception#initialize` methods, allowing the `cause:` argument to be
passed to `Fiber#raise` and `Thread#raise`. This change ensures that
the `cause:` argument is handled correctly, providing a more consistent
and expected behavior when raising exceptions in fibers and threads.

[Feature #21360]

* Shared specs for Fiber/Thread/Kernel raise.

---------

Co-authored-by: Samuel Williams <samuel.williams@shopify.com>
2025-07-24 14:45:43 +12:00
Luke Gruber
5b3f1c4c51 Take VM lock around manipulation of fiber pool for vacant stacks
When creating fibers in multiple ractors at the same time there were
issues with the manipulation of this structure, causing segfaults.

I didn't add any tests for this because I'm making a more general
PR in the very near future to be able to run test methods (test-all suite)
inside multiple ractors at the same time. This is how this bug was
caught, running test/ruby/test_fiber.rb inside 10 ractors at once.
2025-05-29 12:51:43 -04:00
刘皓
6874b289a1 Free jump buffers leaked by cont_restore_thread in WASI builds 2025-04-27 15:47:30 +09:00
刘皓
372515f33c Don't set saved_ec.tag to NULL in cont_init() 2025-03-31 11:59:33 +09:00
刘皓
3a730be8b4 Fix jump buffer leak in setjmp handler in WASI builds 2025-03-31 11:59:33 +09:00
Yuta Saito
eac35edfd1 [wasm] Stop using mprotect(PROT_NONE) on WASI
we had been using a stub weak definition of `mprotect` in wasm/missing.c
so far, but wasi-sdk 23 added mprotect emulation to wasi-libc[^1], so the
emulation is now linked instead. However, the emulation doesn't support
PROT_NONE and fails with ENOSYS, so we need to avoid calling mprotect
completely on WASI.

[^1]: 7528b13170
2025-02-19 11:46:12 +09:00
Nobuyoshi Nakada
4a67ef09cc
[Feature #21116] Extract RJIT as a third-party gem 2025-02-13 18:01:03 +09:00
Kerrick Long
4cfc904d97 [DOC] Fix article-noun agreement 2025-01-30 18:45:29 +09:00
Lars Kanis
142001cd64 Fix callcc on Windows on ARM64
Otherwise using callcc fails with a segfault for instance in this test case:
  TestEnsureAndCallcc#test_bug20655_extension_using_rb_ensure
2025-01-16 19:19:46 +09:00
Nobuyoshi Nakada
51d3f6459b
[DOC] Hide Fiber::Pool
It is experimental yet and is disabled currently.
2024-12-25 11:25:03 +09:00
Nobuyoshi Nakada
adad97a031
[Bug #20978] Stringize Fiber storage keys 2024-12-23 18:16:28 +09:00
John Hawthorn
018b775039 FREE_AT_EXIT: Free all allocations from fiber pool
The fiber pool allocations form a singly-linked list, so when we're
running with RUBY_FREE_AT_EXIT we need to walk the linked list freeing
each element, otherwise it can be detected as a memory leak.
2024-12-20 14:21:57 -08:00
Nobuyoshi Nakada
d07aa670b4
Get rid of duplicate modifier for MSVC 2024-12-18 21:49:37 +09:00
Nobuyoshi Nakada
42b1eaf234 Mark fiber_entry no-return 2024-11-27 10:47:40 +09:00
Kunshan Wang
8ae7c22972 Annotate anonymous mmap
Use PR_SET_VMA_ANON_NAME to set human-readable names for anonymous
virtual memory areas mapped by `mmap()` when compiled and run on Linux
5.17 or higher.  This makes it convenient for developers to debug mmap.
2024-11-21 13:48:05 -05:00
Yusuke Endoh
ac5ac48a36 Revert 28a1c4f33e3349a98c04b8e068d9c674eb936064
28a1c4f33e3349a98c04b8e068d9c674eb936064 seems to call an improper
ensure clause. [Bug #20655]
Than fixing it properly, I bet it would be much better to simply revert
that commit. It reduces the unneeded complexity. Jumping into a block
called by a C function like Hash#each with callcc is user's fault.
It does not need serious support.
2024-07-30 15:31:24 +09:00
Peter Zhu
214811974b Add ruby_mimcalloc
Many places call ruby_mimmalloc then MEMZERO. This can be reduced by
using ruby_mimcalloc instead.
2024-04-24 15:30:43 -04:00
Samuel Williams
6ade36c06b
Fiber#raise recursively raises on nested resuming_fiber. (#10482)
* Improve consistency of `Fiber.current.raise`.
2024-04-17 23:08:47 +12:00
Samuel Williams
5d1702e01a
Enumerator should use a non-blocking fiber, change rb_fiber_new to be non-blocking by default. (#10481) 2024-04-08 00:49:01 +12:00
Samuel Williams
b473d304d4
Revert "Enumerator should use a non-blocking fiber. (#10478)" (#10480)
This reverts commit dfa0897de89251a631a67460b941cd24a14c9b55.

This commit accidentally included some change in `parse.h`. Reverting
and re-applying the relevant changes.
2024-04-07 10:20:22 +00:00
Samuel Williams
dfa0897de8
Enumerator should use a non-blocking fiber. (#10478) 2024-04-07 19:18:09 +12:00
KJ Tsanaktsidis
69579ed57a Mark fiber stacks in rb_execution_context_mark
Currently, fiber stacks are marked separately from the rest of the
execution context. The fiber code deliberately does _NOT_ set
ec->machine.stack_end on the saved EC, so that the code in
`rb_execution_context_mark` does not mark it; instead, the stack marking
is done in `cont_mark`.

Instead, we can set ec->machine.stack_end, and skip out on doing the
stack marking separately in `cont_mark`; that way, all machine stack
marking shares the same code (which does the nescessary ASAN things).

[Bug #20310]
2024-03-25 14:57:04 +11:00
Jean Boussier
8a8df49174 Update set_backtrace documentation
Followup: https://github.com/ruby/ruby/pull/10017

[Feature #13557]
2024-03-18 08:55:46 +01:00
KJ Tsanaktsidis
5621d794a2 Disable callcc when ASAN is enabled
callcc's implementation is fundamentally incompatible with ASAN. Since
callcc is deprecated and almost never used, it's probably OK to disable
callcc when ruby is compiled with ASAN.

[Bug #20273]
2024-03-04 13:07:26 +11:00
Nobuyoshi Nakada
c30b8ae947
Adjust styles and indents [ci skip] 2024-01-08 00:50:41 +09:00
John Hawthorn
f1b7424cbe FREE_AT_EXIT: Don't free main stack post-fork
When a forked process was started in a thread, this would result in a
double-free during the child process exit.

    RUBY_FREE_AT_EXIT=1 ./miniruby -e 'Thread.new { fork { } }.join; Process.waitpid'

This is because the main thread in the forked process was not the
initial VM thread, and the new thread's stack was freed as part of
objectspace iteration.

This change also allows rb_threadptr_root_fiber_release to run without
EC being available.
2023-12-22 18:07:22 -08:00
Victor Shepelev
07734b51c6
[DOC] Small fixes for documentation rendering
Mostly just fixing RDoc's incorrect treatment of `+`
2023-12-09 13:54:33 +09:00
Benoit Daloze
0204523fe7 Improve Fiber#kill docs and simplify the NEWS entry to let the documentation explain 2023-12-08 13:59:40 +01:00
Adam Hess
6816e8efcf Free everything at shutdown
when the RUBY_FREE_ON_SHUTDOWN environment variable is set, manually free memory at shutdown.

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
Co-authored-by: Peter Zhu <peter@peterzhu.ca>
2023-12-07 15:52:35 -05:00
Takashi Kokubun
ba1cdadfc8
YJIT: Cancel on-stack jit_return on invalidation (#9086)
* YJIT: Cancel on-stack jit_return on invalidation

Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>

* Use RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P

---------

Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
2023-11-30 21:35:55 -05:00
Takashi Kokubun
985370406d Call rb_jit_cont_init() even earlier
To fix https://github.com/ruby/ruby/actions/runs/6581593578/job/17881779994
2023-10-19 17:12:09 -07:00
Takashi Kokubun
a9d7525fb4 Avoid initializing jit_cont_lock multiple times
Contrary to my initial assumption, rb_threadptr_root_fiber_setup() is
called for each Ractor, not just once at boot. I changed the place to
call rb_jit_cont_init() to avoid calling it multiple times.
2023-10-19 17:06:23 -07:00
Takashi Kokubun
6beb09c2c9
YJIT: Add RubyVM::YJIT.enable (#8705) 2023-10-19 10:54:35 -07:00
Samuel Williams
d4c720a91b
Fix support for dynamic keys. (#8273)
* Skip RBS test.
2023-08-24 15:19:33 +12:00
Nobuyoshi Nakada
5336b2f0db
Move a local variable declaration after the protected region 2023-08-03 13:43:04 +09:00
Samuel Williams
be86767eef
Add VM_ASSERT on fiber->blocking == 0. (#7926)
I have not seen any problems with this code, but this ensures the invariant.
2023-06-10 23:13:01 +09:00
Samuel Williams
492e0025fd
Allow environment variable to control madvise advice. (#7855)
Introduce experimental support for explicitly specifying the `advice` value provided to `madvise` when releasing the fiber stack.
2023-05-25 11:17:49 +09:00