summaryrefslogtreecommitdiff
path: root/gc.c
AgeCommit message (Collapse)Author
2023-10-01Use reference counting to avoid memory leak in kwargsHParker
Tracks other callinfo that references the same kwargs and frees them when all references are cleared. [bug #19906] Co-authored-by: Peter Zhu <[email protected]>
2023-09-25Dump backtraces to an arbitrary streamNobuyoshi Nakada
2023-09-24Add rb_hash_free for the GC to usePeter Zhu
2023-09-22[Bug #19896]Adam Hess
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 <[email protected]>
2023-09-18Only sort the heap on platforms with compactionMatt Valentine-House
2023-09-18Allow pages to be sorted by pinned slot countMatt Valentine-House
By compacting into slots with pinned objects first, we improve the efficiency of compaction. As it is less likely that there will exist pages containing only pinned objects after compaction. This will increase the number of free pages left after compaction and enable us to free them. This used to be the default compaction method before it was removed (inadvertently?) during the introduction of auto_compaction. This commit will sort the pages by the pinned slot count at the start of a major GC that has been triggered by explicitly calling GC.compact (and thus setting objspace->flags.during_compaction). It works using the same method by which we sort the heap by empty slot count during GC.verify_compaction_references.
2023-09-18Move heap sorting into the main GC loopMatt Valentine-House
Previously it was only being sorted during the verify compaction references stage - so would only happen during testing. This commit allows us to sort the heap prior to each explicit GC.compact run
2023-09-18Enable different heap sort methods during compactionMatt Valentine-House
pass the sorting function in as a function pointer so we don't always sort by how empty a page is
2023-09-16Another try to fix build in emscriptenPeter Zhu
malloc_trim is defined in emscripten/emmalloc.h on emscripten.
2023-09-16Fix malloc_trim on emscriptenPeter Zhu
``` gc.c:9746:5: error: implicit declaration of function 'malloc_trim' is invalid in C99 [-Werror,-Wimplicit-function-declaration] malloc_trim(0); ^ ``` http://rubyci.s3.amazonaws.com/crossruby/crossruby-master-wasm32_emscripten/log/20230916T104311Z.fail.html.gz
2023-09-16Fix malloc_trim() on wasm32Jean Boussier
``` compiling gc.c gc.c:9746:5: error: implicit declaration of function 'malloc_trim' is invalid in C99 [-Werror,-Wimplicit-function-declaration] malloc_trim(0); ^ 1 error generated. ```
2023-09-15Free all heap pages at shutdownAdam Hess
previously heap_allocated_pages was decremented from heap_page_free causing only half the heap pages to be freed at shutdown
2023-09-15Process.warmup: invoke `malloc_trim` if availableJean Boussier
Similar to releasing free GC pages, releasing free malloc pages reduce the amount of page faults post fork.
2023-09-12Fix typo in gc.cPeter Zhu
2023-09-07GC: Only force alloc slowpath for NEWOBJ hookJohn Hawthorn
Previously, configuring any GC event hook would cause all allocations to go through the newobj slowpath. We should only need to do that when the newobj specifically is subscribed to. This renames flags.has_hook to flags.has_newobj_hook, to make this new usage clear. newobj_of0 was the only place which previously checked this flag. Notes: Merged: https://github.com/ruby/ruby/pull/8378
2023-09-06Fix crash in WeakMap during compactionPeter Zhu
WeakMap can crash during compaction because the st_insert could allocate memory.
2023-09-06Support freeing the lowest memory address pagePeter Zhu
This should help fix the following flaky test: ``` 1) Failure: TestProcess#test_warmup_frees_pages [test/ruby/test_process.rb:2751]: <0> expected but was <1>. ``` Notes: Merged: https://github.com/ruby/ruby/pull/8369
2023-09-05Introduce rb_gc_remove_weakPeter Zhu
If we're during incremental marking, then Ruby code can execute that deallocates certain memory buffers that have been called with rb_gc_mark_weak, which can cause use-after-free bugs. Notes: Merged: https://github.com/ruby/ruby/pull/8375
2023-09-05Rename shady to uncollectible_wb_unprotectedPeter Zhu
The term "shady object" was renamed to "uncollectible write barrier unprotected object", so rename `has_uncollectible_shady_objects` to `has_uncollectible_wb_unprotected_objects` for consistency. Notes: Merged: https://github.com/ruby/ruby/pull/8351
2023-09-05Pool more slots for large size poolsPeter Zhu
We always sweep at least 2048 slots per sweep step, but only pool one page. For large size pools, 2048 slots is many pages but one page is very few slots. This commit changes it so that at least 1024 slots are placed in the pooled pages per sweep step. Notes: Merged: https://github.com/ruby/ruby/pull/8249
2023-09-05Add check for T_NONE in rb_gc_mark_weakPeter Zhu
This commit adds a check for T_NONE in rb_gc_mark_weak, just like gc_mark_ptr. This will help debugging.
2023-09-01Incrementally mark even if we have free pagesPeter Zhu
We move all pooled pages to free pages at the start of incremental marking, so we shouldn't run incremental marking only when we have run out of free pages. This causes incremental marking to always complete in a single step. Notes: Merged: https://github.com/ruby/ruby/pull/8230
2023-09-01Skip weak references to old objects in minor GCPeter Zhu
If we are in a minor GC and the object to mark is old, then the old object should already be marked and cannot be reclaimed in this GC cycle so we don't need to add it to the weak refences list. Notes: Merged: https://github.com/ruby/ruby/pull/8304
2023-08-31Remove gc_mark_valuesMatt Valentine-House
Now that gc_mark_values and rb_gc_mark_values are identical, we should remove one. Notes: Merged: https://github.com/ruby/ruby/pull/8341
2023-08-31Prevent rb_gc_mark_values from pinning objectsMatt Valentine-House
This is an internal only function not exposed to the C extension API. It's only use so far is from rb_vm_mark, where it's used to mark the values in the vm->trap_list.cmd array. There shouldn't be any reason why these cannot move. This commit allows them to move by updating their references during the reference updating step of compaction. To do this we've introduced another internal function rb_gc_update_values as a partner to rb_gc_mark_values. This allows us to refactor rb_gc_mark_values to not pin Notes: Merged: https://github.com/ruby/ruby/pull/8341
2023-08-31Correctly calculate initial pagesPeter Zhu
The old algorithm could calculate an undercount for the initial pages due to two issues: 1. It did not take into account that some heap pages will have one less slot due to alignment. It assumed that every heap page would be able to be fully filled with slots. Pages that are unaligned with the slot size will lose one slot. The new algorithm assumes that every page will be unaligned. 2. It performed integer division, which truncates down. This means that the number of pages might not actually satisfy the number of slots. This can cause the heap to grow in `gc_sweep_finish_size_pool` after allocating all of the allocatable pages because the total number of slots would be less than the initial configured number of slots. Notes: Merged: https://github.com/ruby/ruby/pull/8333
2023-08-30Change heap init environment variable namesPeter Zhu
This commit changes RUBY_GC_HEAP_INIT_SIZE_{40,80,160,320,640}_SLOTS to RUBY_GC_HEAP_{0,1,2,3,4}_INIT_SLOTS. This is easier to use because the user does not need to determine the slot sizes (which can vary between 32 and 64 bit systems). They now just use the heap names (`GC.stat_heap.keys`). Notes: Merged: https://github.com/ruby/ruby/pull/8335
2023-08-28Fix growth in minor GC when we have initial slotsPeter Zhu
If initial slots is set, then during a minor GC, if we have allocatable pages but the heap is mostly full, then we will set `grow_heap` to true since `total_slots` does not count allocatable pages so it will be less than `init_slots`. This can cause `allocatable_pages` to grow to much higher than desired since it will appear that the heap is mostly full. Notes: Merged: https://github.com/ruby/ruby/pull/8310
2023-08-28Expose RVALUE_OLD_AGE in GC::INTERNAL_CONSTANTSPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/8310
2023-08-27Free all empty heap pages in Process.warmupPeter Zhu
This commit adds `free_empty_pages` which frees all empty heap pages and moves the number of pages freed to the allocatable pages counter. This is used in Process.warmup to improve performance because page invalidation from copy-on-write is slower than allocating a new page. Notes: Merged: https://github.com/ruby/ruby/pull/8257
2023-08-25[Feature #19785] Deprecate RUBY_GC_HEAP_INIT_SLOTSPeter Zhu
This environment variable is replaced by `RUBY_GC_HEAP_INIT_SIZE_%d_SLOTS`, so it doesn't make sense to keep it. Notes: Merged: https://github.com/ruby/ruby/pull/8147
2023-08-25Expose stats about weak referencesPeter Zhu
[Feature #19783] This commit adds stats about weak references to `GC.latest_gc_info`. It adds the following two keys: - `weak_references_count`: number of weak references registered during the last GC. - `retained_weak_references_count`: number of weak references that survived the last GC. Notes: Merged: https://github.com/ruby/ruby/pull/8113
2023-08-25Implement weak references in the GCPeter Zhu
[Feature #19783] This commit adds support for weak references in the GC through the function `rb_gc_mark_weak`. Unlike strong references, weak references does not mark the object, but rather lets the GC know that an object refers to another one. If the child object is freed, the pointer from the parent object is overwritten with `Qundef`. Co-Authored-By: Jean Boussier <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/8113
2023-08-23Fix typo in anonymous class stringeileencodes
If anonymous was shorted it should be `anon` not `annon`. Fixes typo in APPEND_S for anonymous classes. Notes: Merged: https://github.com/ruby/ruby/pull/8154
2023-08-17Move total_freed_objects to size poolPeter Zhu
This commit moves the `total_freed_objects` statistic to the size pool which allows for `total_freed_objects` key in `GC.stat_heap`. Notes: Merged: https://github.com/ruby/ruby/pull/8231
2023-08-17Move total_allocated_objects to size poolPeter Zhu
This commit moves the `total_allocated_objects` statistic to the size pool which allows for `total_allocated_objects` key in `GC.stat_heap`. Notes: Merged: https://github.com/ruby/ruby/pull/8231
2023-08-16Move the PC regardless of the leaf flag (#8232)Takashi Kokubun
Co-authored-by: Alan Wu <[email protected]> Notes: Merged-By: k0kubun <[email protected]>
2023-08-15Add stat force_incremental_marking_finish_countPeter Zhu
This commit adds key force_incremental_marking_finish_count to GC.stat_heap. This statistic returns the number of times the size pool has forced incremental marking to finish due to running out of slots.
2023-08-15[DOC] Improve some GC docsPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/8219
2023-08-08Remove wrapper functions of RVALUE_REMEMBEREDPeter Zhu
Functions rgengc_remembered, rgengc_remembered_sweep, and rgengc_remembersetbits_get are just wrappers of RVALUE_REMEMBERED and doesn't do much more. We can remove all those and use RVALUE_REMEMBERED directly instead. Notes: Merged: https://github.com/ruby/ruby/pull/8137
2023-08-06Move `GC_CAN_COMPILE_COMPACTION` definition before usedNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/8181
2023-08-04Don't check stack for moved after compactionPeter Zhu
We don't need to check stack for moved objects after compaction because the mutator cannot run between marking the stack and the end of compaction. However, the stack may have moved objects leftover from marking and sweeping phases. This means that their pages will be invalidated and all objects moved back. We don't need to move these objects back. This also fixes the issue on Windows where some compaction tests sometimes fail due to the page of the object being invalidated. Notes: Merged: https://github.com/ruby/ruby/pull/8166
2023-08-03Remove unneeded function prototypePeter Zhu
Function prototype for gc_mode_transition is not needed as it's not used before the implementation.
2023-07-31Fix default value of global_init_slotsPeter Zhu
Not setting a value to global_init_slots causes get_envparam_size to output a broken default value.
2023-07-31Store initial slots per size poolPeter Zhu
This commit stores the initial slots per size pool, configured with the environment variables `RUBY_GC_HEAP_INIT_SIZE_%d_SLOTS`. This ensures that the configured initial slots remains a low bound for the number of slots in the heap, which can prevent heaps from thrashing in size. Notes: Merged: https://github.com/ruby/ruby/pull/8116
2023-07-31use inline cache for refinementsKoichi Sasada
From Ruby 3.0, refined method invocations are slow because resolved methods are not cached by inline cache because of conservertive strategy. However, `using` clears all caches so that it seems safe to cache resolved method entries. This patch caches resolved method entries in inline cache and clear all of inline method caches when `using` is called. fix [Bug #18572] ```ruby # without refinements class C def foo = :C end N = 1_000_000 obj = C.new require 'benchmark' Benchmark.bm{|x| x.report{N.times{ obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; }} } _END__ user system total real master 0.362859 0.002544 0.365403 ( 0.365424) modified 0.357251 0.000000 0.357251 ( 0.357258) ``` ```ruby # with refinment but without using class C def foo = :C end module R refine C do def foo = :R end end N = 1_000_000 obj = C.new require 'benchmark' Benchmark.bm{|x| x.report{N.times{ obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; }} } __END__ user system total real master 0.957182 0.000000 0.957182 ( 0.957212) modified 0.359228 0.000000 0.359228 ( 0.359238) ``` ```ruby # with using class C def foo = :C end module R refine C do def foo = :R end end N = 1_000_000 using R obj = C.new require 'benchmark' Benchmark.bm{|x| x.report{N.times{ obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; obj.foo; }} } Notes: Merged: https://github.com/ruby/ruby/pull/8129
2023-07-31mark `cc->cme_` if it is for `super`Koichi Sasada
`vm_search_super_method()` makes orphan CCs (they are not connected from ccs) and `cc->cme_` can be collected before without marking. Notes: Merged: https://github.com/ruby/ruby/pull/8145
2023-07-30check `cc->*` liveness strictlyKoichi Sasada
to fix SEGV like http://ci.rvm.jp/results/trunk-repeat20-asserts@ruby-sp2-docker/4664004 ``` /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(sigsegv+0x4f) [0x7fcb0343e7df] /tmp/ruby/src/trunk-repeat20-asserts/signal.c:920 /lib/x86_64-linux-gnu/libc.so.6(0x7fcb02e4d520) [0x7fcb02e4d520] /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(RB_SPECIAL_CONST_P+0x13) [0x7fcb03311ea3] /tmp/ruby/src/trunk-repeat20-asserts/include/ruby/internal/special_consts.h:329 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(RB_BUILTIN_TYPE) /tmp/ruby/src/trunk-repeat20-asserts/include/ruby/internal/value_type.h:183 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(gc_object_moved_p) /tmp/ruby/src/trunk-repeat20-asserts/gc.c:1624 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(gc_object_moved_p+0xe) [0x7fcb0331ed16] /tmp/ruby/src/trunk-repeat20-asserts/include/ruby/internal/special_consts.h:329 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(gc_ref_update_imemo) /tmp/ruby/src/trunk-repeat20-asserts/gc.c:10132 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(gc_update_object_references) /tmp/ruby/src/trunk-repeat20-asserts/gc.c:10411 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(gc_ref_update+0xab) [0x7fcb0331fcbb] /tmp/ruby/src/trunk-repeat20-asserts/gc.c:10570 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(gc_update_references) /tmp/ruby/src/trunk-repeat20-asserts/gc.c:10604 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(gc_compact_finish) /tmp/ruby/src/trunk-repeat20-asserts/gc.c:5425 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(gc_sweep_compact) /tmp/ruby/src/trunk-repeat20-asserts/gc.c:8476 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(gc_sweep) /tmp/ruby/src/trunk-repeat20-asserts/gc.c:6040 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(gc_start+0xe25) [0x7fcb03325795] /tmp/ruby/src/trunk-repeat20-asserts/gc.c:9323 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(rb_multi_ractor_p+0x0) [0x7fcb03326108] /tmp/ruby/src/trunk-repeat20-asserts/gc.c:9208 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(rb_vm_lock_leave) /tmp/ruby/src/trunk-repeat20-asserts/vm_sync.h:92 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(garbage_collect) /tmp/ruby/src/trunk-repeat20-asserts/gc.c:9210 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(rbimpl_atomic_exchange+0x0) [0x7fcb033262b9] /tmp/ruby/src/trunk-repeat20-asserts/gc.c:9646 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(gc_finalize_deferred) /tmp/ruby/src/trunk-repeat20-asserts/gc.c:4345 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(gc_start_internal) /tmp/ruby/src/trunk-repeat20-asserts/gc.c:9647 /tmp/ruby/build/trunk-repeat20-asserts/libruby.so.3.3(gc_compact) /tmp/ruby/src/trunk-repeat20-asserts/gc.c:10748 ``` Notes: Merged: https://github.com/ruby/ruby/pull/8142
2023-07-29check liveness of cc->klass and cc->cme_Koichi Sasada
`cc->klass` and `cc->cme_` can be free'ed while last marking so that it should be checked bofore updating the pointers. Note that `T_MOVED` is living, but `is_live_object()` returns false. Notes: Merged: https://github.com/ruby/ruby/pull/8139
2023-07-29do not clear cme but invalidate ccko1
To invalidate a cc, we need to clear cc->klass by `vm_cc_invalidate()`. I hope this patch fix the CI failures. Notes: Merged: https://github.com/ruby/ruby/pull/8134