summaryrefslogtreecommitdiff
path: root/gc.c
AgeCommit message (Collapse)Author
2022-07-15Implement Objects on VWAPeter Zhu
This commit implements Objects on Variable Width Allocation. This allows Objects with more ivars to be embedded (i.e. contents directly follow the object header) which improves performance through better cache locality. Notes: Merged: https://github.com/ruby/ruby/pull/6117
2022-07-12[Feature #18901] Support size pool movement for ArraysMatt Valentine-House
This commit enables Arrays to move between size pools during compaction. This can occur if the array is mutated such that it would fit in a different size pool when embedded. The move is carried out in two stages: 1. The RVALUE is moved to a destination heap during object movement phase of compaction 2. The array data is re-embedded and the original buffer free'd if required. This happens during the update references step Notes: Merged: https://github.com/ruby/ruby/pull/6099
2022-07-11Add expand_heap option to GC.verify_compaction_referencesMatt Valentine-House
In order to reliably test compaction we need to be able to move objects between size pools. In order for this to happen there must be pages in a size pool into which we can allocate. The existing implementation of `double_heap` only doubled the existing number of pages in the heap, so if a size pool had a low number of pages (or 0) it's not guaranteed that enough space will be created to move objects into that size pool. This commit deprecates the `double_heap` option and replaces it with `expand_heap` instead. expand heap will expand each heap by enough pages to hold a number of slots defined by `GC_HEAP_INIT_SLOTS` or by `heap->total_pags` whichever is larger. If both `double_heap` and `expand_heap` are present, a deprecation warning will be shown for `double_heap` and the `expand_heap` behaviour will take precedence Given that this is an API intended for debugging and testing GC compaction I'm not concerned about the extra memory usage or time taken to create the pages. However, for completeness: Running the following `test.rb` and using `time` on my Macbook Pro shows the following memory usage and time impact: pp "RSS (kb): #{`ps -o rss #{Process.pid}`.lines.last.to_i}" GC.verify_compaction_references(double_heap: true, toward: :empty) pp "RSS (kb): #{`ps -o rss #{Process.pid}`.lines.last.to_i}" ❯ time make run ./miniruby -I./lib -I. -I.ext/common -r./arm64-darwin21-fake ./test.rb "RSS (kb): 24000" <internal:gc>:251: warning: double_heap is deprecated and will be removed "RSS (kb): 25232" ________________________________________________________ Executed in 124.37 millis fish external usr time 82.22 millis 0.09 millis 82.12 millis sys time 28.76 millis 2.61 millis 26.15 millis ❯ time make run ./miniruby -I./lib -I. -I.ext/common -r./arm64-darwin21-fake ./test.rb "RSS (kb): 24000" "RSS (kb): 49040" ________________________________________________________ Executed in 150.13 millis fish external usr time 103.32 millis 0.10 millis 103.22 millis sys time 35.73 millis 2.59 millis 33.14 millis Notes: Merged: https://github.com/ruby/ruby/pull/6107
2022-07-10Extract `atomic_inc_wraparound` functionNobuyoshi Nakada
2022-07-10Add `asan_unpoisoning_object` to execute the block with unpoisoningNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/6092
2022-07-10Split `rb_raw_obj_info`Nobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/6092
2022-07-10Cycle `obj_info_buffers_index` atomicallyNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/6092
2022-07-10`APPEND_S` for no conversion formatsNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/6092
2022-07-10Rewrite `APPENDF` using variadic argumentsNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/6092
2022-07-10Use `size_t` for `rb_raw_obj_info`Nobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/6092
2022-07-10Use `asan_unpoison_object_temporary`Nobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/6092
2022-07-10Get rid of static buffer in `obj_info`Nobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/6092
2022-07-07Gather heap page size conditions combinationNobuyoshi Nakada
When similar combination of conditions are separated in two places, it is harder to make sure the conditional blocks match each other, Notes: Merged: https://github.com/ruby/ruby/pull/6100
2022-07-07Improve error message for segv in read_barrier_handlerPeter Zhu
If the page_body is a null pointer, then read_barrier_handler will crash with an unrelated message. This commit improves the error message. Before: test.rb:1: [BUG] Couldn't unprotect page 0x0000000000000000, errno: Cannot allocate memory After: test.rb:1: [BUG] read_barrier_handler: segmentation fault at 0x14 Notes: Merged: https://github.com/ruby/ruby/pull/6096
2022-07-07Fix crash in compaction due to unlocked pagePeter Zhu
The page of src could be partially compacted, so it may contain T_MOVED. Sweeping a page may read objects on this page, so we need to lock the page. Notes: Merged: https://github.com/ruby/ruby/pull/6096
2022-07-07Fix typo in gc_compact_movePeter Zhu
The page we're sweeping is on the destination heap `dheap`, not the source heap `heap`. Notes: Merged: https://github.com/ruby/ruby/pull/6096
2022-07-06Adjust indents [ci skip]Nobuyoshi Nakada
2022-06-18Extract `protect_page_body` to fix mismatched bracesNobuyoshi Nakada
2022-06-18Disable Mach exception handlers when read barriers in placeKJ Tsanaktsidis
The GC compaction mechanism implements a kind of read barrier by marking some (OS) pages as unreadable, and installing a SIGBUS/SIGSEGV handler to detect when they're accessed and invalidate an attempt to move the object. Unfortunately, when a debugger is attached to the Ruby interpreter on Mac OS, the debugger will trap the EXC_BAD_ACCES mach exception before the runtime can transform that into a SIGBUS signal and dispatch it. Thus, execution gets stuck; any attempt to continue from the debugger re-executes the line that caused the exception and no forward progress can be made. This makes it impossible to debug either the Ruby interpreter or a C extension whilst compaction is in use. To fix this, we disable the EXC_BAD_ACCESS handler when installing the SIGBUS/SIGSEGV handlers, and re-enable them once the compaction is done. The debugger will still trap on the attempt to read the bad page, but it will be trapping the SIGBUS signal, rather than the EXC_BAD_ACCESS mach exception. It's possible to continue from this in the debugger, which invokes the signal handler and allows forward progress to be made. Notes: Merged: https://github.com/ruby/ruby/pull/5991
2022-06-17Suppress code unused unless GC_CAN_COMPILE_COMPACTIONNobuyoshi Nakada
2022-06-16Include runtime checks for compaction supportPeter Zhu
Commit 0c36ba53192c5a0d245c9b626e4346a32d7d144e changed GC compaction methods to not be implemented when not supported. However, that commit only does compile time checks (which currently only checks for WASM), but there are additional compaction support checks during run time. This commit changes it so that GC compaction methods aren't defined during run time if the platform does not support GC compaction. [Bug #18829] Notes: Merged: https://github.com/ruby/ruby/pull/6019
2022-06-16Rename GC_COMPACTION_SUPPORTEDPeter Zhu
Naming this macro GC_COMPACTION_SUPPORTED is misleading because it only checks whether compaction is supported at compile time. [Bug #18829] Notes: Merged: https://github.com/ruby/ruby/pull/6019
2022-06-15Remove MJIT worker thread (#6006)Takashi Kokubun
[Misc #18830] Notes: Merged-By: k0kubun <[email protected]>
2022-06-13Move String RVALUES between poolsMatt Valentine-House
And re-embed any strings that can now fit inside the slot they've been moved to Notes: Merged: https://github.com/ruby/ruby/pull/5986
2022-06-08Fix major GC thrashingPeter Zhu
Only growth heaps are allowed to start major GCs. Before this patch, growth heaps are defined as size pools that freed more slots than had empty slots (i.e. there were more dead objects that empty space). But if the size pool is relatively stable and tightly packed with mostly old objects and has allocatable pages, then it would be incorrectly classified as a growth heap and trigger major GC. But since it's stable, it would not use any of the allocatable pages and forever be classified as a growth heap, causing major GC thrashing. This commit changes the definition of growth heap to require that the size pool to have no allocatable pages. Notes: Merged: https://github.com/ruby/ruby/pull/5993
2022-06-08Fix compilation error when USE_RVARGC=0Peter Zhu
force_major_gc_count was not defined when USE_RVARGC=0.
2022-06-08Add key force_major_gc_count to GC.stat_heapPeter Zhu
force_major_gc_count is the number of times the size pool forced major GC to run.
2022-06-07Remove while loop over heap_preparePeter Zhu
Having a while loop over `heap_prepare` makes the GC logic difficult to understand (it is difficult to understand when and why `heap_prepare` yields a free page). It is also a source of bugs and can cause an infinite loop if `heap_page` never yields a free page. Notes: Merged: https://github.com/ruby/ruby/pull/5907
2022-06-02Typedef built-in function typesNobuyoshi Nakada
2022-06-02Move `GC.verify_compaction_references` [Bug #18779]Nobuyoshi Nakada
Define `GC.verify_compaction_references` as a built-in ruby method, according to GC compaction support via `GC::OPTS`. Notes: Merged: https://github.com/ruby/ruby/pull/5972
2022-06-02Adjust indent and nesting [ci skip]Nobuyoshi Nakada
2022-05-24Define unsupported GC compaction methods as rb_f_notimplementMike Dalessio
Fixes [Bug #18779] Define the following methods as `rb_f_notimplement` on unsupported platforms: - GC.compact - GC.auto_compact - GC.auto_compact= - GC.latest_compact_info - GC.verify_compaction_references This change allows users to call `GC.respond_to?(:compact)` to properly test for compaction support. Previously, it was necessary to invoke `GC.compact` or `GC.verify_compaction_references` and check if those methods raised `NotImplementedError` to determine if compaction was supported. This follows the precedent set for other platform-specific methods. For example, in `process.c` for methods such as `Process.fork`, `Process.setpgid`, and `Process.getpriority`. Notes: Merged: https://github.com/ruby/ruby/pull/5934
2022-05-24Move compaction-related methods into gc.cMike Dalessio
These methods are removed from gc.rb and added to gc.c: - GC.compact - GC.auto_compact - GC.auto_compact= - GC.latest_compact_info - GC.verify_compaction_references This is a prefactor to allow setting these methods to `rb_f_notimplement` in a followup commit. Notes: Merged: https://github.com/ruby/ruby/pull/5934
2022-05-13Fix compiler warning when USE_RVARGC=0Matt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/5909
2022-05-10Write have instead of have have [ci skipKaíque Kandy Koga
Notes: Merged: https://github.com/ruby/ruby/pull/5897 Merged-By: nobu <[email protected]>
2022-05-09Don't allocate new page on finish sweepingPeter Zhu
We don't need to allocate a new page in gc_sweep_finish_size_pool. It can be allocated when needed. Notes: Merged: https://github.com/ruby/ruby/pull/5885
2022-05-09Fix heap_extend_pages when total_slots is 0Peter Zhu
Some size pools may not have any pages/slots, so total_slots is 0. This causes a divide-by-zero in the calculation. This commit adds a special case to catch the case when total_slots is 0 and returns the number of pages for heap_init_slots. Notes: Merged: https://github.com/ruby/ruby/pull/5885
2022-05-09Grow size pools with no or few slotsPeter Zhu
If the size pool has no or few pages/slots, then min_free_slots will be a very small number (or even 0). Then the heap won't be eligible to grow, causing GC thrashing or infinite loops. Notes: Merged: https://github.com/ruby/ruby/pull/5885
2022-05-09Call gc_sweep_finish_size_pool on size pools with no pagesPeter Zhu
Size pools with no pages won't be swept so gc_sweep_finish_size_pool will never be called on it, but gc_sweep_finish_size_pool must be called to grow the size pool. Notes: Merged: https://github.com/ruby/ruby/pull/5885
2022-05-09Fix gc_page_sweep when last bitmap plane is not usedPeter Zhu
Depending on alignment, the last bitmap plane may not used. Then it will appear as if all of the objects on that plane is unmarked, which will cause a buffer overrun when we try to free the object. This commit changes the loop to calculate the number of planes used (bitmap_plane_count). Notes: Merged: https://github.com/ruby/ruby/pull/5885
2022-05-05Mark RCLASS_INCLUDERAlan Wu
Since 4d8f76286beefbb8f7fba2479f6d0a0b4a47304c, we need to dereference the includer field on iclasses, so we need to mark it to make sure it's alive. Sometimes during compaction we crash because the field is dangling, though I have a hard time constructing such a situation. See http://ci.rvm.jp/results/trunk@ruby-iga/3947725 Notes: Merged: https://github.com/ruby/ruby/pull/5890
2022-05-04Unpoison freelist when iterating over it in gc_sweep_pageJemma Issroff
Notes: Merged: https://github.com/ruby/ruby/pull/5884
2022-05-04Remove unneeded castPeter Zhu
`start` is of type uintptr_t so it does not need to be casted to VALUE.
2022-05-03Update reference for RCLASS_INCLUDER during compactionAlan Wu
We didn't update the includer field during compaction so it could become a dangling pointer after compaction. It's only recently that we started to dereference the field, and we were only comparing the pointer before then, so the omission only recently started to cause crashes. By instrumenting object.c:833 with `rp(includer);`, you can see the includer field become `T_NONE` with the following script: ```ruby mod = Module.new do protected def foo = 1 end klass = Class.new do include Module.new def run foo end end klass.include(mod) GC.verify_compaction_references(double_heap: true, toward: :empty) klass.new.run ``` I found a crash in a private application that this patch fixes, but wasn't able to develop a small reproducer. Hence the above demo that requires instrumentation. Notes: Merged: https://github.com/ruby/ruby/pull/5880
2022-04-13Parenthize macro argumentsNobuyoshi Nakada
2022-04-12Fix a typo [ci skip]Kazuhiro NISHIYAMA
2022-04-09[DOC]Some link prefix replaceS-H-GAMELINKS
Notes: Merged: https://github.com/ruby/ruby/pull/5783
2022-04-07Update `heap_pages_deferred_final` atomicallyNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/5775
2022-04-04ruby_gc_set_params: update malloc_limit when env is setEric Wong
During VM startup, rb_objspace_alloc sets malloc_limit (objspace->malloc_params.limit) before ruby_gc_set_params is called, thus nullifying the effect of RUBY_GC_MALLOC_LIMIT before the initial GC run. The call sequence is as follows: main.c::main() ruby_init ruby_setup Init_BareVM rb_objspace_alloc // malloc_limit = gc_params.malloc_limit_min; ruby_options ruby_process_options process_options ruby_gc_set_params // RUBY_GC_MALLOC_LIMIT => gc_params.malloc_limit_min With ruby_gc_set_params setting malloc_limit, RUBY_GC_MALLOC_LIMIT affects the process sooner. [ruby-core:107170]
2022-04-04Disable mmap on WASMPeter Zhu
WASM does not have proper support for mmap. Notes: Merged: https://github.com/ruby/ruby/pull/5749