summaryrefslogtreecommitdiff
path: root/gc.c
AgeCommit message (Collapse)Author
51 min.Get rid of `gen_fields_tbl.fields_count`HEADmasterJean Boussier
This data is redundant because the shape already contains both the length and capacity of the object's fields. So it both waste space and create the possibility of a desync between the two. We also do not need to initialize everything to Qundef, this seem to be a left-over from pre-shape instance variables. Notes: Merged: https://github.com/ruby/ruby/pull/13561
12 hoursOptimize callcache invalidation for refinementsalpaca-tc
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. Notes: Merged: https://github.com/ruby/ruby/pull/13077
47 hoursSimplify `rb_gc_rebuild_shape`Jean Boussier
Now that there no longer multiple shape roots, all we need to do when moving an object from one slot to the other is to update the `heap_index` part of the shape_id. Since this never need to create a shape transition, it will always work and never result in a complex shape. Notes: Merged: https://github.com/ruby/ruby/pull/13556
3 daysignore confirming belonging while finrializerKoichi Sasada
A finalizer registerred in Ractor A can be invoked in B. ```ruby require "tempfile" r = Ractor.new{ 10_000.times{|i| Tempfile.new(["file_to_require_from_ractor#{i}", ".rb"]) } } sleep 0.1 ``` For example, above script makes tempfiles which have finalizers on Ractor r, but at the end of the process, main Ractor will invoke finalizers and it violates belonging check. This patch just ignore the belonging check to avoid CI failure. Of course it violates Ractor's isolation and wrong workaround. This issue will be solved with Ractor local GC. Notes: Merged: https://github.com/ruby/ruby/pull/13542
3 daysfix `rp(obj)` for any objectKoichi Sasada
Now `rp(obj)` doesn't work if the `obj` is out-of-heap because of `asan_unpoisoning_object()`, so this patch solves it. Also add pointer information and type information to show. Notes: Merged: https://github.com/ruby/ruby/pull/13534
4 daysGet rid of `rb_shape_t.flags`Jean Boussier
Now all flags are only in the `shape_id_t`, and can all be checked without needing to dereference a pointer. Notes: Merged: https://github.com/ruby/ruby/pull/13515
5 daysRemove dead rb_malloc_info_show_resultsPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/13516
7 daysMake FrozenCore a plain T_CLASSJohn Hawthorn
Notes: Merged: https://github.com/ruby/ruby/pull/13458
10 days`Ractor::Port`Koichi Sasada
* Added `Ractor::Port` * `Ractor::Port#receive` (support multi-threads) * `Rcator::Port#close` * `Ractor::Port#closed?` * Added some methods * `Ractor#join` * `Ractor#value` * `Ractor#monitor` * `Ractor#unmonitor` * Removed some methods * `Ractor#take` * `Ractor.yield` * Change the spec * `Racotr.select` You can wait for multiple sequences of messages with `Ractor::Port`. ```ruby ports = 3.times.map{ Ractor::Port.new } ports.map.with_index do |port, ri| Ractor.new port,ri do |port, ri| 3.times{|i| port << "r#{ri}-#{i}"} end end p ports.each{|port| pp 3.times.map{port.receive}} ``` In this example, we use 3 ports, and 3 Ractors send messages to them respectively. We can receive a series of messages from each port. You can use `Ractor#value` to get the last value of a Ractor's block: ```ruby result = Ractor.new do heavy_task() end.value ``` You can wait for the termination of a Ractor with `Ractor#join` like this: ```ruby Ractor.new do some_task() end.join ``` `#value` and `#join` are similar to `Thread#value` and `Thread#join`. To implement `#join`, `Ractor#monitor` (and `Ractor#unmonitor`) is introduced. This commit changes `Ractor.select()` method. It now only accepts ports or Ractors, and returns when a port receives a message or a Ractor terminates. We removes `Ractor.yield` and `Ractor#take` because: * `Ractor::Port` supports most of similar use cases in a simpler manner. * Removing them significantly simplifies the code. We also change the internal thread scheduler code (thread_pthread.c): * During barrier synchronization, we keep the `ractor_sched` lock to avoid deadlocks. This lock is released by `rb_ractor_sched_barrier_end()` which is called at the end of operations that require the barrier. * fix potential deadlock issues by checking interrupts just before setting UBF. https://bugs.ruby-lang.org/issues/21262 Notes: Merged: https://github.com/ruby/ruby/pull/13445
11 daysRead {max_iv,variation}_count from prime classextJohn Hawthorn
MAX_IV_COUNT is a hint which determines the size of variable width allocation we should use for a given class. We don't need to scope this by namespace, if we end up with larger builtin objects on some namespaces that isn't a user-visible problem, just extra memory use. Similarly variation_count is used to track if a given object has had too many branches in shapes it has used, and to use too_complex when that happens. That's also just a hint, so we can use the same value across namespaces without it being visible to users. Previously variation_count was being incremented (written to) on the RCLASS_EXT_READABLE ext, which seems incorrect if we wanted it to be different across namespaces Notes: Merged: https://github.com/ruby/ruby/pull/13434
13 daysRename `rb_shape_set_shape_id` in `rb_obj_set_shape_id`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13450
13 daysRefactor `rb_shape_too_complex_p` to take a `shape_id_t`.Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13450
13 daysRefactor `rb_shape_has_object_id`Jean Boussier
Now takes a `shape_id_t` and the version that takes a `rb_shape_t *` is private. Notes: Merged: https://github.com/ruby/ruby/pull/13450
13 daysRefactor `rb_obj_shape` out.Jean Boussier
It still exists but only in `shape.c`. Notes: Merged: https://github.com/ruby/ruby/pull/13450
13 daysFix reference updating for id2ref tablePeter Zhu
The id2ref table could contain dead entries which should not be passed into rb_gc_location. Also, we already update references in gc_update_references using rb_gc_vm_weak_table_foreach so we do not need to update it again. Notes: Merged: https://github.com/ruby/ruby/pull/13444
2025-05-26Add shape_id to RBasic under 32 bitJohn Hawthorn
This makes `RBobject` `4B` larger on 32 bit systems but simplifies the implementation a lot. [Feature #21353] Co-authored-by: Jean Boussier <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/13341
2025-05-25Use RB_VM_LOCKINGNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/13439
2025-05-23Don't use namespaced classext for superclassesJohn Hawthorn
Superclasses can't be modified by user code, so do not need namespace indirection. For example Object.superclass is always BasicObject, no matter what modules are included onto it. Notes: Merged: https://github.com/ruby/ruby/pull/13420
2025-05-22Fix a -Wmaybe-uninitializedNobuyoshi Nakada
lev in rb_gc_vm_lock() is uninitialized in single ractor mode.
2025-05-21Remove too_complex GC assertionJohn Hawthorn
Classes from the default namespace are not writable, however they do not transition to too_complex until they have been written to inside a user namespace. So this assertion is invalid (as is the previous location it was) but it doesn't seem to provide us much value. Co-authored-by: Aaron Patterson <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/13403
2025-05-21Add assertion for RCLASS_SET_PRIME_CLASSEXT_WRITABLEAaron Patterson
When classes are booted, they should all be writeable unless namespaces are enabled. This commit adds an assertion to ensure that classes are writable. Notes: Merged: https://github.com/ruby/ruby/pull/13385
2025-05-21Use rb_id_table_foreach_values for mark_cc_tblPeter Zhu
We don't need the key, so we can improve performance by only iterating on the value. This will also fix the MMTk build because looking up the key in rb_id_table_foreach requires locking the VM, which is not supported in the MMTk worker threads. Notes: Merged: https://github.com/ruby/ruby/pull/13386
2025-05-15Disable GC when building id2ref tableJean Boussier
Building that table will likely malloc several time which can trigger GC and cause race condition by freeing objects that were just added to the table. Disabling GC to prevent the race condition isn't elegant, but iven this is a deprecated callpath that is executed at most once per process, it seems acceptable. Notes: Merged: https://github.com/ruby/ruby/pull/13346
2025-05-15Ensure shape_id is never used on T_IMEMOJean Boussier
It doesn't make sense to set ivars or anything shape related on a T_IMEMO. Co-Authored-By: John Hawthorn <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/13347
2025-05-14Reduce `Object#object_id` contention.Jean Boussier
If the object isn't shareable and already has a object_id we can access it without a lock. If we need to generate an ID, we may need to lock to find the child shape. We also generate the next `object_id` using atomics. Notes: Merged: https://github.com/ruby/ruby/pull/13298
2025-05-14Rename `id_to_obj_tbl` -> `id2ref_tbl`Jean Boussier
As well as associated functions, this should make it more obvious what the purpose is. Notes: Merged: https://github.com/ruby/ruby/pull/13334
2025-05-14Fix `object_id` for classes and modules in namespace contextJean Boussier
Given classes and modules have a different set of fields in every namespace, we can't store the object_id in fields for them. Given that some space was freed in `RClass` we can store it there instead. Notes: Merged: https://github.com/ruby/ruby/pull/13315
2025-05-13Reclaim one `VALUE` from `rb_classext_t`Jean Boussier
The `includer` field is only used for `T_ICLASS`, so by moving it into the existing union we can save one `VALUE` per class and module. Notes: Merged: https://github.com/ruby/ruby/pull/13316
2025-05-13Make `waiting_fd` behaviour per-IO. (#13127)Samuel Williams
- `rb_thread_fd_close` is deprecated and now a no-op. - IO operations (including close) no longer take a vm-wide lock. Notes: Merged-By: ioquatix <[email protected]>
2025-05-13variable.c: Refactor rb_obj_field_* to take shape_id_tJean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13314
2025-05-12Remove duplicate asan_unpoisoning_objectPeter Zhu
It's already defined in internal/sanitizers.h. Notes: Merged: https://github.com/ruby/ruby/pull/13267
2025-05-11Handle GC triggering while building the initial `id_to_obj_tbl`Jean Boussier
GC can trigger while we build the table, and if it sweeps an object with an ID, it may not find it in the `id_to_obj` table. Notes: Merged: https://github.com/ruby/ruby/pull/13303
2025-05-11Allow T_CLASS and generic types to be too_complexJean Boussier
The intial complex shape implementation never allowed objects other than T_OBJECT to become too complex, unless we run out of shapes. I don't see any reason to prevent that. Ref: https://github.com/ruby/ruby/pull/6931 Notes: Merged: https://github.com/ruby/ruby/pull/13301
2025-05-11Suppress warning about unused variable without VM_CHECK_MODESatoshi Tagomori
2025-05-11Skip updating max_iv_count when the namespace cannot be determinedSatoshi Tagomori
2025-05-11Follow the code style about elseSatoshi Tagomori
2025-05-11Rename RCLASS_EXT() macro to RCLASS_EXT_PRIME() to prevent using it wronglySatoshi Tagomori
The macro RCLASS_EXT() accesses the prime classext directly, but it can be valid only in a limited situation when namespace is enabled. So, to prevent using RCLASS_EXT() in the wrong way, rename the macro and let the developer check it is ok to access the prime classext or not.
2025-05-11namespace on readSatoshi Tagomori
2025-05-10[DOC] Update documentation for ObjectSpace#each_objectDaisuke Aritomo
Co-authored-by: Benoit Daloze <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/13278
2025-05-10[DOC] Make clear that current behavior is not idealDaisuke Aritomo
Notes: Merged: https://github.com/ruby/ruby/pull/13278
2025-05-10[DOC] ObjectSpace#each_object behavior in multi-Ractor modeDaisuke Aritomo
This behavior of ObjectSpace#each_object has been around since Ruby 3.0 when Ractors were first introduced, but was never documented and has caused some amount of confusion: https://bugs.ruby-lang.org/issues/17360 https://bugs.ruby-lang.org/issues/19387 https://bugs.ruby-lang.org/issues/21149 Notes: Merged: https://github.com/ruby/ruby/pull/13278
2025-05-10Rename `rb_field_get` -> `rb_obj_field_get`Jean Boussier
To be consistent with `rb_obj_field_set`. Notes: Merged: https://github.com/ruby/ruby/pull/13297
2025-05-09Refactor `FIRST_T_OBJECT_SHAPE_ID` to not be used outside `shape.c`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13291
2025-05-09Rename `RB_OBJ_SHAPE` -> `rb_obj_shape`Jean Boussier
As well as `RB_OBJ_SHAPE_ID` -> `rb_obj_shape_id` and `RSHAPE` is now a simple alias for `rb_shape_lookup`. I tried to turn all these into `static inline` but I'm having trouble with `RUBY_EXTERN rb_shape_tree_t *rb_shape_tree_ptr;` not being exposed as I'd expect. Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Eliminate some `rb_shape_t *` usages outside of `shape.c`.Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Rename `rb_shape_get_shape_id` -> `RB_OBJ_SHAPE_ID`Jean Boussier
And `rb_shape_get_shape` -> `RB_OBJ_SHAPE`. Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Rename `rb_shape_obj_too_complex` -> `rb_shape_obj_too_complex_p`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Rename `rb_shape_get_shape_by_id` -> `RSHAPE`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Refactor `rb_shape_traverse_from_new_root` to not expose `rb_shape_t`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Deprecate `ObjectSpace._id2ref`Jean Boussier
[Feature #15408] Matz decided to deprecate it for Ruby 2.6 or 2.7 but that never actually happened. Given the object_id table is a contention point for Ractors it seems sensible to finally deprecate this API so we can generate and store object ids more efficiently in the future. Notes: Merged: https://github.com/ruby/ruby/pull/13157