636 Commits
Author SHA1 Message Date
Luke Gruber ae2c6841c4 Don't create CCs for methods we assume are cold
The assumption is that we're usually calling these methods on boot, and they don't
need CCs. CCs scale with the number of classes that use these methods in the app, so
if you have 10k classes and these classes use 3 of these methods on average, then that
saves 30k CC objects.

Methods on Module that are marked cold are:

public, protected, private, module_function, ruby2_keywords, alias_method, undef_method,
remove_method, attr_reader, attr_writer, attr_accessor, include, prepend.

If these methods ever get redefined, they get new method definitions that are not
marked uncacheable (CCs will get created).

In one of our apps (not the largest), we observed this difference after boot:

| method            | before | after | delta       |
|-------------------|-------:|------:|------------:|
| `include`         |   4518 |     2 |       -4516 |
| `alias_method`    |   3921 |     0 |       -3921 |
| `ruby2_keywords`  |   3784 |     0 |       -3784 |
| `private`         |   3519 |     3 |       -3516 |
| `attr_reader`     |   2738 |     0 |       -2738 |
| `attr_accessor`   |   2288 |     0 |       -2288 |
| `prepend`         |    354 |     1 |        -353 |
| `protected`       |    303 |     0 |        -303 |
| `public`          |    302 |     0 |        -302 |
| `undef_method`    |    178 |     0 |        -178 |
| `attr_writer`     |    124 |     0 |        -124 |
| `module_function` |     42 |     0 |         -42 |
| `remove_method`   |     24 |     0 |         -24 |
| **total**         |        |       | **-22,089** |

NOTE: CC tables and ccs (the malloced struct) are still being created, so this only reduces
the CC objects themselves. I will tackle that in a follow-up.
2026-10-27 09:49:20 -04:00
John Hawthorn 2500ab0668 Don't call rb_add_method with the VM lock held when refining
Defining a method in a refinement makes rb_method_entry_make (VM lock held)
add an entry to the refined class by calling rb_add_method. rb_add_method must
be called without the VM lock: it asserts that, and emits warnings, which can
run Ruby code, after its critical section. With a second Ractor around that
tripped ASSERT_vm_unlocking and called rb_warn with the lock held (e.g.
refine(Object) { def respond_to? }).

Add the entry with rb_method_entry_make directly and let it store its warnings
in the caller's struct, so the outermost rb_add_method emits them after
unlocking. Every warning is still emitted; the 'object_id' and '__send__'
ones, which used to be emitted twice, now once.
2026-10-21 16:40:46 -07:00
Jeremy EvansandShugo Maeda e2e8646718 Make send and symbol procs work with super in refined module methods
Co-authored-by: Shugo Maeda <shugo@ruby-lang.org>
2026-10-10 01:14:57 -07:00
Hiroshi SHIBATAandClaude Opus 5 975c2a45f1 Use rb_len_t for Array and String lengths in the VM
Argument counts stay `int` or `long`. The int range checks in proc.c and compile.c now depend on SIZEOF_VALUE so that they are kept once rb_len_t widens.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-09 14:00:15 +09:00
Luke Gruber 4eed7d64ea Don't call Ruby code in rb_method_definition_eq
During method aliasing, we check if the methods `a` and `b` are equal
before aliasing. If they are equal, we don't need to alias. That check
was running Ruby code with the VM lock held when the first method was a
bmethod, which is not good and can cause incorrect behavior. Now, we call
`rb_proc_eq` directly. This means an override of `Proc#==` will not be
called to check if 2 methods are equal and will instead use the definition
of Proc equality at VM startup. `Method#==` and `UnboundMethod==` will
also not call into `Proc#==` now for bmethods. This is probably better behavior
even without the VM lock fix because `Method#hash` never called `Proc#hash` when
the method was a bmethod, it used `rb_hash_proc` directly.

