summaryrefslogtreecommitdiff
path: root/gc.c
AgeCommit message (Collapse)Author
2025-03-13merge revision(s) bccec7fb468ad977be75e7e4c2644b4ea845ab0c, ↵Hiroshi SHIBATA
5f8ebcada099351acbc22db264e7cd3773c2bdc4, e13575bb7938e9e5b6a79bfca1b3793123f479da, 4adcfc8cd7a17593a6590025da2b03eebf4fd63c: [Backport #19584] Fix crash in rb_gc_register_address [Bug #19584] Some C extensions pass a pointer to a global variable to rb_gc_register_address. However, if a GC is triggered inside of rb_gc_register_address, then the object could get swept since it does not exist on the stack. [Bug #19584] Register global variable address before assignment [Bug #19584] Register global variables before assignment [Bug #19584] [DOC] Tweek description of `rb_gc_register_address`
2024-12-21merge revision(s) a1758fbd7fe7406601b0eb1617752db59b83586a:nagachika
Crash when malloc during GC This feature was introduced in commit 2ccf6e5, but I realized that using rb_warn is a bad idea because it allocates objects, which causes a different crash ("object allocation during garbage collection phase"). We should just hard crash here instead.
2024-01-18merge revision(s) f9a48548cf3ef54fc0a385ccd78c708737055ecc: [Backport #20042]nagachika
restore the stack pointer on finalizer When error on finalizer, the exception will be ignored. To restart the code, we need to restore the stack pointer. fix [Bug #20042] --- gc.c | 4 ++++ test/ruby/test_gc.rb | 9 +++++++++ 2 files changed, 13 insertions(+)
2023-09-30merge revision(s) 8b236e0c66da8f92e9fc33de66cfbc8e4b0c0763: [Backport #19896]nagachika
[Bug #19896] fix memory leak in vm_method This introduces a unified reference_count to clarify who is referencing a method. This also allows us to treat the refinement method as the def owner since it counts itself as a reference Co-authored-by: Peter Zhu <peter@peterzhu.ca> --- gc.c | 4 +- method.h | 6 +-- rjit_c.rb | 6 +-- test/ruby/test_module.rb | 4 +- vm_insnhelper.c | 2 +- vm_method.c | 105 +++++++++++++++++++---------------------------- 6 files changed, 54 insertions(+), 73 deletions(-)
2023-07-22merge revision(s) 54dbd8bea8a79bfcdefa471c1717c6cd28022f33: [Backport #19535]nagachika
Use an st table for "too complex" objects st tables will maintain insertion order so we can marshal dump / load objects with instance variables in the same order they were set on that particular instance [ruby-core:112926] [Bug #19535] Co-Authored-By: Jemma Issroff <jemmaissroff@gmail.com> --- gc.c | 10 ++++------ include/ruby/st.h | 2 ++ object.c | 2 +- ractor.c | 43 ++++++++++++++++++++++--------------------- shape.h | 6 +++--- st.c | 6 ++++++ test/ruby/test_shapes.rb | 21 +++++++++++++++++++++ variable.c | 28 ++++++++++++++-------------- vm_insnhelper.c | 2 +- 9 files changed, 74 insertions(+), 46 deletions(-)
2023-07-22merge revision(s) 3592b24cdc07ed89eecb39161f21fe721a89a5de: [Backport #19531]nagachika
ObjectSpace::WeakMap: clean inverse reference when an entry is re-assigned [Bug #19531] ```ruby wmap[1] = "A" wmap[1] = "B" ``` In the example above, we need to remove the `"A" => 1` inverse reference so that when `"A"` is GCed the `1` key isn't deleted. --- test/ruby/test_weakmap.rb | 17 +++++++++ weakmap.c | 91 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 91 insertions(+), 17 deletions(-)
2023-07-17merge revision(s) 52e571fa72debcd764765775bd1b76ee87e36d2d: [Backport #19580]nagachika
Ensure ruby_xfree won't segfault if called after vm_destruct [Bug #19580] The real-world scenario motivating this change is libxml2's pthread code which uses `pthread_key_create` to set up a destructor that is called at thread exit to free thread-local storage. There is a small window of time -- after ruby_vm_destruct but before the process exits -- in which a pthread may exit and the destructor is called, leading to a segfault. Please note that this window of time may be relatively large if `atexit` is being used. --- gc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
2023-07-17merge revision(s) 417b1a36447cb2c650de55b433ba623541fb8bb3: [Backport #19550]nagachika
Fix memory leak for iclass [Bug #19550] If !RCLASS_EXT_EMBEDDED (e.g. 32 bit systems) then the rb_classext_t is allocated throug malloc so it must be freed. The issue can be seen in the following script: ``` 20.times do 100_000.times do mod = Module.new Class.new do include mod end end # Output the Resident Set Size (memory usage, in KB) of the current Ruby process puts `ps -o rss= -p #{$$}` end ``` Before this fix, the max RSS is 280MB, while after this change, it's 30MB. --- gc.c | 2 +- test/ruby/test_module.rb | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-)
2023-07-16merge revision(s) e1bd45624c85e8a80991bda20801f50967ac77a1: [Backport #19482]nagachika
Fix crash when allocating classes with newobj hook We need to zero out the whole slot when running the newobj hook for a newly allocated class because the slot could be filled with garbage, which would cause a crash if a GC runs inside of the newobj hook. For example, the following script crashes: ``` require "objspace" GC.stress = true ObjectSpace.trace_object_allocations { 100.times do Class.new end } ``` [Bug #19482] --- gc.c | 8 +++++++- test/objspace/test_objspace.rb | 7 +++++++ 2 files changed, 14 insertions(+), 1 deletion(-)
2023-07-01Fix cvar caching when class is clonedeileencodes
The class variable cache that was added in https://github.com/ruby/ruby/pull/4544 changed the behavior of class variables on cloned classes. As reported when a class is cloned AND a class variable was set, and the class variable was read from the original class, reading a class variable from the cloned class would return the value from the original class. This was happening because the IC (inline cache) is stored on the ISEQ which is shared between the original and cloned class, therefore they share the cache too. To fix this we are now storing the `cref` in the cache so that we can check if it's equal to the current `cref`. If it's different we don't want to read from the cache. If it's the same we do. Cloned classes don't share the same cref with their original class. This will need to be backported to 3.1 in addition to 3.2 since the bug exists in both versions. We also added a marking function which was missing. Fixes [Bug #19379] Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2023-06-25merge revision(s) 7bd7aee02e303de27d2cddfc5ef47e612d6782cb: [Backport #18464]nagachika
Fix interpreter crash caused by RUBY_INTERNAL_EVENT_NEWOBJ + Ractors When a Ractor is created whilst a tracepoint for RUBY_INTERNAL_EVENT_NEWOBJ is active, the interpreter crashes. This is because during the early setup of the Ractor, the stdio objects are created, which allocates Ruby objects, which fires the tracepoint. However, the tracepoint machinery tries to dereference the control frame (ec->cfp->pc), which isn't set up yet and so crashes with a null pointer dereference. Fix this by not firing GC tracepoints if cfp isn't yet set up. --- gc.c | 1 + test/objspace/test_ractor.rb | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 test/objspace/test_ractor.rb
2023-06-25merge revision(s) ↵nagachika
548086b34e3dd125edabf5dc1e46b891fad3ea9c,3dc8cde70078ccb38f5f4b0818ad5eecded01bd5,e0cf80d666d4b5df3229f030a16d10d21323508e: [Backport #19529] ObjectSpace::WeakMap: fix compaction support [Bug #19529] `rb_gc_update_tbl_refs` can't be used on `w->obj2wmap` because it's not a `VALUE -> VALUE` table, but a `VALUE -> VALUE *` table, so we need some dedicated iterator. --- test/ruby/test_weakmap.rb | 8 ++++++++ weakmap.c | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) Fix crash during compaction [Bug #19529] The fix for [Bug #19529] in commit 548086b contained a bug that crashes on the following script: ``` wm = ObjectSpace::WeakMap.new obj = Object.new 100.times do wm[Object.new] = obj GC.start end GC.compact ``` --- test/ruby/test_weakmap.rb | 10 ++++++++++ weakmap.c | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) Fix incorrect size of WeakMap buffer In wmap_final_func, j is the number of elements + 1 (since j also includes the length at the 0th index), so we should resize the buffer to size j and the new length is j - 1. --- weakmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
2023-02-06merge revision(s) c6f84e918943a0bf8db6fee556fc53180d257510: [Backport #19398]NARUSE, Yui
[Bug #19398] Memory leak in WeakMap There's a memory leak in ObjectSpace::WeakMap due to not freeing the `struct weakmap`. It can be seen in the following script: ``` 100.times do 10000.times do ObjectSpace::WeakMap.new end # Output the Resident Set Size (memory usage, in KB) of the current Ruby process puts `ps -o rss= -p #{$$}` end ``` --- gc.c | 1 + test/ruby/test_weakmap.rb | 9 +++++++++ 2 files changed, 10 insertions(+)
2023-01-19merge revision(s) 3be2acfafd3b3c6168e2266c7c6561d143d7ae5c: [Backport #19327]NARUSE, Yui
Fix re-embedding of strings during compaction The reference updating code for strings is not re-embedding strings because the code is incorrectly wrapped inside of a `if (STR_SHARED_P(obj))` clause. Shared strings can't be re-embedded so this ends up being a no-op. This means that strings can be moved to a large size pool during compaction, but won't be re-embedded, which would waste the space. --- gc.c | 16 +++++++++------- string.c | 12 ++++++++---- test/ruby/test_gc_compact.rb | 8 ++++---- 3 files changed, 21 insertions(+), 15 deletions(-)
2023-01-17merge revision(s) 90a80eb076429978e720e11fb17a3cbb96de3454: [Backport #19284]NARUSE, Yui
Fix integer underflow when using HEAP_INIT_SLOTS There is an integer underflow when the environment variable RUBY_GC_HEAP_INIT_SLOTS is less than the number of slots currently in the Ruby heap. [Bug #19284] --- gc.c | 25 +++++++++++++------------ test/ruby/test_gc.rb | 5 +++++ 2 files changed, 18 insertions(+), 12 deletions(-)
2022-12-20[DOC] Fix formatting for GC.compactPeter Zhu
2022-12-20[DOC] Escape all usages of GCPeter Zhu
RDoc was making every usage of the word "GC" link to the page for GC (which is the same page).
2022-12-20[DOC] Fix call-seq for GC methodsPeter Zhu
RDoc parses the last arrow in the call-seq as the arrow for the return type. It was getting confused over the arrow in the hash.
2022-12-20[DOC] Fix formatting for GC#latest_compact_infoPeter Zhu
2022-12-20Fix thrashing of major GC when size pool is smallPeter Zhu
If a size pooll is small, then `min_free_slots < heap_init_slots` is true. This means that min_free_slots will be set to heap_init_slots. This causes `swept_slots < min_free_slots` to be true in a later if statement. The if statement could trigger a major GC which could cause major GC thrashing. Notes: Merged: https://github.com/ruby/ruby/pull/6971
2022-12-19Fix misfire of compaction read barrierPeter Zhu
gc_compact_move incorrectly returns false when destination heap is full after sweeping. It returns false even if destination heap is different than source heap (returning false means that the source heap has finished compacting). This causes the source page to get locked, which causes a read barrier fire when we try to compact the source heap again. Notes: Merged: https://github.com/ruby/ruby/pull/6963
2022-12-19Fix buffer overrun when re-embedding objectsPeter Zhu
We eagerly set the new shape of an object when moving an object during compaction. This new shape may have a different capacity than the current original shape capacity. This means that we cannot copy from the original buffer using size of the new capacity. Instead, we should use the ivar count (which is less than or equal to both the new and original capacities). Co-Authored-By: Matt Valentine-House <matt@eightbitraptor.com> Notes: Merged: https://github.com/ruby/ruby/pull/6962
2022-12-17Hard crash when allocating in GC when RUBY_DEBUGPeter Zhu
Not all builds have RGENGC_CHECK_MODE set, so it should also crash when RUBY_DEBUG is set.
2022-12-17Move check for GC to xmalloc and xcallocPeter Zhu
Moves the check earlier to before we actually perform the allocation.
2022-12-16Don't allow allocating memory during GCPeter Zhu
Allocating memory (xmalloc and xrealloc) during GC could cause GC to trigger, which would crash with `[BUG] during_gc != 0`. This is an intermittent bug which could be hard to debug. This commit changes it so that any memory allocation during GC will emit a warning. When debug flags are enabled it will also cause a crash. Notes: Merged: https://github.com/ruby/ruby/pull/6921
2022-12-15Refactor to only attempt to move movable objectsPeter Zhu
Moves check for gc_is_moveable_obj from try_move to gc_compact_plane. Co-Authored-By: Matt Valentine-House <matt@eightbitraptor.com> Notes: Merged: https://github.com/ruby/ruby/pull/6938
2022-12-15Fix Object Movement allocation in GCMatt Valentine-House
When moving Objects between size pools we have to assign a new shape. This happened during updating references - we tried to create a new shape tree that mirrored the existing tree, but based on the root shape of the new size pool. This causes allocations to happen if the new tree doesn't already exist, potentially triggering a GC, during GC. This commit changes object movement to look for a pre-existing new tree during object movement, and if that tree does not exist, we don't move the object to the new pool. This allows us to remove the shape allocation from update references. Co-Authored-By: Peter Zhu <peter@peterzhu.ca> Notes: Merged: https://github.com/ruby/ruby/pull/6938
2022-12-15Transition complex objects to "too complex" shapeJemma Issroff
When an object becomes "too complex" (in other words it has too many variations in the shape tree), we transition it to use a "too complex" shape and use a hash for storing instance variables. Without this patch, there were rare cases where shape tree growth could "explode" and cause performance degradation on what would otherwise have been cached fast paths. This patch puts a limit on shape tree growth, and gracefully degrades in the rare case where there could be a factorial growth in the shape tree. For example: ```ruby class NG; end HUGE_NUMBER.times do NG.new.instance_variable_set(:"@unique_ivar_#{_1}", 1) end ``` We consider objects to be "too complex" when the object's class has more than SHAPE_MAX_VARIATIONS (currently 8) leaf nodes in the shape tree and the object introduces a new variation (a new leaf node) associated with that class. For example, new variations on instances of the following class would be considered "too complex" because those instances create more than 8 leaves in the shape tree: ```ruby class Foo; end 9.times { Foo.new.instance_variable_set(":@uniq_#{_1}", 1) } ``` However, the following class is *not* too complex because it only has one leaf in the shape tree: ```ruby class Foo def initialize @a = @b = @c = @d = @e = @f = @g = @h = @i = nil end end 9.times { Foo.new } `` This case is rare, so we don't expect this change to impact performance of most applications, but it needs to be handled. Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/6931
2022-12-15Revert "Fix Object Movement allocation in GC"Peter Zhu
This reverts commit 9c54466e299aa91af225bc2d92a3d7755730948f. We're seeing crashes in Shopify CI after this commit.
2022-12-15Fix Object Movement allocation in GCMatt Valentine-House
When moving Objects between size pools we have to assign a new shape. This happened during updating references - we tried to create a new shape tree that mirrored the existing tree, but based on the root shape of the new size pool. This causes allocations to happen if the new tree doesn't already exist, potentially triggering a GC, during GC. This commit changes object movement to look for a pre-existing new tree during object movement, and if that tree does not exist, we don't move the object to the new pool. This allows us to remove the shape allocation from update references. Co-Authored-By: Peter Zhu <peter@peterzhu.ca> Notes: Merged: https://github.com/ruby/ruby/pull/6926
2022-12-13fix indentation: gc_compact_destination_poolMatt Valentine-House
[ci skip] Co-Authored-By: Peter Zhu <peter@peterzhu.ca> Notes: Merged: https://github.com/ruby/ruby/pull/6918
2022-12-12[DOC] Don't document private methods in objspacePeter Zhu
2022-12-10Expose need_major_gc via GC.latest_gc_info (#6791)Mirek Klimos
Notes: Merged-By: peterzhu2118 <peter@peterzhu.ca>
2022-12-09Remove unused counter for heap_page->pinned_slotsMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/6881
2022-11-22Increment max_iv_count on class based on number of set_iv in initialize (#6788)Jemma Issroff
We can loosely predict the number of ivar sets on a class based on the number of iv set instructions in the initialize method. This should give us a more accurate estimate to use for initial size pool allocation, which should in turn give us more cache hits. Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-11-21Add RVALUE_OVERHEAD and move ractor_belonging_idPeter Zhu
This commit adds RVALUE_OVERHEAD for storing metadata at the end of the slot. This commit moves the ractor_belonging_id in debug builds from the flags to RVALUE_OVERHEAD which frees the 16 bits in the headers for object shapes. Notes: Merged: https://github.com/ruby/ruby/pull/6763
2022-11-18Differentiate T_OBJECT shapes from other objectsAaron Patterson
We would like to differentiate types of objects via their shape. This commit adds a special T_OBJECT shape when we allocate an instance of T_OBJECT. This allows us to avoid testing whether an object is an instance of a T_OBJECT or not, we can just check the shape. Notes: Merged: https://github.com/ruby/ruby/pull/6758
2022-11-16Using UNDEF_P macroS-H-GAMELINKS
Notes: Merged: https://github.com/ruby/ruby/pull/6721
2022-11-10Remove numiv from RObjectJemma Issroff
Since object shapes store the capacity of an object, we no longer need the numiv field on RObjects. This gives us one extra slot which we can use to give embedded objects one more instance variable (for a total of 3 ivs). This commit removes the concept of numiv from RObject. Notes: Merged: https://github.com/ruby/ruby/pull/6699
2022-11-10Transition shape when object's capacity changesJemma Issroff
This commit adds a `capacity` field to shapes, and adds shape transitions whenever an object's capacity changes. Objects which are allocated out of a bigger size pool will also make a transition from the root shape to the shape with the correct capacity for their size pool when they are allocated. This commit will allow us to remove numiv from objects completely, and will also mean we can guarantee that if two objects share shapes, their IVs are in the same positions (an embedded and extended object cannot share shapes). This will enable us to implement ivar sets in YJIT using object shapes. Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/6699
2022-11-06[wasm] Scan machine stack based on `ec->machine.stack_{start,end}`Yuta Saito
fiber machine stack is placed outside of C stack allocated by wasm-ld, so highest stack address recorded by `rb_wasm_record_stack_base` is invalid when running on non-main fiber. Therefore, we should scan `stack_{start,end}` which always point a valid stack range in any context. Notes: Merged: https://github.com/ruby/ruby/pull/6679
2022-11-04Increment max_iv_count on class in gc marking, not gc freeingJemma Issroff
We were previously incrementing the max_iv_count on a class in gc freeing. By the time we free an object though, we're not guaranteed its class is still valid. Instead, we can do this when marking and we're guaranteed the object still knows its class. Notes: Merged: https://github.com/ruby/ruby/pull/6673
2022-10-31Implement object shapes for T_CLASS and T_MODULE (#6637)John Hawthorn
* Avoid RCLASS_IV_TBL in marshal.c * Avoid RCLASS_IV_TBL for class names * Avoid RCLASS_IV_TBL for autoload * Avoid RCLASS_IV_TBL for class variables * Avoid copying RCLASS_IV_TBL onto ICLASSes * Use object shapes for Class and Module IVs Notes: Merged-By: jhawthorn <john@hawthorn.email>
2022-10-28fix ASAN error in GCAaron Patterson
2022-10-21Rename `iv_count` on shapes to `next_iv_index`Jemma Issroff
`iv_count` is a misleading name because when IVs are unset, the new shape doesn't decrement this value. `next_iv_count` is an accurate, and more descriptive name. Notes: Merged: https://github.com/ruby/ruby/pull/6608
2022-10-21Remove unused class serialJemma Issroff
Before object shapes, we were using class serial to invalidate inline caches. Now that we use shape_id for inline cache keys, the class serial is unnecessary. Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/6605
2022-10-21Check writebarrier arguments only when RGENGC_CHECK_MODE [ci skip]Nobuyoshi Nakada
The commit 575ae50d16a03ed23357ec4ea0dbf7167fc26c8c was for debugging the failure triggered by f55212bce939f736559709a8cd16c409772389c8, and it was fixed at the commit 39f7eddec4c55711d56f05b085992a83bf23159e.
2022-10-20Check writebarrier argumentsNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/6600
2022-10-19Stop zeroing memory on allocation / copyAaron Patterson
Shapes gives us an almost exact count of instance variables on an object. Since we know the number of instance variables that have been set, we will never access slots that haven't been initialized with an IV. Notes: Merged: https://github.com/ruby/ruby/pull/6585
2022-10-19Fix and improve coroutines for Darwin (macOS) ppc/ppc64. (#5975)Sergey Fedorov
Notes: Merged-By: ioquatix <samuel@codeotaku.com>