summaryrefslogtreecommitdiff
path: root/internal/gc.h
AgeCommit message (Collapse)Author
2025-05-08Move `object_id` in object fields.Jean Boussier
And get rid of the `obj_to_id_tbl` It's no longer needed, the `object_id` is now stored inline in the object alongside instance variables. We still need the inverse table in case `_id2ref` is invoked, but we lazily build it by walking the heap if that happens. The `object_id` concern is also no longer a GC implementation concern, but a generic implementation. Co-Authored-By: Matt Valentine-House <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/13159
2025-04-04Ractor: revert to moving object bytes, but size pool awareJean Boussier
Using `rb_obj_clone` introduce other problems, such as `initialize_*` callbacks invocation in the context of the parent ractor. So we can revert back to copy the content of the object slots, but in a way that is aware of size pools. Notes: Merged: https://github.com/ruby/ruby/pull/13070
2025-03-31Ractor: Fix moving embedded objectsJean Boussier
[Bug #20271] [Bug #20267] [Bug #20255] `rb_obj_alloc(RBASIC_CLASS(obj))` will always allocate from the basic 40B pool, so if `obj` is larger than `40B`, we'll create a corrupted object when we later copy the shape_id. Instead we can use the same logic than ractor copy, which is to use `rb_obj_clone`, and later ask the GC to free the original object. We then must turn it into a `T_OBJECT`, because otherwise just changing its class to `RactorMoved` leaves a lot of ways to keep using the object, e.g.: ``` a = [1, 2, 3] Ractor.new{}.send(a, move: true) [].concat(a) # Should raise, but wasn't. ``` If it turns out that `rb_obj_clone` isn't performant enough for some uses, we can always have carefully crafted specialized paths for the types that would benefit from it. Notes: Merged: https://github.com/ruby/ruby/pull/13008
2025-02-19Add rb_gc_object_metadata APIPeter Zhu
This function replaces the internal rb_obj_gc_flags API. rb_gc_object_metadata returns an array of name and value pairs, with the last element having 0 for the name. Notes: Merged: https://github.com/ruby/ruby/pull/12777
2025-01-11Remove stale declaration for modular GCNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/12546
2024-12-16Check whether object is valid in allocation_info_tracer_compactPeter Zhu
When reference updating ObjectSpace.trace_object_allocations, we need to check whether the object is valid or not because it does not mark the object so the object may be dead. This can cause a segmentation fault if the object is on a free heap page. For example, the following script crashes: require "objspace" objs = [] ObjectSpace.trace_object_allocations do 1_000_000.times do objs << Object.new end end objs = nil # Free pages that the objs were on GC.start # Run compaction and check that it doesn't crash GC.compact Notes: Merged: https://github.com/ruby/ruby/pull/12360
2024-12-06Add rb_gc_impl_active_gc_name to gc/gc_impl.hPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/12271
2024-12-05Use rb_gc_enable/rb_gc_disable_no_rest instead of ruby_disable_gcPeter Zhu
We should use the rb_gc_enable/rb_gc_disable_no_rest APIs instead of directly setting the ruby_disable_gc variable. Notes: Merged: https://github.com/ruby/ruby/pull/12264
2024-12-05Standardize on the name "modular GC"Peter Zhu
We have name fragmentation for this feature, including "shared GC", "modular GC", and "external GC". This commit standardizes the feature name to "modular GC" and the implementation to "GC library". Notes: Merged: https://github.com/ruby/ruby/pull/12261
2024-11-25Place all non-default GC API behind USE_SHARED_GCMatt Valentine-House
So that it doesn't get included in the generated binaries for builds that don't support loading shared GC modules Co-Authored-By: Peter Zhu <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/12149
2024-11-21Annotate anonymous mmapKunshan Wang
Use PR_SET_VMA_ANON_NAME to set human-readable names for anonymous virtual memory areas mapped by `mmap()` when compiled and run on Linux 5.17 or higher. This makes it convenient for developers to debug mmap. Notes: Merged: https://github.com/ruby/ruby/pull/12119
2024-11-14Include the currently active GC in RUBY_DESCRIPTIONMatt Valentine-House
This will add +MOD_GC to the version string and Ruby description when Ruby is compiled with shared gc support. When shared GC support is compiled in and a GC module has been loaded using RUBY_GC_LIBRARY, the version string will include the name of the currently active GC as reported by the rb_gc_active_gc_name function in the form +MOD_GC[gc_name] [Feature #20794] Notes: Merged: https://github.com/ruby/ruby/pull/11872
2024-10-03Rename size_pool -> heapMatt Valentine-House
Now that we've inlined the eden_heap into the size_pool, we should rename the size_pool to heap. So that Ruby contains multiple heaps, with different sized objects. The term heap as a collection of memory pages is more in memory management nomenclature, whereas size_pool was a name chosen out of necessity during the development of the Variable Width Allocation features of Ruby. The concept of size pools was introduced in order to facilitate different sized objects (other than the default 40 bytes). They wrapped the eden heap and the tomb heap, and some related state, and provided a reasonably simple way of duplicating all related concerns, to provide multiple pools that all shared the same structure but held different objects. Since then various changes have happend in Ruby's memory layout: * The concept of tomb heaps has been replaced by a global free pages list, with each page having it's slot size reconfigured at the point when it is resurrected * the eden heap has been inlined into the size pool itself, so that now the size pool directly controls the free_pages list, the sweeping page, the compaction cursor and the other state that was previously being managed by the eden heap. Now that there is no need for a heap wrapper, we should refer to the collection of pages containing Ruby objects as a heap again rather than a size pool Notes: Merged: https://github.com/ruby/ruby/pull/11771
2024-07-03Move ruby_load_external_gc_from_argv to gc.hPeter Zhu
2024-07-03[Feature #20470] Split GC into gc_impl.cPeter Zhu
This commit splits gc.c into two files: - gc.c now only contains code not specific to Ruby GC. This includes code to mark objects (which the GC implementation may choose not to use) and wrappers for internal APIs that the implementation may need to use (e.g. locking the VM). - gc_impl.c now contains the implementation of Ruby's GC. This includes marking, sweeping, compaction, and statistics. Most importantly, gc_impl.c only uses public APIs in Ruby and a limited set of functions exposed in gc.c. This allows us to build gc_impl.c independently of Ruby and plug Ruby's GC into itself.
2024-04-24Add ruby_mimcallocPeter Zhu
Many places call ruby_mimmalloc then MEMZERO. This can be reduced by using ruby_mimcalloc instead.
2024-04-18Remove unused rb_size_pool_slot_sizePeter Zhu
2024-04-15Initialize external GC LibraryMatt Valentine-House
Co-Authored-By: Peter Zhu <[email protected]>
2024-03-27Fix setting GC stress at boot when objspace not availablePeter Zhu
2024-03-26Refactor init_copy gc attributeseileencodes
This PR moves `rb_copy_wb_protected_attribute` and `rb_gc_copy_finalizer` into a single function called `rb_gc_copy_attributes` to be called by `init_copy`. This reduces the surface area of the GC API. Co-authored-by: Peter Zhu <[email protected]>
2024-03-25Fix --debug=gc_stress flagPeter Zhu
ruby_env_debug_option gets called after Init_gc_stress, so the --debug=gc_stress flag never works.
2024-03-20Make rb_aligned_malloc privatePeter Zhu
It is not used anywhere else.
2024-03-18Remove duplicated function prototype rb_gc_disable_no_restPeter Zhu
2024-03-18Remove rb_raw_obj_info_basicPeter Zhu
It's not used outside of gc.c.
2024-03-14[Feature #20265] Remove rb_newobj_of and RB_NEWOBJ_OFPeter Zhu
2024-03-13Don't directly read the SIZE_POOL_COUNT in shapesPeter Zhu
This removes the assumption about SIZE_POOL_COUNT for shapes.
2024-03-13Simplify NEWOBJ_OF macroPeter Zhu
2024-03-11Use NEWOBJ_OF_ec in NEWOBJ_OF_0Peter Zhu
2024-03-08Retire RUBY_MARK_UNLESS_NULLJean Boussier
Marking `Qnil` or `Qfalse` works fine, having an extra macro to avoid it isn't needed.
2024-02-28Make rb_define_finalizer_no_check privatePeter Zhu
2024-02-28Remove unused rb_gc_id2ref_obj_tblPeter Zhu
2024-02-26Remove rb_objspace_marked_object_pPeter Zhu
rb_objspace_marked_object_p is no longer used in the objspace module, so we can remove it.
2024-02-26Make rb_objspace_data_type_memsize privatePeter Zhu
rb_objspace_data_type_memsize is not used in the objspace module, so we can make it private.
2024-02-26Remove unused rb_objspace_each_objects_without_setupPeter Zhu
2024-02-22Extract imemo functions from gc.c into imemo.cPeter Zhu
2024-02-14Move rb_class_allocate_instance from gc.c to object.cPeter Zhu
2024-01-11Fix crash when printing RGENGC_DEBUG=5 output from GCKJ Tsanaktsidis
I was trying to debug an (unrelated) issue in the GC, and wanted to turn on the trace-level GC output by compiling it with -DRGENGC_DEBUG=5. Unfortunately, this actually causes a crash in newobj_init() because the code there tries to log the obj_info() of the newly created object. However, the object is not actually sufficiently set up for some of the things that obj_info() tries to do: * The instance variable table for a class is not yet initialized, and when using variable-length RVALUES, said ivar table is embedded in as-yet unitialized memory after the struct RValue. Attempting to read this, as obj_info() does, causes a crash. * T_DATA variables need to dereference their ->type field to print out the underlying C type name, which is not set up until newobj_fill() is called. To fix this, create a new method `obj_info_basic`, which dumps out only the parts of the object that are valid before the object is fully initialized. [Fixes #18795]
2023-11-24Fix compaction for generic ivarsPeter Zhu
When generic instance variable has a shape, it is marked movable. If it it transitions to too complex, it needs to update references otherwise it may have incorrect references.
2023-10-23rb_shape_transition_shape_capa: use optimal sizes transitionsJean Boussier
Previously the growth was 3(embed), 6, 12, 24, ... With this change it's now 3(embed), 8, 16, 32, 64, ... by default. However, since power of two isn't the best size for all allocators, if `malloc_usable_size` is vailable, we use it to discover the best offset. On Linux/glibc 2.35 for instance, the growth will be 3(embed), 7, 15, 31 to avoid wasting 8B per object. Test program: ```c size_t test(size_t slots) { size_t allocated = slots * VALUE_SIZE; void *test_ptr = malloc(allocated); size_t wasted = malloc_usable_size(test_ptr) - allocated; free(test_ptr); fprintf(stderr, "slots = %lu, wasted_bytes = %lu\n", slots, wasted); return wasted; } int main(int argc, char *argv[]) { size_t best_padding = 0; size_t padding = 0; for (padding = 0; padding <= 2; padding++) { size_t wasted = test(8 - padding); if (wasted == 0) { best_padding = padding; break; } } size_t index = 0; fprintf(stderr, "=============== naive ================\n"); size_t list_size = 4; for (index = 0; index < 10; index++) { test(list_size); list_size *= 2; } fprintf(stderr, "=============== auto-padded (-%lu) ================\n", best_padding); list_size = 4; for (index = 0; index < 10; index ++) { test(list_size - best_padding); list_size *= 2; } fprintf(stderr, "\n\n"); return 0; } ``` ``` ===== glibc ====== slots = 8, wasted_bytes = 8 slots = 7, wasted_bytes = 0 =============== naive ================ slots = 4, wasted_bytes = 8 slots = 8, wasted_bytes = 8 slots = 16, wasted_bytes = 8 slots = 32, wasted_bytes = 8 slots = 64, wasted_bytes = 8 slots = 128, wasted_bytes = 8 slots = 256, wasted_bytes = 8 slots = 512, wasted_bytes = 8 slots = 1024, wasted_bytes = 8 slots = 2048, wasted_bytes = 8 =============== auto-padded (-1) ================ slots = 3, wasted_bytes = 0 slots = 7, wasted_bytes = 0 slots = 15, wasted_bytes = 0 slots = 31, wasted_bytes = 0 slots = 63, wasted_bytes = 0 slots = 127, wasted_bytes = 0 slots = 255, wasted_bytes = 0 slots = 511, wasted_bytes = 0 slots = 1023, wasted_bytes = 0 slots = 2047, wasted_bytes = 0 ``` ``` ========== jemalloc ======= slots = 8, wasted_bytes = 0 =============== naive ================ slots = 4, wasted_bytes = 0 slots = 8, wasted_bytes = 0 slots = 16, wasted_bytes = 0 slots = 32, wasted_bytes = 0 slots = 64, wasted_bytes = 0 slots = 128, wasted_bytes = 0 slots = 256, wasted_bytes = 0 slots = 512, wasted_bytes = 0 slots = 1024, wasted_bytes = 0 slots = 2048, wasted_bytes = 0 =============== auto-padded (-0) ================ slots = 4, wasted_bytes = 0 slots = 8, wasted_bytes = 0 slots = 16, wasted_bytes = 0 slots = 32, wasted_bytes = 0 slots = 64, wasted_bytes = 0 slots = 128, wasted_bytes = 0 slots = 256, wasted_bytes = 0 slots = 512, wasted_bytes = 0 slots = 1024, wasted_bytes = 0 slots = 2048, wasted_bytes = 0 ```
2023-09-06Fix crash in WeakMap during compactionPeter Zhu
WeakMap can crash during compaction because the st_insert could allocate memory.
2023-09-05