summaryrefslogtreecommitdiff
path: root/internal
AgeCommit message (Collapse)Author
2025-08-27Replace ROBJECT_EMBED by ROBJECT_HEAPJean Boussier
The embed layout is way more common than the heap one, especially since WVA. I think it makes for more readable code to inverse the flag.
2025-08-26Ensure T_OBJECT and T_IMEMO/fields have identical layoutJean Boussier
2025-08-25Get rid of obj_ivar_set_transition_too_complexJean Boussier
2025-08-22Fixes to encoding/transcoding for ractors.Luke Gruber
Not all ractor-related encoding issues were fixed by 1afc07e815051e2f73493f055f2130cb642ba12a. I found more by running my test-all branch with 3 ractors for each test.
2025-08-21Atomic CC table set in cache_callable_method_entryJohn Hawthorn
2025-08-19ZJIT: Compile toregexp (#14200)Daniel Colson
`toregexp` is fairly similar to `concatstrings`, so this commit extracts a helper for pushing and popping operands on the native stack. There's probably opportunity to move some of this into lir (e.g. Alan suggested a push_many that could use STP on ARM to push 2 at a time), but I might save that for another day.
2025-08-13imemo_fields: store owner object in RBasic.klassJean Boussier
It is much more convenient than storing the klass, especially when dealing with `object_id` as it allows to update the id2ref table without having to dereference the owner, which may be garbage at that point.
2025-08-12set.c: Store `set_table->bins` at the end of `set_table->entries`Jean Boussier
This saves one pointer in `struct set_table`, which would allow `Set` objects to still fit in 80B TypedData slots even if RTypedData goes from 32B to 40B large. The existing set benchmark seem to show this doesn't have a very significant impact. Smaller sets are a bit faster, larger sets a bit slower. It seem consistent over multiple runs, but it's unclear how much of that is just error margin. ``` compare-ruby: ruby 3.5.0dev (2025-08-12T02:14:57Z master 428937a536) +YJIT +PRISM [arm64-darwin24] built-ruby: ruby 3.5.0dev (2025-08-12T07:22:26Z set-entries-bounds da30024fdc) +YJIT +PRISM [arm64-darwin24] warming up........ | |compare-ruby|built-ruby| |:------------------------|-----------:|---------:| |new_0 | 15.459M| 15.823M| | | -| 1.02x| |new_10 | 3.484M| 3.574M| | | -| 1.03x| |new_100 | 546.992k| 564.679k| | | -| 1.03x| |new_1000 | 49.391k| 48.169k| | | 1.03x| -| |aref_0 | 18.643M| 19.350M| | | -| 1.04x| |aref_10 | 5.941M| 6.006M| | | -| 1.01x| |aref_100 | 822.197k| 814.219k| | | 1.01x| -| |aref_1000 | 83.230k| 79.411k| | | 1.05x| -| ```
2025-08-07symbol.c: use `rb_gc_mark_and_move` over `rb_gc_location`Jean Boussier
The `p->field = rb_gc_location(p->field)` isn't ideal because it means all references are rewritten on compaction, regardless of whether the referenced object has moved. This isn't good for caches nor for Copy-on-Write. `rb_gc_mark_and_move` avoid needless writes, and most of the time allow to have a single function for both marking and updating references.
2025-08-06Struct: keep direct reference to IMEMO/fields when space allowsJean Boussier
It's not rare for structs to have additional ivars, hence are one of the most common, if not the most common type in the `gen_fields_tbl`. This can cause Ractor contention, but even in single ractor mode means having to do a hash lookup to access the ivars, and increase GC work. Instead, unless the struct is perfectly right sized, we can store a reference to the associated IMEMO/fields object right after the last struct member. ``` compare-ruby: ruby 3.5.0dev (2025-08-06T12:50:36Z struct-ivar-fields-2 9a30d141a1) +PRISM [arm64-darwin24] built-ruby: ruby 3.5.0dev (2025-08-06T12:57:59Z struct-ivar-fields-2 2ff3ec237f) +PRISM [arm64-darwin24] warming up..... | |compare-ruby|built-ruby| |:---------------------|-----------:|---------:| |member_reader | 590.317k| 579.246k| | | 1.02x| -| |member_writer | 543.963k| 527.104k| | | 1.03x| -| |member_reader_method | 213.540k| 213.004k| | | 1.00x| -| |member_writer_method | 192.657k| 191.491k| | | 1.01x| -| |ivar_reader | 403.993k| 569.915k| | | -| 1.41x| ``` Co-Authored-By: Étienne Barrié <etienne.barrie@gmail.com>
2025-08-06variable.c: refactor accesses to the generic_fields_tblJean Boussier
All accesses to `generic_fields_tbl_` are now encapsulated inside: - `rb_obj_fields` - `rb_obj_set_fields` - `rb_obj_replace_fields`
2025-08-05Fix RUBY_FREE_AT_EXIT for static symbolsPeter Zhu
Since static symbols allocate memory, we should deallocate them at shutdown to prevent memory leaks from being reported with RUBY_FREE_AT_EXIT.
2025-08-01Make `RClass.cc_table` a managed objectJean Boussier
For now this doesn't change anything, but now that the table is managed by GC, it opens the door to use RCU when in multi-ractor mode, hence allow unsynchornized reads.
2025-07-30ZJIT: Prepare for sharing JIT hooks with ZJIT (#14044)Takashi Kokubun
2025-07-29ZJIT: Add --zjit-stats (#14034)Takashi Kokubun
2025-07-29Improve performance of bignum[beg, len] (#14007)tomoya ishida
Implement rb_big_aref2. Taking a small slice from large bignum was slow in rb_int_aref2.
2025-07-29Get rid of imemo_astJean Boussier
It has been marked as obsolete for a while and I see no reason to keep it.
2025-07-24Disable TSAN for rb_gc_mark_machine_contextJohn Hawthorn
Previously this was listed as a suppression, but we actually want this permanently unsanitized. This should be faster and more reliable since TASN won't have to match against symbolicated backtraces.
2025-07-24Remove unused imemo_parser_strtermPeter Zhu
2025-07-24Support `cause:` in `Thread#raise` and `Fiber#raise`. (#13967)Samuel Williams
* Add support for `cause:` argument to `Fiber#raise` and `Thread#raise`. The implementation behaviour is consistent with `Kernel#raise` and `Exception#initialize` methods, allowing the `cause:` argument to be passed to `Fiber#raise` and `Thread#raise`. This change ensures that the `cause:` argument is handled correctly, providing a more consistent and expected behavior when raising exceptions in fibers and threads. [Feature #21360] * Shared specs for Fiber/Thread/Kernel raise. --------- Co-authored-by: Samuel Williams <samuel.williams@shopify.com>
2025-07-23Cleanup M_TBL workarounds and commentsJohn Hawthorn
Previously we had an assertion that the method table was only set on young objects, and a comment stating that was how it needed to be used. I think that confused the complexity of the write barriers that may be needed here. * Setting an empty M_TBL never needs a write barrier * T_CLASS and T_MODULE should always fire a write barrier to newly added methods * T_ICLASS only needs a write barrier to methods when RCLASSEXT_ICLASS_IS_ORIGIN(x) && !RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(x) We shouldn't assume that the object being young is sufficient, because we also need write barriers for incremental marking and it's unreliable.
2025-07-21Introduce free function to rb_concurrent_set_funcsPeter Zhu
If we create a key but don't insert it (due to other Ractor winning the race), then it would leak memory if we don't free it. This introduces a new function to free that memory for this case.
2025-07-21Convert global symbol table to concurrent setPeter Zhu
2025-07-21Add rb_concurrent_set_findPeter Zhu
2025-07-21Add rb_concurrent_set_sizePeter Zhu
2025-07-15Make rb_concurrent_set_funcs constPeter Zhu
We should never modify rb_concurrent_set_funcs during runtime, so we can make it const.
2025-07-14Remove dead rb_cc_table_freePeter Zhu
2025-07-14Remove dead rb_cc_table_markPeter Zhu
2025-07-11Rename some set_* functions to set_table_*Jeremy Evans
These functions conflict with the planned C-API functions. Since they deal with the underlying set_table pointers and not Set instances, this seems like a more accurate name as well.
2025-07-10Make `rb_enc_autoload_p` atomicJean Boussier
Using `encoding->max_enc_len` as a way to check if the encoding has been loaded isn't atomic, because it's not atomically set last. Intead we can use a dedicated atomic value inside the encoding table.
2025-07-07Rename `ractor_safe_set` into `concurrent_set`Jean Boussier
There's nothing ractor related in them, and the classic terminology for these sort of data structures is `concurrent-*`, e.g. concurrent hash.
2025-07-03imemo_fields_set: save copying when reassigning a variableJean Boussier
If we still fit in the existing imemo/fields object we can update it atomically, saving a reallocation.
2025-06-30Inline ASAN poison functions when ASAN is not enabledPeter Zhu
The ASAN poison functions was always defined in gc.c, even if ASAN was not enabled. This made function calls to happen all the time even if ASAN is not enabled. This commit defines these functions as empty macros when ASAN is not enabled.
2025-06-28Fix race condition in signal handler query (#13712)Erik Berlin
* Fix race condition in signal handler query * Initialize signal lock dynamically and reset after fork * Fix signal handler mutex initialization conditions
2025-06-27Extract Ractor safe table used for frozen stringsPeter Zhu
This commit extracts the Ractor safe table used for frozen strings into ractor_safe_table.c, which will allow it to be used elsewhere, including for the global symbol table.
2025-06-26variable.c: Refactor `generic_field_set` / `generic_ivar_set`Jean Boussier
These two functions are very similar, they can share most of their logic.
2025-06-24Change how to correct the first lineno in the backtrace on ArgumentErrorYusuke Endoh
Follow up to fix 3b7373fd00a0ba456498a7b7d6de2a47c96434a2. In that commit, the line number in the first frame was overwritten after the whole backtrace was created. There was a problem that the line number was overwritten even if the location was backpatched. Instead, this commit uses first_lineno if the frame is VM_FRAME_MAGIC_DUMMY when generating the backtrace. Before the patch: ``` $ ./miniruby -e '[1, 2].inject(:tap)' -e:in '<main>': wrong number of arguments (given 1, expected 0) (ArgumentError) from -e:1:in 'Enumerable#inject' from -e:1:in '<main>' ``` After the patch: ``` $ ./miniruby -e '[1, 2].inject(:tap)' -e:1:in '<main>': wrong number of arguments (given 1, expected 0) (ArgumentError) from -e:1:in 'Enumerable#inject' from -e:1:in '<main>' ```
2025-06-23Make the critical level an enumNobuyoshi Nakada
2025-06-23Shink RClass when it is known they can't be namespacedJean Boussier
Even when namespaces are enabled, only a few core classes created during init will eventually be namespaced. For these it's OK to allocate a 320B slot to hold the extra namespace stuff. But for any class created post init, we know we'll never need the namespace and we can fit in a 160B slot.
2025-06-23Avoid creating namespace table for classes that can't be namespaced.Jean Boussier
2025-06-23Mark RClass instance that may be namespaced with RCLASS_NAMESPACEABLEJean Boussier
2025-06-23Optimize `rb_namespace_available`Jean Boussier
Rather than to lazily check the env using a trinary value, we can more straightforwardly check for the env during the VM boot. This allow `rb_namespace_available` to just be a pointer dereference.
2025-06-17Refactor generic fields to use `T_IMEMO/fields` objects.Jean Boussier
Followup: https://github.com/ruby/ruby/pull/13589 This simplify a lot of things, as we no longer need to manually manage the memory, we can use the Read-Copy-Update pattern and avoid numerous race conditions. Co-Authored-By: Étienne Barrié <etienne.barrie@gmail.com> Notes: Merged: https://github.com/ruby/ruby/pull/13626
2025-06-17Refactor `rb_imemo_fields_new` to not assume T_CLASSJean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13626
2025-06-17Rename `imemo_class_fields` -> `imemo_fields`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13626
2025-06-17Optimize `benchmark/vm_ivar_of_class`Jean Boussier
``` compare-ruby: ruby 3.5.0dev (2025-06-17T08:45:40Z master e9d35671d2) +PRISM [arm64-darwin24] last_commit=[ruby/json] Fix a typo built-ruby: ruby 3.5.0dev (2025-06-17T09:27:05Z opt-getivar-for-cl.. ed1d7cd778) +PRISM [arm64-darwin24] | |compare-ruby|built-ruby| |:---------------------|-----------:|---------:| |vm_ivar_of_class_set | 12.306M| 13.957M| | | -| 1.13x| |vm_ivar_of_class | 16.167M| 24.029M| | | -| 1.49x| ``` Notes: Merged: https://github.com/ruby/ruby/pull/13639
2025-06-14Fix blocking operation cancellation. (#13614)Samuel Williams
Expose `rb_thread_resolve_unblock_function` internally. Notes: Merged-By: ioquatix <samuel@codeotaku.com>
2025-06-13Add SHAPE_ID_HAS_IVAR_MASK for quick ivar checkJean Boussier
This allow checking if an object has ivars with just a shape_id mask. Notes: Merged: https://github.com/ruby/ruby/pull/13606
2025-06-12Add a new_thread flag to rb_interrupt_execJohn Hawthorn
Previously rb_ractor_interrupt_exec would use an intermediate function to create a new thread with the actual target function, replacing the data being passed in with a piece of malloc memory holding the "next" function and the original data. Because of this, passing rb_interrupt_exec_flag_value_data to rb_ractor_interrupt_exec didn't have the intended effect of allowing data to be passed in and marked. This commit adds a rb_interrupt_exec_flag_new_thread flag, which both simplifies the implementation and allows the original data to be marked. Notes: Merged: https://github.com/ruby/ruby/pull/13531
2025-06-12Make setting and accessing class ivars lock-freeJean Boussier
Now that class fields have been deletated to a T_IMEMO/class_fields when we're in multi-ractor mode, we can read and write class instance variable in an atomic way using Read-Copy-Update (RCU). Note when in multi-ractor mode, we always use RCU. In theory we don't need to, instead if we ensured the field is written before the shape is updated it would be safe. Benchmark: ```ruby Warning[:experimental] = false class Foo @foo = 1 @bar = 2 @baz = 3 @egg = 4 @spam = 5 class << self attr_reader :foo, :bar, :baz, :egg, :spam end end ractors = 8.times.map do Ractor.new do 1_000_000.times do Foo.bar + Foo.baz * Foo.egg - Foo.spam end end end if Ractor.method_defined?(:value) ractors.each(&:value) else ractors.each(&:take) end ``` This branch vs Ruby 3.4: ```bash $ hyperfine -w 1 'ruby --disable-all ../test.rb' './miniruby ../test.rb' Benchmark 1: ruby --disable-all ../test.rb Time (mean ± σ): 3.162 s ± 0.071 s [User: 2.783 s, System: 10.809 s] Range (min … max): 3.093 s … 3.337 s 10 runs Benchmark 2: ./miniruby ../test.rb Time (mean ± σ): 208.7 ms ± 4.6 ms [User: 889.7 ms, System: 6.9 ms] Range (min … max): 202.8 ms … 222.0 ms 14 runs Summary ./miniruby ../test.rb ran 15.15 ± 0.47 times faster than ruby --disable-all ../test.rb ``` Notes: Merged: https://github.com/ruby/ruby/pull/13594