582 Commits

Author SHA1 Message Date
Luke Gruber
4fb537b1ee
Make tracepoints with set_trace_func or TracePoint.new ractor local (#15468)
Before this change, GC'ing any Ractor object caused you to lose all
enabled tracepoints across all ractors (even main). Now tracepoints are
ractor-local and this doesn't happen. Internal events are still global.

Fixes [Bug #19112]
2025-12-16 14:06:55 -05:00
John Hawthorn
32e6dc0f31 Speed up class allocator search
This rewrites the class allocator search to be faster. Instead of using
RCLASS_SUPER, which is now even slower due to Box, we can scan the
superclasses list to find a class where the allocator is defined.

This also disallows allocating from an ICLASS. Previously I believe that
was only done for FrozenCore, and that was changed in
e596cf6e93dbf121e197cccfec8a69902e00eda3.
2025-12-11 09:53:10 -08:00
Jeremy Evans
1e7cf7b2bc Fix refinement modification of method visibility in superclass
Previously, this didn't work correctly, resulting in a
SystemStackError. This fixes the issue by finding the related
superclass method entry, and updating the orig_me in the
refinement method to point to the superclass method.

Fixes [Bug #21446]
2025-12-10 06:19:52 +09:00
John Hawthorn
1d3fe2c382 Change bmethod defined_ractor to use id instead
When defining a bmethod, we recorded the current Ractor's object in the
method. However that was never marked and so could be GC'd and reused by
a future Ractor. Instead we can use the Ractor's id, which we expect to
be unique forever.

Co-authored-by: Luke Gruber <luke.gru@gmail.com>
2025-12-04 13:25:45 -08:00
Peter Zhu
bcfcfedc30 Fix memory leak in invalidate_ccs_in_iclass_cc_tbl
invalidate_ccs_in_iclass_cc_tbl deletes the ccs from the table but never
frees it, causing memory to leak.
2025-11-12 03:48:59 -08:00
Nobuyoshi Nakada
a4dff09be7
[Bug #21673] Fix resolving refined module-defined method
A method defined in a module has no `defined_class`, use the ICLASS
for it as the `defined_class`.
2025-11-09 16:39:38 +09:00
Satoshi Tagomori
d2a587c791 renaming internal data structures and functions from namespace to box 2025-11-07 13:14:54 +09:00
Peter Zhu
b66fbd59ae Make rb_vm_ccs_invalidate_and_free static 2025-10-26 15:27:14 -04:00
Koichi Sasada
bc00c4468e use SET_SHAREABLE
to adopt strict shareable rule.

* (basically) shareable objects only refer shareable objects
* (exception) shareable objects can refere unshareable objects
  but should not leak reference to unshareable objects to Ruby world
2025-10-23 13:08:26 +09:00
Peter Zhu
14cdd88970 [Bug #21620] Fix strict aliasing in rb_managed_id_table_lookup
We cannot pass &ccs into rb_managed_id_table_lookup because rb_managed_id_table_lookup
takes in a VALUE*, so it violates strict aliasing in C. This causes segfaults
when compiling with LTO enabled.
2025-10-03 09:20:53 -04:00
Alan Wu
328d2037a6 ZJIT: Remove dead CMEs from Invariants 2025-09-25 18:36:58 -04:00
John Hawthorn
4afc6370cb Add missing locks to method table 2025-09-22 09:59:35 -07:00
Takashi Kokubun
51cd877636 ZJIT: Add missing rb_zjit_cme_invalidate 2025-08-28 15:46:16 -07:00
John Hawthorn
823d55a827 Add lock-free fastpath to callable_method_entry... 2025-08-21 15:42:14 -07:00
Jeremy Evans
acb29f7fa1 Do not respect ruby2_keywords on method/proc with post arguments
Previously, ruby2_keywords could be used on a method or proc with
post arguments, but I don't think the behavior is desired:

```ruby
def a(*c, **kw) [c, kw] end
def b(*a, b) a(*a, b) end
ruby2_keywords(:b)

b({foo: 1}, bar: 1)
```

This changes ruby2_keywords to emit a warning and not set the
flag on a method/proc with post arguments.

While here, fix the ruby2_keywords specs for warnings, since they
weren't testing what they should be testing.  They all warned
because the method didn't accept a rest argument, not because it
accepted a keyword or keyword rest argument.
2025-08-22 00:46:57 +09:00
John Hawthorn
feb8331673 Atomic CC table set in cache_callable_method_entry 2025-08-21 09:17:31 +02:00
Peter Zhu
2c7ec3d155 Fix race condition in method invalidation for Ractors
We lock the VM to invalidate method entries. However, we do not lock the
VM to call methods, so it's possible that during a method call the method
entry gets invalidated. We only check that the method entry in the callcache
is not invalidated at the beginning of the method call, which makes it
possible to have race conditions. This causes crashes like:

    vm_callinfo.h:421: Assertion Failed: vm_cc_cme:cc->klass != Qundef || !vm_cc_markable(cc)
    vm_insnhelper.c:2200: Assertion Failed: vm_lookup_cc:!METHOD_ENTRY_INVALIDATED(vm_cc_cme(ccs_cc))

This commit adds a VM barrier to method cache invalidation to ensure that
other Ractors are stopped at a safe-point before invalidating the method
entry.
2025-08-20 15:53:00 -04:00
Peter Zhu
9d484e3412 Fix indentation in clear_method_cache_by_id_in_class [ci skip] 2025-08-20 10:57:47 -04:00
John Hawthorn
c41c323f1a
Invalidate CCs when cme is invalidated in marking
* Skip assertion when cc->klass is Qundef
* Invalidate CCs when cme is invalidated in marking
* Add additional assertions that CC references stay valid

Co-authored-by: Peter Zhu <peter@peterzhu.ca>
2025-08-07 15:39:45 -07:00
John Hawthorn
faa67506e5 Ensure CC entries always marked, add missing WB
Previously we were issuing writebarriers for each cc, but were missing
the cme.

We also need to avoid it being possible to run GC after we've copied the
values into the allocated array, but before they're visible in the
object.
2025-08-01 13:45:29 -07:00
Jean Boussier
bc789ca804 Convert rb_class_cc_entries.entries in a flexible array member
`rb_class_cc_entries` is little more than a `len` and `capa`.
Hence embedding the entries doesn't cost much extra copying and
saves a bit of memory and some pointer chasing.

Co-Authored-By: Étienne Barrié <etienne.barrie@gmail.com>
2025-08-01 19:49:38 +02:00
Jean Boussier
547f111b5b Refactor vm_lookup_cc to allow lock-free lookups in RClass.cc_tbl
In multi-ractor mode, the `cc_tbl` mutations use the RCU pattern,
which allow lock-less reads.

Based on the assumption that invalidations and misses should be
increasingly rare as the process ages, locking on modification
isn't a big concern.
2025-08-01 10:42:04 +02:00
Jean Boussier
f2a7e48dea Make RClass.cc_table a managed object
For now this doesn't change anything, but now that the table
is managed by GC, it opens the door to use RCU when in multi-ractor
mode, hence allow unsynchornized reads.
2025-08-01 10:42:04 +02:00
Jean Boussier
fc5e1541e4 Use rb_gc_mark_weak for cc->klass.
One of the biggest remaining contention point is `RClass.cc_table`.
The logical solution would be to turn it into a managed object, so
we can use an RCU strategy, given it's read heavy.

However, that's not currently possible because the table can't
be freed before the owning class, given the class free function
MUST go over all the CC entries to invalidate them.

However if the `CC->klass` reference is weak marked, then the
GC will take care of setting the reference to `Qundef`.
2025-08-01 10:42:04 +02:00
Takashi Kokubun
2cd10de330
ZJIT: Prepare for sharing JIT hooks with ZJIT (#14044) 2025-07-30 10:11:10 -07:00
Stan Lo
a0d0b84bad
ZJIT: Support invalidating constant patch points (#13998) 2025-07-28 14:48:41 -07:00
Stan Lo
8df61bfc92
ZJIT: Support invalidating on method redefinition (#13875)
ZJIT: Support invalidating method redefinition

This commit adds support for the MethodRedefined invariant to be invalidated
when a method is redefined.

Changes:
- Added CME pointer to the MethodRedefined invariant in HIR
- Updated all places where MethodRedefined invariants are created to
    include the CME pointer
- Added handling for MethodRedefined invariants in gen_patch_point to
    call track_cme_assumption, which registers the patch point for
    invalidation when rb_zjit_cme_invalidate is called

This ensures that when a method is redefined, all JIT code that
depends on that method will be properly invalidated.
2025-07-18 15:36:51 +00:00
Vinicius Stock
d1f38ce4ac
Make protected documentation more explicit about differences (#13849)
[DOC] Make protected documentation more explicit about differences

Protected is a common source of confusion for devs
coming from different languages to Ruby. This
commit makes the documentation more explicit about
the differences, so that the use case for
protected is clearer.
2025-07-17 12:19:51 -07:00
Jeremy Evans
08d4f7893e Rename some set_* functions to set_table_*
These functions conflict with the planned C-API functions. Since they
deal with the underlying set_table pointers and not Set instances,
this seems like a more accurate name as well.
2025-07-11 15:24:23 +09:00
John Hawthorn
581da51cb5 Fix whitespace on some RB_VM_LOCKING calls 2025-07-09 17:28:47 -07:00
Luke Gruber
3c66eb3358 Change def->method_serial to be atomic
`rb_method_definition_create` can be called across different ractors at the same time, so `def->method_serial` should be atomic.
2025-06-25 15:43:57 -07:00
alpaca-tc
c8ddc0a843 Optimize callcache invalidation for refinements
Fixes [Bug #21201]

This change addresses a performance regression where defining methods
inside `refine` blocks caused severe slowdowns. The issue was due to
`rb_clear_all_refinement_method_cache()` triggering a full object
space scan via `rb_objspace_each_objects` to find and invalidate
affected callcaches, which is very inefficient.

To fix this, I introduce `vm->cc_refinement_table` to track
callcaches related to refinements. This allows us to invalidate
only the necessary callcaches without scanning the entire heap,
resulting in significant performance improvement.
2025-06-09 12:33:35 +09:00
git
aa00a2d07b * remove trailing spaces. [ci skip] 2025-05-26 02:44:58 +00:00
Nobuyoshi Nakada
aad9fa2853
Use RB_VM_LOCKING 2025-05-25 15:22:43 +09:00
Satoshi Tagomori
382645d440 namespace on read 2025-05-11 23:32:50 +09:00
Alan Wu
dd0e0eb4ac Delete always true assert [ci skip] 2025-05-02 21:06:11 +09:00
Jean Boussier
c0417bd094 Use set_table to track const caches
Now that we have a `set_table` implementation, we can
use it to track const caches and save some memory.

We could even save some more memory if `numtable` didn't
store a copy of the `hash` and instead recomputed it every
time, but this is a quick win.
2025-04-26 12:10:32 +02:00
Nobuyoshi Nakada
c218862d3c
Fix style [ci skip] 2025-04-19 22:02:10 +09:00
John Hawthorn
bfe6068417 Use atomic for method reference count [Bug #20934]
This changes reference_count on rb_method_definition_struct into an
atomic.

Ractors can create additional references as part of `bind_call` or
(presumably) similar. Because this can be done inside Ractors, we should
use a lock or atomics so that we don't race and avoid incrementing.

Co-authored-by: wanabe <s.wanabe@gmail.com>
2025-03-20 13:09:40 -07:00
Nobuyoshi Nakada
4a67ef09cc
[Feature #21116] Extract RJIT as a third-party gem 2025-02-13 18:01:03 +09:00
Fabio Sangiovanni
f0dc9dcdc7 rb_alias: improve "undefined method" error message by invoking
`rb_print_undef` with `target_klass` as argument.
2025-01-31 00:20:47 +09:00
Alan Wu
ce849d565b
ruby2_keywords warnings: Quote non-UTF8 method names fully
It used to quote only part of the method name because NUL byte in
the method terminates the C string:

```
(irb)> "abcdef".encode("UTF-16LE").bytes
=> [97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0]
```

```
expected: /abcdef/
actual: warning: Skipping set of ruby2_keywords flag for a (method not defined in Ruby)\n".
```
2024-12-19 10:32:14 -05:00
Peter Zhu
a58675386c Prefix asan_poison_object with rb 2024-12-19 09:14:34 -05:00
John Hawthorn
f1dda5ed01 Warn when redefining __id__ as well as object_id
[Feature #20912]
2024-11-29 20:41:00 -08:00
Matt Valentine-House
551be8219e Place all non-default GC API behind USE_SHARED_GC
So that it doesn't get included in the generated binaries for builds
that don't support loading shared GC modules

Co-Authored-By: Peter Zhu <peter@peterzhu.ca>
2024-11-25 13:05:23 +00:00
Peter Zhu
56ecc243e2 [Bug #20868] Fix Method#hash to not change after compaction
The hash value of a Method must remain constant after a compaction, otherwise
it may not work as the key in a hash table.

For example:

    def a; end

    # Need this method here because otherwise the iseq may be on the C stack
    # which would get pinned and not move during compaction
    def get_hash
      method(:a).hash
    end

    puts get_hash # => 2993401401091578131

    GC.verify_compaction_references(expand_heap: true, toward: :empty)

    puts get_hash # => -2162775864511574135
2024-11-06 10:34:20 -05:00
Takashi Kokubun
478e0fc710
YJIT: Replace Array#each only when YJIT is enabled (#11955)
* YJIT: Replace Array#each only when YJIT is enabled

* Add comments about BUILTIN_ATTR_C_TRACE

* Make Ruby Array#each available with --yjit as well

* Fix all paths that expect a C location

* Use method_basic_definition_p to detect patches

* Copy a comment about C_TRACE flag to compilers

* Rephrase a comment about add_yjit_hook

* Give METHOD_ENTRY_BASIC flag to Array#each

* Add --yjit-c-builtin option

* Allow inconsistent source_location in test-spec

* Refactor a check of BUILTIN_ATTR_C_TRACE

* Set METHOD_ENTRY_BASIC without touching vm->running
2024-11-04 11:14:28 -05:00
Koichi Sasada
783dde2159 alias should not set defined_class for Modules
`me->defined_class` should be 0 for method entries of
Modules.

This patch checks this condition
and fix https://github.com/ruby/ruby/pull/11965#issuecomment-2448291790
2024-11-01 11:50:00 +09:00
Nobuyoshi Nakada
abfefd8e0c
Define VM_ASSERT_TYPE macros 2024-10-31 22:12:16 +09:00
Nobuyoshi Nakada
eb1e1d99b7
Detail the failing assertion [ci skip] 2024-10-30 14:48:21 +09:00