summaryrefslogtreecommitdiff
path: root/gc.c
AgeCommit message (Collapse)Author
2022-11-10Remove numiv from RObjectJemma Issroff
Since object shapes store the capacity of an object, we no longer need the numiv field on RObjects. This gives us one extra slot which we can use to give embedded objects one more instance variable (for a total of 3 ivs). This commit removes the concept of numiv from RObject. Notes: Merged: https://github.com/ruby/ruby/pull/6699
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-11-06[wasm] Scan machine stack based on `ec->machine.stack_{start,end}`Yuta Saito
fiber machine stack is placed outside of C stack allocated by wasm-ld, so highest stack address recorded by `rb_wasm_record_stack_base` is invalid when running on non-main fiber. Therefore, we should scan `stack_{start,end}` which always point a valid stack range in any context. Notes: Merged: https://github.com/ruby/ruby/pull/6679
2022-11-04Increment max_iv_count on class in gc marking, not gc freeingJemma Issroff
We were previously incrementing the max_iv_count on a class in gc freeing. By the time we free an object though, we're not guaranteed its class is still valid. Instead, we can do this when marking and we're guaranteed the object still knows its class. Notes: Merged: https://github.com/ruby/ruby/pull/6673
2022-10-31Implement object shapes for T_CLASS and T_MODULE (#6637)John Hawthorn
* Avoid RCLASS_IV_TBL in marshal.c * Avoid RCLASS_IV_TBL for class names * Avoid RCLASS_IV_TBL for autoload * Avoid RCLASS_IV_TBL for class variables * Avoid copying RCLASS_IV_TBL onto ICLASSes * Use object shapes for Class and Module IVs Notes: Merged-By: jhawthorn <john@hawthorn.email>
2022-10-28fix ASAN error in GCAaron Patterson
2022-10-21Rename `iv_count` on shapes to `next_iv_index`Jemma Issroff
`iv_count` is a misleading name because when IVs are unset, the new shape doesn't decrement this value. `next_iv_count` is an accurate, and more descriptive name. Notes: Merged: https://github.com/ruby/ruby/pull/6608
2022-10-21Remove unused class serialJemma Issroff
Before object shapes, we were using class serial to invalidate inline caches. Now that we use shape_id for inline cache keys, the class serial is unnecessary. Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/6605
2022-10-21Check writebarrier arguments only when RGENGC_CHECK_MODE [ci skip]Nobuyoshi Nakada
The commit 575ae50d16a03ed23357ec4ea0dbf7167fc26c8c was for debugging the failure triggered by f55212bce939f736559709a8cd16c409772389c8, and it was fixed at the commit 39f7eddec4c55711d56f05b085992a83bf23159e.
2022-10-20Check writebarrier argumentsNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/6600
2022-10-19Stop zeroing memory on allocation / copyAaron Patterson
Shapes gives us an almost exact count of instance variables on an object. Since we know the number of instance variables that have been set, we will never access slots that haven't been initialized with an IV. Notes: Merged: https://github.com/ruby/ruby/pull/6585
2022-10-19Fix and improve coroutines for Darwin (macOS) ppc/ppc64. (#5975)Sergey Fedorov
Notes: Merged-By: ioquatix <samuel@codeotaku.com>
2022-10-15More precisely iterate over Object instance variablesAaron Patterson
Shapes provides us with an (almost) exact count of instance variables. We only need to check for Qundef when an IV has been "undefined" Prefer to use ROBJECT_IV_COUNT when iterating IVs Notes: Merged: https://github.com/ruby/ruby/pull/6555
2022-10-14Use `roomof` macro for rounding up divisionsNobuyoshi Nakada
2022-10-11Revert "Revert "This commit implements the Object Shapes technique in CRuby.""Jemma Issroff
This reverts commit 9a6803c90b817f70389cae10d60b50ad752da48f.
2022-10-07Add IO#timeout attribute and use it for blocking IO operations. (#5653)Samuel Williams
Notes: Merged-By: ioquatix <samuel@codeotaku.com>
2022-10-04[Bug #19028] Suppress GCC 12 `-Wuse-after-free` false warningNobuyoshi Nakada
GCC 12 introduced a new warning flag `-Wuse-after-free`, however it has a false positive at `realloc` when optimization is disabled, since the memory requested for reallocation is guaranteed to not be touched. This workaround is very unclear why the false warning is suppressed by a statement-expression GCC extension. Notes: Merged: https://github.com/ruby/ruby/pull/6487
2022-09-30Revert "This commit implements the Object Shapes technique in CRuby."Aaron Patterson
This reverts commit 68bc9e2e97d12f80df0d113e284864e225f771c2.
2022-09-28This commit implements the Object Shapes technique in CRuby.Jemma Issroff
Object Shapes is used for accessing instance variables and representing the "frozenness" of objects. Object instances have a "shape" and the shape represents some attributes of the object (currently which instance variables are set and the "frozenness"). Shapes form a tree data structure, and when a new instance variable is set on an object, that object "transitions" to a new shape in the shape tree. Each shape has an ID that is used for caching. The shape structure is independent of class, so objects of different types can have the same shape. For example: ```ruby class Foo def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end class Bar def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end foo = Foo.new # `foo` has shape id 2 bar = Bar.new # `bar` has shape id 2 ``` Both `foo` and `bar` instances have the same shape because they both set instance variables of the same name in the same order. This technique can help to improve inline cache hits as well as generate more efficient machine code in JIT compilers. This commit also adds some methods for debugging shapes on objects. See `RubyVM::Shape` for more details. For more context on Object Shapes, see [Feature: #18776] Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org> Co-Authored-By: Eileen M. Uchitelle <eileencodes@gmail.com> Co-Authored-By: John Hawthorn <john@hawthorn.email>
2022-09-28Always use the longer version of `TRY_WITH_GC`Nobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/6464
2022-09-26Revert this until we can figure out WB issues or remove shapes from GCAaron Patterson
Revert "* expand tabs. [ci skip]" This reverts commit 830b5b5c351c5c6efa5ad461ae4ec5085e5f0275. Revert "This commit implements the Object Shapes technique in CRuby." This reverts commit 9ddfd2ca004d1952be79cf1b84c52c79a55978f4.
2022-09-27* expand tabs. [ci skip]git
Tabs were expanded because the file did not have any tab indentation in unedited lines. Please update your editor config, and use misc/expand_tabs.rb in the pre-commit hook.
2022-09-26This commit implements the Object Shapes technique in CRuby.Jemma Issroff
Object Shapes is used for accessing instance variables and representing the "frozenness" of objects. Object instances have a "shape" and the shape represents some attributes of the object (currently which instance variables are set and the "frozenness"). Shapes form a tree data structure, and when a new instance variable is set on an object, that object "transitions" to a new shape in the shape tree. Each shape has an ID that is used for caching. The shape structure is independent of class, so objects of different types can have the same shape. For example: ```ruby class Foo def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end class Bar def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end foo = Foo.new # `foo` has shape id 2 bar = Bar.new # `bar` has shape id 2 ``` Both `foo` and `bar` instances have the same shape because they both set instance variables of the same name in the same order. This technique can help to improve inline cache hits as well as generate more efficient machine code in JIT compilers. This commit also adds some methods for debugging shapes on objects. See `RubyVM::Shape` for more details. For more context on Object Shapes, see [Feature: #18776] Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org> Co-Authored-By: Eileen M. Uchitelle <eileencodes@gmail.com> Co-Authored-By: John Hawthorn <john@hawthorn.email> Notes: Merged: https://github.com/ruby/ruby/pull/6386
2022-09-26Rework vm_core to use `int first_lineno` struct member.Samuel Williams
Notes: Merged: https://github.com/ruby/ruby/pull/6430
2022-08-09Skip poisoned regionsNobuyoshi Nakada
Poisoned regions cannot be accessed without unpoisoning outside gc.c. Specifically, debug.gem is terminated by AddressSanitizer. ``` SUMMARY: AddressSanitizer: use-after-poison iseq_collector.c:39 in iseq_i ```
2022-07-28Lock the VM for rb_gc_writebarrier_unprotectPeter Zhu
When using Ractors, rb_gc_writebarrier_unprotect requries a VM lock since it modifies the bitmaps. Notes: Merged: https://github.com/ruby/ruby/pull/6192
2022-07-28Make array slices views rather than copiesPeter Zhu
Before this commit, if the slice fits in VWA, it would make a copy rather than a view. This is slower as it requires a memcpy of the contents. Notes: Merged: https://github.com/ruby/ruby/pull/6192
2022-07-28Refactor gc_ref_update_arrayPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/6192
2022-07-28Suppress use-after-free warning by gcc-12Nobuyoshi Nakada
2022-07-27Adjust styles [ci skip]Nobuyoshi Nakada
2022-07-27* expand tabs. [ci skip]git
Tabs were expanded because the file did not have any tab indentation in unedited lines. Please update your editor config, and use misc/expand_tabs.rb in the pre-commit hook.
2022-07-26Refactored poisoning and unpoisoning freelist to simpler APIJemma Issroff
2022-07-26Rename rb_ary_tmp_new to rb_ary_hidden_newPeter Zhu
rb_ary_tmp_new suggests that the array is temporary in some way, but that's not true, it just creates an array that's hidden and not on the transient heap. This commit renames it to rb_ary_hidden_new. Notes: Merged: https://github.com/ruby/ruby/pull/6180
2022-07-25Fix format specifierNobuyoshi Nakada
`uintptr_t` is not always `unsigned long`, but can be casted to void pointer safely.
2022-07-21Expand tabs [ci skip]Takashi Kokubun
[Misc #18891] Notes: Merged: https://github.com/ruby/ruby/pull/6094
2022-07-21[Bug #18929] Fix heap creation thrashing in GCPeter Zhu
Before this commit, if we don't have enough slots after sweeping but had pages on the tomb heap, then the GC would frequently allocate and deallocate pages. This is because after sweeping it would set allocatable pages (since there were not enough slots) but free the pages on the tomb heap. This commit reuses pages on the tomb heap if there's not enough slots after sweeping. Notes: Merged: https://github.com/ruby/ruby/pull/6156
2022-07-21Refactor macros of array.cPeter Zhu
Move some macros in array.c to internal/array.h so that other files can also access these macros. Notes: Merged: https://github.com/ruby/ruby/pull/6157
2022-07-20Ensure _id2ref finds symbols with the correct typeDaniel Colson
Prior to this commit it was possible to call `ObjectSpace._id2ref` with an offset static symbol object_id and get back a new, incorrectly tagged symbol: ``` > sensible_sym = ObjectSpace._id2ref(:a.object_id) => :a > nonsense_sym = ObjectSpace._id2ref(:a.object_id + 40) => :a > sensible_sym == nonsense_sym => false ``` `nonsense_sym` ends up tagged with `RUBY_ID_INSTANCE` instead of `RB_ID_LOCAL`. That means we can do silly things like: ``` > foo = Object.new > foo.instance_variable_set(:a, 123) (irb):2:in `instance_variable_set': `a' is not allowed as an instance variable name (NameError) > foo.instance_variable_set(ObjectSpace._id2ref(:a.object_id + 40), 123) => 123 > foo.instance_variables => [:a] ``` This was happening because `get_id_entry` ignores the tag bits when looking up the symbol. So `rb_id2str(symid)` would return a value and then we'd continue on with the nonsense `symid`. This commit prevents the situation by checking that the `symid` actually matches what we get back from `get_id_entry`. Now we get a `RangeError` for the nonsense id: ``` > ObjectSpace._id2ref(:a.object_id) => :a > ObjectSpace._id2ref(:a.object_id + 40) (irb):1:in `_id2ref': 0x000000000013f408 is not symbol id value (RangeError) ``` Co-authored-by: John Hawthorn <jhawthorn@github.com> Notes: Merged: https://github.com/ruby/ruby/pull/6147
2022-07-20[Bug #18928] Fix crash in WeakMapPeter Zhu
In wmap_live_p, if is_pointer_to_heap returns false, then the page is either in the tomb or has already been freed, so the object is dead. In this case, wmap_live_p should return false. Notes: Merged: https://github.com/ruby/ruby/pull/6152
2022-07-20Fix free objects count conditionNobuyoshi Nakada
Free objects have `T_NONE` as the builtin type. A pointer to a valid array element will never be `NULL`. Notes: Merged: https://github.com/ruby/ruby/pull/6153 Merged-By: nobu <nobu@ruby-lang.org>
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