aboutsummaryrefslogtreecommitdiffstats
path: root/gc.c
Commit message (Collapse)AuthorAgeFilesLines
* Don't immediately promote children of old objectsPeter Zhu2023-05-251-78/+22
| | | | | | | | | | | | | | | | | | | | | | | | | [Feature #19678] References from an old object to a write barrier protected young object will not immediately promote the young object. Instead, the young object will age just like any other object, meaning that it has to survive three collections before being promoted to the old generation. References from an old object to a write barrier unprotected object will place the parent object in the remember set for marking during minor collections. This allows the child object to be reclaimed in minor collections at the cost of increased time for minor collections. On one of [Shopify's highest traffic Ruby apps, Storefront Renderer](https://shopify.engineering/how-shopify-reduced-storefront-response-times-rewrite), we saw significant improvements after deploying this feature in production. We compare the GC time and response time of web workers that have the original behaviour (non-experimental group) and this new behaviour (experimental group). We see that with this feature we spend significantly less time in the GC, 0.81x on average, 0.88x on p99, and 0.45x on p99.9. This translates to improvements in average response time (0.96x) and p99 response time (0.92x).
* Add REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIOPeter Zhu2023-05-241-1/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | [Feature #19571] This commit adds the environment variable `RUBY_GC_HEAP_REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO` which is used to calculate the `remembered_wb_unprotected_objects_limit` using a ratio of `old_objects`. This should improve performance by reducing major GC because, in a major GC, we mark all of the old objects, so we should have more uncollectible WB unprotected objects before starting a major GC. The default has been set to 0.01 (1% of old objects). On one of [Shopify's highest traffic Ruby apps, Storefront Renderer](https://shopify.engineering/how-shopify-reduced-storefront-response-times-rewrite), we saw significant improvements after deploying this patch in production. In the graphs below, we have the `tuned` group which uses `RUBY_GC_HEAP_REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO=0.01` (the default value), and an `untuned` group, which turns this feature off with `RUBY_GC_HEAP_REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO=0`. We see that the tuned group spends significantly less time in GC, on average 0.67x of the time compared to the untuned group and 0.49x for p99. We see this improvement in GC time translate to improvements in response times. The average response time is now 0.96x of the time compared to the untuned group and 0.86x for p99. https://user-images.githubusercontent.com/15860699/229559078-e23e8ce4-5f1f-4a2f-b5ef-5769f92b8c70.png
* gc.c: get rid of unused objspace parameters (#7853)Jean Boussier2023-05-241-10/+10
|
* `rb_bug` prints a newline after the messageNobuyoshi Nakada2023-05-201-6/+6
|
* Move ar_hint to ar_table_structPeter Zhu2023-05-171-3/+3
| | | | This allows Hashes with ST tables to fit int he 80 byte size pool.
* Implement Hash ST tables on VWAPeter Zhu2023-05-171-8/+10
|
* Implement Hash AR tables on VWAPeter Zhu2023-05-171-29/+8
|
* Ensure the VM is alive before accessing objspace in C API (Feature #19627)Ian Ker-Seymer2023-05-041-3/+9
| | | [Feature #19627]
* Make classes embedded on 32 bitPeter Zhu2023-04-161-11/+0
| | | | | Classes are now exactly 80 bytes when embedded, which perfectly fits the 3rd size pool on 32 bit systems.
* [DOC] Update sample callback of `rb_objspace_each_objects`Nobuyoshi Nakada2023-04-151-8/+10
| | | | | * refine liveness check * fix missing closing brace
* Change max_iv_count to type attr_index_tPeter Zhu2023-04-111-1/+1
| | | | | | max_iv_count is calculated from next_iv_index of the shape, which is of type attr_index_t, so we can also make max_iv_count of type attr_index_t.
* Enable 5 size pools on 32 bit systemsPeter Zhu2023-04-111-6/+4
| | | | This commit will allow 32 bit systems to take advantage of VWA.
* * expand tabs. [ci skip]git2023-04-071-3/+3
| | | | Please consider using misc/expand_tabs.rb as a pre-commit hook.
* [Bug #19584] [DOC] Tweek description of `rb_gc_register_address`Nobuyoshi Nakada2023-04-071-3/+9
|
* Fix crash in rb_gc_register_addressPeter Zhu2023-04-061-0/+7
| | | | | | | | | [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.
* [Feature #19474] Refactor NEWOBJ macrosMatt Valentine-House2023-04-061-8/+1
| | | | NEWOBJ_OF is now our canonical newobj macro. It takes an optional ec
* Remove newobj_of_crMatt Valentine-House2023-04-061-18/+11
| | | | We can just make newobj_of take a ractor
* Ensure ruby_xfree won't segfault if called after vm_destructMike Dalessio2023-04-051-2/+10
| | | | | | | | | | | | | | | [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.
* [Feature #19579] Remove !USE_RVARGC code (#7655)Peter Zhu2023-04-041-98/+0
| | | | | | | | | | | Remove !USE_RVARGC code [Feature #19579] The Variable Width Allocation feature was turned on by default in Ruby 3.2. Since then, we haven't received bug reports or backports to the non-Variable Width Allocation code paths, so we assume that nobody is using it. We also don't plan on maintaining the non-Variable Width Allocation code, so we are going to remove it.
* Revert "Fix transient heap mode"Aaron Patterson2023-04-041-47/+0
| | | | | | | | This reverts commit 87253d047ce35e7836b6f97edbb4f819879a3b25. Revert "Implement `Process.warmup`" This reverts commit ba6ccd871442f55080bffd53e33678c0726787d2.
* Fix transient heap modeAaron Patterson2023-04-041-1/+17
| | | | | | Make sure the transient heap is in the right mode when we finish warming the heap. Also ensure the GC isn't allowed to run while we iterate and mutate the heap.
* Implement `Process.warmup`Jean Boussier2023-04-041-0/+31
| | | | | | | | | | | | [Feature #18885] For now, the optimizations performed are: - Run a major GC - Compact the heap - Promote all surviving objects to oldgen Other optimizations may follow.
* add `RUBY_DEBUG_LOG` fo `each_machine_stack_value`Koichi Sasada2023-03-311-0/+1
|
* Fix memory leak for iclassPeter Zhu2023-03-281-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | [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.
* Use an st table for "too complex" objectsAaron Patterson2023-03-201-6/+4
| | | | | | | | | | 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>
* [Feature #19406] Allow declarative definition of referencesMatt Valentine-House2023-03-171-5/+46
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When using rb_data_type_struct to wrap a C struct, that C struct can contain VALUE references to other Ruby objects. If this is the case then one must also define dmark and optionally dcompact callbacks in order to allow these objects to be correctly handled by the GC. This is suboptimal as it requires GC related logic to be implemented by extension developers. This can be a cause of subtle bugs when references are not marked of updated correctly inside these callbacks. This commit provides an alternative approach, useful in the simple case where the C struct contains VALUE members (ie. there isn't any conditional logic, or data structure manipulation required to traverse these references). In this case references can be defined using a declarative syntax as a list of edges (or, pointers to references). A flag can be set on the rb_data_type_struct to notify the GC that declarative references are being used, and a list of those references can be assigned to the dmark pointer instead of a function callback, on the rb_data_type_struct. Macros are also provided for simple declaration of the reference list, and building edges. To avoid having to also find space in the struct to define a length for the references list, I've chosed to always terminate the references list with RUBY_REF_END - defined as UINTPTR_MAX. My assumption is that no single struct will ever be large enough that UINTPTR_MAX is actually a valid reference.
* Assume that FL_FINALIZE is in finalizer_tablePeter Zhu2023-03-171-3/+3
| | | | | If the flag FL_FINALIZE is set, then it's guaranteed to be in the finalizer_table, so we can directly assume that without checking.
* [Feature #19442] Remove GC_ENABLE_INCREMENTAL_MARKMatt Valentine-House2023-03-161-76/+2
| | | | | | | Ruby doesn't compile when this is disabled, and it's not tested on CI. We should remove it. Co-Authored-By: Peter Zhu <peter@peterzhu.ca>
* [Feature #19442] Remove USE_RINCGC flagMatt Valentine-House2023-03-161-1/+1
| | | | Ruby doesn't compile when this is set to 0. Let's remove it.
* Use __builtin_ppc_get_timebase on POWER with clangpkubaj2023-03-141-1/+1
|
* Remove duplicate code in gc_marks_finishPeter Zhu2023-03-101-7/+0
| | | | | There is an identical block a few lines down that does the exact same thing.
* Revert "Allow classes and modules to become too complex"Aaron Patterson2023-03-101-5/+1
| | | | This reverts commit 69465df4242f3b2d8e55fbe18d7c45b47b40a626.
* Move WeakMap and WeakKeyMap code to weakmap.cPeter Zhu2023-03-101-883/+62
| | | | | | These classes don't belong in gc.c as they're not actually part of the GC. This commit refactors the code by moving all the code into a weakmap.c file.
* Allow classes and modules to become too complexHParker2023-03-091-1/+5
| | | | This makes the behavior of classes and modules when there are too many instance variables match the behavior of objects with too many instance variables.
* Fix interpreter crash caused by RUBY_INTERNAL_EVENT_NEWOBJ + RactorsKJ Tsanaktsidis2023-03-091-0/+1
| | | | | | | | | | | | 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.
* Fix crash when allocating classes with newobj hookPeter Zhu2023-03-081-1/+7
| | | | | | | | | | | | | | | | | | | | | | 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]
* Adjust styles [ci skip]Nobuyoshi Nakada2023-03-081-1/+2
|
* Add function rb_data_freePeter Zhu2023-03-071-46/+42
| | | | | | | This commit adds a function rb_data_free used by obj_free and rb_objspace_call_finalizer to free T_DATA objects. This change also means that RUBY_TYPED_FREE_IMMEDIATELY objects can be freed immediately in rb_objspace_call_finalizer rather than being created into a zombie.
* s/mjit/rjit/Takashi Kokubun2023-03-061-1/+1
|
* Stop exporting symbols for MJITTakashi Kokubun2023-03-061-5/+5
|
* Crash when malloc during GCPeter Zhu2023-03-061-12/+12
| | | | | | | 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.
* Fix spelling (#7389)John Bampton2023-02-271-1/+1
|
* [ci skip] Add note in gc.c about ambiguous casePeter Zhu2023-02-241-5/+18
|
* Fix incorrect line numbers in GC hookPeter Zhu2023-02-241-2/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the previous instruction is not a leaf instruction, then the PC was incremented before the instruction was ran (meaning the currently executing instruction is actually the previous instruction), so we should not increment the PC otherwise we will calculate the source line for the next instruction. This bug can be reproduced in the following script: ``` require "objspace" ObjectSpace.trace_object_allocations_start a = 1.0 / 0.0 p [ObjectSpace.allocation_sourceline(a), ObjectSpace.allocation_sourcefile(a)] ``` Which outputs: [4, "test.rb"] This is incorrect because the object was allocated on line 10 and not line 4. The behaviour is correct when we use a leaf instruction (e.g. if we replaced `1.0 / 0.0` with `"hello"`), then the output is: [10, "test.rb"]. [Bug #19456]
* Fix a warning on typedefTakashi Kokubun2023-02-231-2/+2
| | | | | | ../gc.c:13317:1: warning: ‘typedef’ is not at beginning of declaration [-Wold-style-declaration] 13317 | } typedef weakkeymap_entry_t; | ^
* Implement ObjectSpace::WeakKeyMap basic allocatorJean Boussier2023-02-231-0/+325
| | | | [Feature #18498]
* * remove trailing spaces. [ci skip]git2023-02-221-1/+1
|
* Make GC faster when RGENGC_CHECK_MODE >= 2Peter Zhu2023-02-221-8/+4
| | | | | | We shouldn't run gc_verify_internal_consistency after every GC step when RGENGC_CHECK_MODE >= 2, only when GC has finished. Running it on every GC step makes it too slow.
* Add marking and sweeping time to GC.statPeter Zhu2023-02-211-49/+91
| | | | | | | | | | | | There is a `time` key in GC.stat that gives us the total time spent in GC. However, we don't know what proportion of the time is spent between marking and sweeping. This makes it difficult to tune the GC as we're not sure where to focus our efforts on. This PR adds keys `marking_time` and `sweeping_time` to GC.stat for the time spent marking and sweeping, in milliseconds. [Feature #19437]
* Refactor to separate marking and sweeping phasesPeter Zhu2023-02-211-47/+49
| | | | | This commit separates the marking and sweeping phases so that marking functions do not directly call sweeping functions.