Fixes [Bug #22398]
2026-10-02 09:35:13 -04:00
Shugo MaedaandClaude Fable 5.1 e45f082e39 Keep the refinement call cache set pinned while inserting into it
dd7be7ce69 re-read the embedded data pointer of vm->cc_refinement_set
after the realloc that may move the set.  Keep the set on the stack
with RB_GC_GUARD instead, as id_table.c does for managed id tables, so
that the pointer stays valid for the whole insertion.

https://bugs.ruby-lang.org/issues/22397

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-30 23:31:51 +09:00
Shugo MaedaandClaude Fable 5.1 dd7be7ce69 Re-read the refinement call cache set after growing it
rb_vm_insert_cc_refinement() kept a pointer into the embedded data of
vm->cc_refinement_set across the realloc of its entries.  Under
GC.stress, ruby_xrealloc2_sized() runs a GC first, and when that GC
compacts and moves the set, the new buffer and capacity are written to
the abandoned slot while the moved set keeps the freed buffer.  The next
growth then reallocates freed memory, or the weak reference pass of the
next GC walks it.

[Bug #22397]

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-30 20:53:44 +09:00
Nobuyoshi Nakada 753e64f352 Merge alias definition and registration
Also, make `lazy_use_super_method` hash `compare_by_identity` since
all the keys are symbols, .
2026-09-29 17:35:03 +09:00
Shugo MaedaandClaude Fable 5.1 611bb146b0 [Feature #22304] Add rb_warn_to_remove_at and rb_warn_scheduled_deprecation
rb_warn_deprecated_to_remove_at warns only when Warning[:deprecated]
is enabled, so a deprecation scheduled to warn by default in a later
version needed a hand-written rb_warn and a separate commit to switch.

rb_warn_to_remove_at emits the same message with rb_warn and no
category.  rb_warn_scheduled_deprecation(X.Y, X.Z, ...) selects
between the two at compile time by RUBY_API_VERSION_CODE: gated by
Warning[:deprecated] before X.Y, shown by default from X.Y, and a
compile error in RUBY_DEBUG builds at X.Z, like the existing removal
check.  ruby/version.h is now included unconditionally and RUBY_VERSION_SINCE
and the version-string macros are always defined for that, while the
compile-time checks and RBIMPL_TODO stay RUBY_DEBUG only.  Both
functions are exported so that the new -test-/warning extension can
exercise both phases.

Use it for the two alias deprecations in rb_alias, which are scheduled
to warn by default in 4.2 and to be removed in 4.3.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-24 20:33:14 +09:00
Stan Lo 420a1deef3 [DOC] Add no argument example to module_function's doc (#18962) 2026-09-23 10:17:56 +01:00
Jeremy Evans 1c13d07cfc Emit deprecation warning for aliasing method in prepended module
Aliasing a method in a prepended module can result in a super
call going into a descendant instead of an ancestor. Removal plan:

4.1: Deprecation warning
4.2: Warning even in non-verbose mode
4.3: Removal (target method lookup starts at origin class)

Fixes [Bug #22273]
2026-09-17 18:29:51 -07:00
Shugo MaedaandClaude Fable 5 1c0b1be076 Deprecate the fallback to Object for alias in a module
`alias` and `Module#alias_method` in a module fall back to searching
the method from Object when the module and its ancestors do not have
it. The fallback assumes Object is the root class, which is no longer
true since BasicObject was introduced in 1.9, so Matz decided to
remove it. As the first step, warn in verbose mode when the fallback
is used; the plan is to warn unconditionally in 4.2 and to raise
NameError in 4.3.

https://bugs.ruby-lang.org/issues/22276

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-17 12:37:38 +09:00
Luke Gruber a00df45480 Add assertions that interrupts aren't checked when VM lock taken. (#18832) 2026-09-15 16:23:10 +12:00
Jean Boussier fad4751ae2 Module#method_defined? optional arguments to also match private method
[Feature #22297]

When generating code dynamically, you often need to check whether
the method already exists, regardless of visibility.

Currently it requires two method calls and two method lookups:

```ruby
mod.method_defined?(name) || mod.private_method_defined?(name)
```

This is both inconvenient and wastefull in hotspots.

You can now match all methods regardless of visibility with
a single lookup:

```ruby
mod.method_defined?(name, true, true)
```
2026-09-11 15:50:19 +01:00
Koichi SasadaandClaude Opus 5 b8e5bf5522 Ractor: check ownership on visibility changes
set_method_visibility only called rb_check_frozen, so public/private/protected
and module_function never met the ownership check, even though the proposal
lists visibility changes as owner-only.  A non-owner Ractor could rewrite the
method entries of a foreign class through them.

The check goes next to the frozen one rather than replacing both with the
rb_class_modify_check every other method table modification uses: that one also
marks a module initialized, which this path has never done.

module_function with no arguments only sets the visibility of the current
scope, so it stays unchecked; the definitions that follow are checked as
definitions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 16:02:03 +09:00
Koichi SasadaandClaude Fable 5 2e5bf429e4 Ractor: restrict class/module modification to the creator Ractor
Only the Ractor which created a class/module may modify it: define, remove or
undefine methods, alias, include/prepend, refine, define or remove constants,
register an autoload, and set the class's own instance variables.  Reading is
unchanged.  This replaces the assorted "main Ractor only" rules with one
creator-based rule, and in exchange a Ractor gets full use of the classes it
creates itself -- unshareable constant and instance variable values included,
which even the main Ractor could not do for its own classes before.

Three paths reach a class's tables without going through rb_class_modify_check,
so they get the check of their own: Module#refine (which writes its refinement
tables into the receiver as well as into the refined class), Class#initialize
(which writes the superclass of a not-yet-initialized class, and had no frozen
check either), and Module#ruby2_keywords.

The constant inline cache has to move with the rule.  Its hit condition was
"shareable value, or we are the main Ractor", which was sound only because a
non-main Ractor could not have an unshareable constant in the first place.  Now
it can, so an owner priming the cache would let any other Ractor read that value
straight out of it, never reaching the owner check in vm_get_ev_const.  The
entry records the Ractor which filled it instead -- the one that passed the
check -- which also gives a non-main owner a fast path it never had.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 16:02:03 +09:00
Luke Gruber c329f36bea Add and use rb_gc_update_moved(VALUE *obj) which conditionally assigns
Using the `container->obj = rb_gc_location(container->obj)` pattern dirties pages unconditionally.
If we're in a forked process, this is bad for CoW. If the object hasn't moved, don't reassign.
2026-09-08 21:43:48 -04:00
Luke Gruber 3a0ec78790 Don't create CCs for hook methods called from C
Calling these hook methods shouldn't create CCs because these are not hot methods.
These CCs were only looked up in the gccct table (global call cache lookup table)
for rb_funcall and friends.

For one of our apps after bootup we reduced CCs significantly:

|                       | A control  | B (your commit) | B − A                 |
|-----------------------|------------|-----------------|-----------------------|
| callcaches (after GC) | 705,957    | 651,747         | −54,210 (−7.7%)       |
| cc tables             | 46,361     | 43,051          | −3,310                |
| total cc memory       | 86,441,345 | 79,823,142      | −6,618,203 (−6.3 MB)  |
2026-09-04 10:33:08 -04:00
Nobuyoshi Nakada 9ee713a92c Revert "Adjust indent [ci skip]"
This reverts commit c0a526dd97.
2026-08-27 09:27:53 +09:00
Nobuyoshi Nakada c0a526dd97 Adjust indent [ci skip] 2026-08-27 09:26:49 +09:00
John HawthornandLuke Gruber f95e71cc1e [Bug #22242] Invalidate CCs on cc_table_dup
When a Ractor is started, rather than modifying the cc table in place we
make a copy and CAS the table. When making the copy we previously
skipped cc_entries with an invalidated CME. However, that left the CCs
associated with that entry orphaned. CCs do not mark their CME, and the
CAS removed the table from the live set, so nothing invalidated the CC
and it ended up pointing at a garbage object.

We believe this bug is dormant in HEAD because handle_weak_references
for imemo_callcache will invalidate when the cme is collected.

Co-authored-by: Luke Gruber <luke.gru@gmail.com>
2026-08-26 14:00:38 -07:00
Koichi SasadaandClaude 65424e1791 GC: per-Ractor local GC — VM (lock / roots / write barrier)
Make the VM-global GC roots per-Ractor so the main Ractor's ordinary
local GC runs lock-free.  Add the shareability and objspace-locality
checks to the write barrier, and split the VM-wide tables behind
finer-grained locks.

Co-authored-by: Claude <noreply@anthropic.com>
2026-08-07 16:27:53 +09:00
Benoit DalozeandClaude Opus 4.8 c0ed960df1 [Bug #22197] Record the definition module on the method definition
Backtrace labels need the module where a method body was originally
defined, but alias_method and define_method(UnboundMethod) overwrite the
CME owner with the install site, producing "Class#method" pairs that
never existed. The label code reconstructed the origin from a mix of
owner, defined_class and the iseq cref with several heuristics.

Store it directly instead: a new original_module field on
rb_method_definition_t, set once when a body is created. Because the
definition is reference-counted and shared, every alias/define_method
copy inherits it, so the backtrace reader collapses to a field read.

module_function is the one case that also installs an instance method's
shared definition onto the module's singleton class; that copy is still
labeled by its owner (M.f), detected as the copy whose owner is the
singleton class of the definition module.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 13:43:21 +02:00
Shugo Maeda 1d9b1291dc [DOC] Deprecate ruby2_keywords
Add documentation-only deprecation notices to Module#ruby2_keywords,
main.ruby2_keywords, Proc#ruby2_keywords, Hash.ruby2_keywords_hash?,
and Hash.ruby2_keywords_hash, as the first phase of the schedule
proposed at https://bugs.ruby-lang.org/issues/22205.
2026-08-06 16:31:41 +09:00
Yusuke EndohandClaude Opus 4.8 b26b0227f8 Fix method coverage dropping redefined/removed methods after GC [Bug #22179]
Method coverage rebuilt its result by walking the heap for method
entries, so a shadowed or removed method that was never called could be
reclaimed by GC and vanish from the result depending on GC timing.

Record each defined method entry in me_set as it is defined, and compute
the result from me_set and cme2counter instead of walking the heap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-03 20:25:35 +09:00
Nobuyoshi Nakada 92c6f4331b Bound GC and VM diagnostic strings 2026-07-15 13:28:39 +09:00
John HawthornandLuke Gruber daffaaee73 Mark most TypedData types as THREAD_SAFE_FREE
Set RUBY_TYPED_THREAD_SAFE_FREE on TypedData types whose dfree function
is trivially safe, and only frees its own memory

Types not yet marked as THREAD_SAFE_FREE:
- id2ref_tbl_type: sets the process-global id2ref_tbl to NULL.
- mutex_data_type: unlinks itself from another thread's keeping_mutexes list.
- autoload_data_type: deletes nodes from a shared intrusive list.
- autoload_const_type: deletes itself from a shared list.
- rb_cont_data_type: mutates the shared fiber pool and the global first_jit_cont list.
- rb_fiber_data_type: delegates to cont_free.
- FiberPoolDataType: mutates shared fiber pool free-lists.
- ractor_data_type: reconfigures global VM event-hook flags and call caches.
- exported_object_registry: frees a global table under the VM lock.
- rb_box_data_type (Box::Entry): unlinks classext from other live class and module objects.
- box_ext_cleanup_type: dereferences another String object and calls unlink.
- monitor_data_type: uses the default free, so the flag has no effect.

Co-authored-by: Luke Gruber <luke.gruber@shopify.com>
2026-06-23 13:30:26 -07:00
John Hawthorn 6b915ecb1d Stop using rb_gc_pointer_to_heap_p 2026-06-16 09:43:07 -07:00
John Hawthorn 4c3d436636 Add a check in non-debug mode for a T_NONE class
Although a crash could occur anywhere, one of the most common symptoms
we see from getting a reference to a garbage collected object is
crashing while attempting to call a method on it.

These crashes usually occur when trying to perform an rb_id_table_lookup
in the "class" cc_tbl, where the class is usually another garbage
collected object, because the freelist is stored in the class pointer.

This commit aims to have a better error message in this case, in hopes
of having a better grouping of errors and to give a better hint to those
investigating and triaging crashes.
2026-06-08 11:47:54 -07:00
Satoshi Tagomori 954f4dc4c8 [Box] make the tmp array safe
* Using rb_ary_hidden_new() to hide this array
  from ObjectSpace.each_object
* Call RB_GC_GUARD to not collect this value in GC
2026-06-06 15:04:16 +09:00
Satoshi Tagomori b2715bf268 [Box] Invalidate callable me on per-box origin IClasses 2026-05-27 02:27:12 +09:00
Satoshi Tagomori 29a596f87d [Box] Invalidate the method cache of the owner too
The owner could be different from the housing class when the housing
module is prepended.
2026-05-27 02:27:12 +09:00
John Hawthorn cb9f2ba804 Use atomics for kwargs reference count
Fixes [Bug #22075]
2026-05-20 09:48:55 -07:00
Jeremy Evans 26ee2c2e82 Fix Method/UnboundMethod for refinement psuedo-zsuper methods
fafb55877a fixed issues with
refinement zsuper methods by converting them to a cfunc that calls
super. This changes Method creation to recognize the cfunc used
and skip those methods just as regular zsuper methods are skipped.
This makes refinement zsuper function the same way as subclass
zsuper in regards to Method/UnboundMethod.
2026-05-18 07:10:11 -07:00
John Hawthorn f71840a230 Replace subclasses linked list with weakref array 2026-05-13 18:36:51 -07:00
Jeremy Evans fafb55877a Avoid issues with refinement zsuper lookup
Without this patch, there are multiple issues when defining a zsuper
method via a refinement. These issues are due to the orig_me entry
for the zsuper method not being updated when the method it refers
to is modified via:

* Method being redefined (in same or closer ancestor)
* Method being removed
* Method being undef-ed (in same or closer ancestor)
* Method being overridden by method in included module
* Method being overridden by method in prepended module
* Method being defined in an included/prepended module at time of
  refinement

This includes a comprehensive test suite for these cases, using both
zsuper methods and iseq methods that call super. Without the changes
to refinement method lookup, the following types of errors occur for
refinement zsuper methods (all of the iseq methods that call super
work correctly with or without these changes):

* Incorrect result (not returning result of expected method, not
  raising NoMethodError if the method was removed or has been undef-ed)
* SystemStackError: stack level too deep
* NotImplementedError: false() function is unimplemented on this machine

This avoids the issues with refinement zsuper lookup by turning the
zsuper into a cfunc that uses rb_call_super_kw. This is not a perfect
solution, for two reasons:

* cfuncs are slower than zsuper
* arity/parameters for the method not as helpful (you

It may possible to avoid these issues by clearing method caches in
more cases. However, I think that would require a lot of extra work,
since you cannot just clear the method cache for the current class.
You would need to clear it for all subclasses that are refined, and
if this is a module, do the same for all classes that include/prepend
the module, as well as any subclasses of those classes.

Considering the need for refinement zsuper methods is very rare, the
performance and arity/parameters issues seem acceptable (to me).

Fixes [Bug #22022]
2026-05-06 17:49:31 -07:00
John Hawthorn 93ef22634f Fix missing writebarrier on refined orig_me
Caught by wbcheck. The same field is written with RB_OBJ_WRITE
in rb_method_definition_set.
2026-05-03 20:19:58 -07:00
Jean Boussier 53099633e2 Make ruby_xfree_sized and ruby_xrealloc_sized public
[Feature #21861]
2026-04-01 08:10:07 +01:00
John Hawthorn 3c251f79a3 Don't add singleton classes to subclasses list
Singleton classes don't need to be iterated in the subclasses list, we
only need to know that a subclass exists so that we can use the "method
entry" path for invalidation.
2026-03-30 18:26:58 -07:00
Takashi Kokubun ee60b99b2f Rename rb_cfp_iseq to CFP_ISEQ and rb_cfp_pc to CFP_PC
Rename for consistency with ISEQ_BODY naming convention. Remove the
separate rb_cfp_has_iseq/rb_cfp_has_pc wrappers — CFP_ISEQ and CFP_PC
return NULL for missing values, which works directly in if conditions.
2026-03-27 16:26:12 -07:00
Takashi Kokubun 226f37059e Rename cfp->iseq to cfp->_iseq and rb_zjit_cfp_iseq to rb_cfp_iseq
Per tenderlove's review, every cfp->iseq read should go through an
accessor that accounts for JITFrame. Rename the field to _iseq so
direct access causes a compile error, and rename the accessors to
drop the zjit prefix (rb_cfp_iseq, rb_cfp_has_iseq, rb_cfp_pc,
rb_cfp_has_pc).
2026-03-27 16:26:12 -07:00
John Hawthorn 111215de27 Copy allocator to subclasses at boot and on change
Copy the allocator from superclass to subclass at class creation time,
so rb_get_alloc_func no longer needs to walk the ancestor chain.

This expands on 68ffc8db08, which did this
copy, but only for classes defined in Ruby (ex. `class Foo`). And allows
us to simple read the allocator field for any class to get the correct
value.

To keep this correct when rb_define_alloc_func is called after
subclasses already exist, propagate the new allocator down to all
subclasses. An RCLASS_ALLOCATOR_DEFINED flag distinguishes classes with
an explicitly set allocator from those that inherited one, so
propagation stops at subclasses that define their own.
2026-03-25 12:51:46 -07:00
John Hawthorn a2531ba293 Simplify subclasses list, remove from Box
Currently we maintain the subclasses list for two separate purposes (we essentially have to different relationships we're putting into the same list):

1. On a T_MODULE, we track the T_ICLASSes created to include it into
   other classes. Used for method invalidation and propagating includes
   on the module that happen after it's been used
2. On a T_CLASS/T_ICLASS, we track the T_CLASS/T_ICLASS which are the
   immediate children of the class. We use this for method invalidation,
   some cvar things, and to iterate through subclasses.

Purpose 1 does not have any issues with box, the T_ICLASS always belongs
to one specific module and that's immutable. This list can be box-global
(always use the prime classext or hoist it out) and only needs to be
pruned during free. If we care about behaviour under a particular box
(ie. the propagating includes), we should look up the current box being
modified on the ICLASS itself.

Purpose 2 is more complicated. It currently tracks the immediate
children, the T_CLASS or T_ICLASS whose super points back. Because super
is per-box and is mutable (include/prepend insert ICLASSes into the
chain) we need to update the list on include/prepend, entries must be
per-box, and we can have multiple entries per-box. *I propose we
simplify this by no longer tracking the immediate subclass*, but instead
tracking the T_CLASS -> ... -> T_CLASS relationship, ie. the inverse of
rb_class_superclass. That relationship is the same across all boxes and
immutable after Class creation.

As a special case the ICLASS for refinements are also added to the
purpose 2 list (on T_CLASS). As those ICLASS do not chain to an eventual
leaf T_CLASS.

When we need to find the classes which have included a module, we can
use the module subclasses list to find the ICLASS and then use
RCLASS_INCLUDER. If we needed to iterate all T_ICLASS, we could then
walk up the CLASS_SUPER chain, but I didn't find anywhere we needed to
do that.
2026-03-17 14:42:07 -07:00
Jean Boussier 8982de2de8 Embed vm->ci_table 2026-03-16 22:23:21 +01:00
Jean Boussier 14eb083152 Speedup repeated calls to rb_gccct_clear_table
Profiling of `ruby --disable-all -e 1` shows between 5 and 10%
of the time is spent in `_platform_memset`, called from `rb_gccct_clear_table()`,
itself called from `clear_method_cache_by_id_in_class()`.

Which makes sense, during boot we define numerous methods, and after
each we have to invalidate the `gccct`, which is done by zeroing
1023 pointers, so roughtly 8kiB of memory.

By keeping track of whether the table was used since the last clear,
we can save a lot of useless memory writes.

This may also be beneficial when loading user defined code, as it's unlikely
the `gccct` would be dirtied between two `def`.

NB: profiling such a short lived process gives a lot of variance, but
with a very high sampling rate and multiple attempts, `clear_method_cache_by_id_in_class`
is always in the top 2 hotspots.
2026-03-16 20:53:49 +01:00
Jean Boussier 08e03af56b Embed vm->overloaded_cme_table 2026-03-16 15:04:38 +01:00
Jean Boussier caef12448c Embed vm->negative_cme_table id_table 2026-03-16 15:04:38 +01:00
Jean Boussier 2003835d53 Embed the vm->constant_cache id_table 2026-03-16 15:04:38 +01:00
John Hawthorn 8eab317278 Convert cc_refinement_table into TypedData object
This converts the cc_refinement_table in the VM into a standard
TypedData object using rb_gc_declare_weak_references to allow it to be
.

This allows us to store all the refinements in a flat array, and simply
remove them as that are GC'd, we don't need a set for efficient deletes.

This should also allow us to assume that imemo_callcache never requires
additional cleanup.
2026-02-26 08:26:57 -08:00
Jean Boussier 9fa0cdc923 vm_method.c: use sized free for css and method_definition 2026-02-01 12:17:29 +01:00