summaryrefslogtreecommitdiff
path: root/internal/gc.h
AgeCommit message (Collapse)Author
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-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-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-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 <byroot@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/8113
2023-07-17Implement Process.warmupJean Boussier
[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. Notes: Merged: https://github.com/ruby/ruby/pull/7662
2023-06-12[Feature #19719] Universal Parseryui-knk
Introduce Universal Parser mode for the parser. This commit includes these changes: * Introduce `UNIVERSAL_PARSER` macro. All of CRuby related functions are passed via `struct rb_parser_config_struct` when this macro is enabled. * Add CI task with 'cppflags=-DUNIVERSAL_PARSER' for ubuntu. Notes: Merged: https://github.com/ruby/ruby/pull/7927
2023-04-16Make classes embedded on 32 bitPeter Zhu
Classes are now exactly 80 bytes when embedded, which perfectly fits the 3rd size pool on 32 bit systems. Notes: Merged: https://github.com/ruby/ruby/pull/7719
2023-04-11Enable 5 size pools on 32 bit systemsPeter Zhu
This commit will allow 32 bit systems to take advantage of VWA. Notes: Merged: https://github.com/ruby/ruby/pull/7688
2023-04-06[Feature #19474] Refactor NEWOBJ macrosMatt Valentine-House
NEWOBJ_OF is now our canonical newobj macro. It takes an optional ec Notes: Merged: https://github.com/ruby/ruby/pull/7393
2023-04-06Remove dependancy of vm_core.h on shape.hMatt Valentine-House
so that now shape can happily include gc.h Notes: Merged: https://github.com/ruby/ruby/pull/7393
2023-04-04[Feature #19579] Remove !USE_RVARGC code (#7655)Peter Zhu
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. Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-04-04Revert "Fix transient heap mode"Aaron Patterson
This reverts commit 87253d047ce35e7836b6f97edbb4f819879a3b25. Revert "Implement `Process.warmup`" This reverts commit ba6ccd871442f55080bffd53e33678c0726787d2.
2023-04-04Implement `Process.warmup`Jean Boussier
[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. Notes: Merged: https://github.com/ruby/ruby/pull/7346
2023-03-27Allow user defined SIZE_POOL_COUNTPeter Zhu
We shouldn't overwrite the value of SIZE_POOL_COUNT if the user has specified one.
2023-03-15Move RB_GC_SAVE_MACHINE_CONTEXT to vm_core.hMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/7465
2023-03-10Move WeakMap and WeakKeyMap code to weakmap.cPeter Zhu
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. Notes: Merged: https://github.com/ruby/ruby/pull/7451
2023-03-09Remove unused forward decl of rb_thread_structMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/7467
2023-03-06Stop exporting symbols for MJITTakashi Kokubun
Notes: Merged: https://github.com/ruby/ruby/pull/7459
2023-02-09Merge gc.h and internal/gc.hMatt Valentine-House
[Feature #19425] Notes: Merged: https://github.com/ruby/ruby/pull/7273
2023-02-07Make Time objects WB protectedPeter Zhu
Co-Authored-By: Jean Boussier <byroot@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/7244
2023-02-07Fix typo in gc.h [ci skip]Peter Zhu
2023-01-21In `UNALIGNED_MEMBER_PTR` cast through `void` pointerNobuyoshi Nakada
Suppress warnings shown even with `-Waddress-of-packed-member` disabled in gcc 11. Notes: Merged: https://github.com/ruby/ruby/pull/7161
2023-01-19Add rb_gc_mark_and_move and implement on iseqPeter Zhu
This commit adds rb_gc_mark_and_move which takes a pointer to an object and marks it during marking phase and updates references during compaction. This allows for marking and reference updating to be combined into a single function, which reduces code duplication and prevents bugs if marking and reference updating goes out of sync. This commit also implements rb_gc_mark_and_move on iseq as an example. Notes: Merged: https://github.com/ruby/ruby/pull/7140
2023-01-18Don't redefine RB_OBJ_WRITEPeter Zhu
RB_OBJ_WRITE already exists in rgengc.h, so we shouldn't redefine it in gc.h. Notes: Merged: https://github.com/ruby/ruby/pull/7131
2022-12-15Move definition of SIZE_POOL_COUNT back to gc.hPeter Zhu
SIZE_POOL_COUNT is a GC macro, it should belong in gc.h and not shape.h. SIZE_POOL_COUNT doesn't depend on shape.h so we can have shape.h depend on gc.h. Co-Authored-By: Matt Valentine-House <matt@eightbitraptor.com> Notes: Merged: https://github.com/ruby/ruby/pull/6940
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-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-05-09Increase SIZE_POOL_COUNT to 5Peter Zhu
Having more size pools will allow us to allocate larger objects through Variable Width Allocation. I have attached some benchmark results below. Discourse: On Discourse, we don't see much change in response times. We do see a small reduction in RSS. Branch RSS: 377.8 MB Master RSS: 396.3 MB railsbench: On railsbench, we don't see a big change in RPS or p99 performance. We see a small increase in RSS. Branch RPS: 815.38 Master RPS: 811.73 Branch p99: 1.69 ms Master p99: 1.68 ms Branch RSS: 90.6 MB Master RSS: 89.4 MB liquid: We don't see a significant change in liquid performance. Branch parse & render: 29.041 I/s Master parse & render: 29.211 I/s Notes: Merged: https://github.com/ruby/ruby/pull/5885
2022-03-30Decouple incremental marking step from page sizesPeter Zhu
Currently, the number of incremental marking steps is calculated based on the number of pooled pages available. This means that if we make Ruby heap pages larger, it would run fewer incremental marking steps (which would mean each incremental marking step takes longer). This commit changes incremental marking to run after every INCREMENTAL_MARK_STEP_ALLOCATIONS number of allocations. This means that the behaviour of incremental marking remains the same regardless of the Ruby heap page size. I've benchmarked against discourse benchmarks and did not get a significant change in response times beyond the margin of error. This is expected as this new incremental marking algorithm behaves very similarly to the previous one. Notes: Merged: https://github.com/ruby/ruby/pull/5732
2022-02-16Change darray size to size_t and add functions that use GC mallocPeter Zhu
Changes size and capacity of darray to size_t to support more elements. Adds functions to darray that use GC allocation functions. Notes: Merged: https://github.com/ruby/ruby/pull/5546
2021-11-23Speed up Ractors for Variable Width AllocationPeter Zhu
This commit adds a Ractor cache for every size pool. Previously, all VWA allocated objects used the slowpath and locked the VM. On a micro-benchmark that benchmarks String allocation: VWA turned off: 29.196591 0.889709 30.086300 ( 9.434059) VWA before this commit: 29.279486 41.477869 70.757355 ( 12.527379) VWA after this commit: 16.782903 0.557117 17.340020 ( 4.255603) Notes: Merged: https://github.com/ruby/ruby/pull/5151
2021-11-10gc.h: move rb_objspace_garbage_object_p to internal/gc.hYusuke Endoh
... to allow class.c to use the function Notes: Merged: https://github.com/ruby/ruby/pull/5097
2021-10-25[Feature #18239] Implement VWA for stringsPeter Zhu
This commit adds support for embedded strings with variable capacity and uses Variable Width Allocation to allocate strings. Notes: Merged: https://github.com/ruby/ruby/pull/4933
2021-10-25[Feature #18239] Refactor RVARGC alloc functionsPeter Zhu
The allocation functions no longer assume that one RVALUE needs to be allocated. Notes: Merged: https://github.com/ruby/ruby/pull/4933
2021-09-10internal/*.h: skip doxygen卜部昌平
These contents are purely implementation details, not worth appearing in CAPI documents. [ci skip] Notes: Merged: https://github.com/ruby/ruby/pull/4815
2021-08-25[Feature #18045] Implement size classes for GCPeter Zhu
This commits implements size classes in the GC for the Variable Width Allocation feature. Unless `USE_RVARGC` compile flag is set, only a single size class is created, maintaining current behaviour. See the redmine ticket for more details. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/4773
2021-08-25[Feature #18045] Remove T_PAYLOADPeter Zhu
This commit removes T_PAYLOAD since the new VWA implementation no longer requires T_PAYLOAD types. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/4773
2021-08-23Revert "[Feature #18045] Implement size classes for GC"Peter Zhu
This reverts commits 48ff7a9f3e47bffb3e4d067a12ba9b936261caa0 and b2e2cf2dedd104acad8610721db5e4d341f135ef because it is causing crashes in SPARC solaris and i386 debian. Notes: Merged: https://github.com/ruby/ruby/pull/4764
2021-08-23[Feature #18045] Implement size classes for GCPeter Zhu
This commits implements size classes in the GC for the Variable Width Allocation feature. Unless `USE_RVARGC` compile flag is set, only a single size class is created, maintaining current behaviour. See the redmine ticket for more details. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/4680
2021-08-23[Feature #18045] Remove T_PAYLOADPeter Zhu
This commit removes T_PAYLOAD since the new VWA implementation no longer requires T_PAYLOAD types. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/4680
2021-07-28Don't export rb_gc_ractor_newobj_cache_clearPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/4690
2021-07-15[Bug #18014] Fix memory leak in GC when using RactorsPeter Zhu
When a Ractor is removed, the freelist in the Ractor cache is not returned to the GC, leaving the freelist permanently lost. This commit recycles the freelist when the Ractor is destroyed, preventing a memory leak from occurring. Notes: Merged: https://github.com/ruby/ruby/pull/4613
2021-05-07Protoized old pre-ANSI K&R style declarations and definitionsNobuyoshi Nakada
2021-05-06Allow newobj_of0 and newobj_slowpath to allocate into multiple heap slotsMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/4391
2020-12-13Narrowed down unaligned member access region in RB_OBJ_WRITENobuyoshi Nakada
Since UNALIGNED_MEMBER_ACCESS assigns to an intermediate variable, it can cause unused-value warnings.
2020-12-07RB_EC_NEWOBJ_OFKoichi Sasada
NEWOBJ with current ec. Notes: Merged: https://github.com/ruby/ruby/pull/3842
2020-09-02Initialize new T_OBJECT as ROBJECT_EMBEDJohn Hawthorn
Previously, when an object is first initialized, ROBJECT_EMBED isn't set. This means that for brand new objects, ROBJECT_NUMIV(obj) is 0 and ROBJECT_IV_INDEX_TBL(obj) is NULL. Previously, this combination meant that the inline cache would never be initialized when setting an ivar on an object for the first time since iv_index_tbl was NULL, and if it were it would never be used because ROBJECT_NUMIV was 0. Both cases always fell through to the generic rb_ivar_set which would then set the ROBJECT_EMBED flag and initialize the ivar array. This commit changes rb_class_allocate_instance to set the ROBJECT_EMBED flag on the object initially and to initialize all members of the embedded array to Qundef. This allows the inline cache to be set correctly on first use and to be used on future uses. This moves rb_class_allocate_instance to gc.c, so that it has access to newobj_of. This seems appropriate given that there are other allocating methods in this file (ex. rb_data_object_wrap, rb_imemo_new). Notes: Merged: https://github.com/ruby/ruby/pull/3486
2020-05-11sed -i 's|ruby/impl|ruby/internal|'卜部昌平
To fix build failures. Notes: Merged: https://github.com/ruby/ruby/pull/3079