summaryrefslogtreecommitdiff
path: root/internal
AgeCommit message (Collapse)Author
2025-04-16Introduce `enum rb_io_mode`. (#7894)Samuel Williams
Notes: Merged-By: ioquatix <[email protected]>
2025-04-10Restore the original order of const_added and inherited callbacksXavier Noria
Originally, if a class was defined with the class keyword, the cref had a const_added callback, and the superclass an inherited callback, const_added was called first, and inherited second. This was discussed in https://bugs.ruby-lang.org/issues/21143 and an attempt at changing this order was made. While both constant assignment and inheritance have happened before these callbacks are invoked, it was deemed nice to have the same order as in C = Class.new This was mostly for alignment: In that last use case things happen at different times and therefore the order of execution is kind of obvious, whereas when the class keyword is involved, the order is opaque to the user and it is up to the interpreter. However, soon in https://bugs.ruby-lang.org/issues/21193 Matz decided to play safe and keep the existing order. This reverts commits: de097fbe5f3df105bd2a26e72db06b0f5139bc1a de48e47ddf78aba02fd9623bc7ce685540a10743 Notes: Merged: https://github.com/ruby/ruby/pull/13085
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-03-27Freeze $/ and make it ractor safeÉtienne Barrié
[Feature #21109] By always freezing when setting the global rb_rs variable, we can ensure it is not modified and can be accessed from a ractor. We're also making sure it's an instance of String and does not have any instance variables. Of course, if $/ is changed at runtime, it may cause surprising behavior but doing so is deprecated already anyway. Co-authored-by: Jean Boussier <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/12975
2025-03-20Trigger `inherited` and `const_set` callbacks after const has been definedJean Boussier
[Misc #21143] [Bug #21193] The previous change caused a backward compatibility issue with code that called `Object.const_source_location` from the `inherited` callback. To fix this, the order is now: - Define the constant - Invoke `inherited` - Invoke `const_set` Notes: Merged: https://github.com/ruby/ruby/pull/12956
2025-03-16Make ASAN default option string built-in librubyNobuyoshi Nakada
The content depends on ruby internal, not responsibility of the caller. Revive `RUBY_GLOBAL_SETUP` macro to define the hook function. Notes: Merged: https://github.com/ruby/ruby/pull/12933
2025-02-24String#gsub! Elide MatchData allocation when we know it can't escapeJean Boussier
In gsub is used with a string replacement or a map that doesn't have a default proc, we know for sure no code can cause the MatchData to escape the `gsub` call. In such case, we still have to allocate a new MatchData because we don't know what is the lifetime of the backref, but for any subsequent match we can re-use the MatchData we allocated ourselves, reducing allocations significantly. This partially fixes [Misc #20652], except when a block is used, and partially reduce the performance impact of abc0304cb28cb9dcc3476993bc487884c139fd11 / [Bug #17507] ``` compare-ruby: ruby 3.5.0dev (2025-02-24T09:44:57Z master 5cf146399f) +PRISM [arm64-darwin24] built-ruby: ruby 3.5.0dev (2025-02-24T10:58:27Z gsub-elude-match da966636e9) +PRISM [arm64-darwin24] warming up.... | |compare-ruby|built-ruby| |:----------------|-----------:|---------:| |escape | 3.577k| 3.697k| | | -| 1.03x| |escape_bin | 5.869k| 6.743k| | | -| 1.15x| |escape_utf8 | 3.448k| 3.738k| | | -| 1.08x| |escape_utf8_bin | 6.361k| 7.267k| | | -| 1.14x| ``` Co-Authored-By: Étienne Barrié <[email protected]>
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-02-19[Bug #21144] Win32: Use Windows time zone ID if TZ is not setNobuyoshi Nakada
If the TZ environment variable is not set, the time zone names retrieved from the system are localized for UI display and may vary across editions and language packs for the same time zone. Use the time zone IDs that are invariant across environments instead. Notes: Merged: https://github.com/ruby/ruby/pull/12765
2025-02-14Only count VM instructions in YJIT stats buildsAaron Patterson
The instruction counter is slowing multi-Ractor applications. I had changed it to use a thread local, but using a thread local is slowing single threaded applications. This commit only enables the instruction counter in YJIT stats builds until we can figure out a way to gather the information with lower overhead. Co-authored-by: Randy Stauner <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/12670
2025-02-13[Feature #21116] Extract RJIT as a third-party gemNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/12740
2025-02-12Elide string allocation when using `String#gsub` in MAP modeJean Boussier
If the provided Hash doesn't have a default proc, we know for sure that we'll never call into user provided code, hence the string we allocate to access the Hash can't possibly escape. So we don't actually have to allocate it, we can use a fake_str, AKA a stack allocated string. ``` compare-ruby: ruby 3.5.0dev (2025-02-10T13:47:44Z master 3fb455adab) +PRISM [arm64-darwin23] built-ruby: ruby 3.5.0dev (2025-02-10T17:09:52Z opt-gsub-alloc ea5c28958f) +PRISM [arm64-darwin23] warming up.... | |compare-ruby|built-ruby| |:----------------|-----------:|---------:| |escape | 3.374k| 3.722k| | | -| 1.10x| |escape_bin | 5.469k| 6.587k| | | -| 1.20x| |escape_utf8 | 3.465k| 3.734k| | | -| 1.08x| |escape_utf8_bin | 5.752k| 7.283k| | | -| 1.27x| ``` Notes: Merged: https://github.com/ruby/ruby/pull/12730
2025-02-10Move global symbol reference updating to rb_sym_global_symbols_update_referencesPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/12711
2025-02-10Make ruby_global_symbols movablePeter Zhu
The `ids` array and `dsymbol_fstr_hash` were pinned because they were kept alive by rb_vm_register_global_object. This prevented the GC from moving them even though there were reference updating code. This commit changes it to be marked movable by marking it as a root object. Notes: Merged: https://github.com/ruby/ruby/pull/12711
2025-01-27Use rb_gc_vm_weak_table_foreach for reference updatingPeter Zhu
We can use rb_gc_vm_weak_table_foreach for reference updating of weak tables in the default GC. Notes: Merged: https://github.com/ruby/ruby/pull/12629
2025-01-22Add generic ivar reference updating stepPeter Zhu
Previously, generic ivars worked differently than the other global tables during compaction. The other global tables had their references updated through iteration during rb_gc_update_vm_references. Generic ivars updated the keys when the object moved and updated the values while reference updating the object. This is inefficient as this required one lookup for every moved object and one lookup for every object with generic ivars. Instead, this commit changes it to iterate over the generic ivar table to update both the keys and values. Notes: Merged: https://github.com/ruby/ruby/pull/12607
2025-01-20Remove dead function rb_func_proc_newPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/12566
2025-01-10Make rb_vm_insns_count a thread local variableAaron Patterson
`rb_vm_insns_count` is a global variable used for reporting YJIT statistics. It is a counter that tallies the number of interpreter instructions that have been executed, this way we can approximate how much time we're spending in YJIT compared to the interpreter. Unfortunately keeping this statistic means that every instruction executed in the interpreter loop must increment the counter. Normally this isn't a problem, but in multi-threaded situations (when Ractors are used), incrementing this counter can become quite costly due to page caching issues. Additionally, since there is no locking when incrementing this global, the count can't really make sense in a multi-threaded environment. This commit changes `rb_vm_insns_count` to a thread local. That way each Ractor has it's own copy of the counter and incrementing the counter becomes quite cheap. Of course this means that in multi-threaded situations, the value doesn't really make sense (but it didn't make sense before because of the lack of locking). The counter is used for YJIT statistics, and since YJIT is basically disabled when Ractors are in use, I don't think we care about inaccuracies (for the time being). We can revisit this counter when we give YJIT multi-threading support, but for the time being this commit restores multi-threaded performance. To test this, I used the benchmark in [Bug #20489]. Here is the performance on Ruby 3.2: ``` $ time RUBY_MAX_CPU=12 ./miniruby -v ../test.rb 8 8 ruby 3.2.0 (2022-12-25 revision a528908271) [x86_64-linux] [0...1, 1...2, 2...3, 3...4, 4...5, 5...6, 6...7, 7...8] ../test.rb:43: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. ________________________________________________________ Executed in 2.53 secs fish external usr time 19.86 secs 370.00 micros 19.86 secs sys time 0.02 secs 320.00 micros 0.02 secs ``` We can see the regression in performance on the master branch: ``` $ time RUBY_MAX_CPU=12 ./miniruby -v ../test.rb 8 8 ruby 3.5.0dev (2025-01-10T16:22:26Z master 4a2702dafb) +PRISM [x86_64-linux] [0...1, 1...2, 2...3, 3...4, 4...5, 5...6, 6...7, 7...8] ../test.rb:43: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. ________________________________________________________ Executed in 24.87 secs fish external usr time 195.55 secs 0.00 micros 195.55 secs sys time 0.00 secs 716.00 micros 0.00 secs ``` Here are the stats after this commit: ``` $ time RUBY_MAX_CPU=12 ./miniruby -v ../test.rb 8 8 ruby 3.5.0dev (2025-01-10T20:37:06Z tl 3ef0432779) +PRISM [x86_64-linux] [0...1, 1...2, 2...3, 3...4, 4...5, 5...6, 6...7, 7...8] ../test.rb:43: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. ________________________________________________________ Executed in 2.46 secs fish external usr time 19.34 secs 381.00 micros 19.34 secs sys time 0.01 secs 321.00 micros 0.01 secs ``` [Bug #20489] Notes: Merged: https://github.com/ruby/ruby/pull/12549
2025-01-11Remove stale declaration for modular GCNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/12546
2025-01-08Pass allocation size to rb_imemo_newPeter Zhu
This would allow imemo to take advantage of VWA and allocate sizes larger than RVALUE (40 bytes). Notes: Merged: https://github.com/ruby/ruby/pull/12524
2025-01-07Remove IMEMO_DEBUGPeter Zhu
The code path hasn't compiled for almost a year, since 330830dd1a44b6e497250a14d93efae6fa363f82, so probably nobody uses it. Notes: Merged: https://github.com/ruby/ruby/pull/12519
2025-01-03Remove dead function rb_struct_const_heap_ptrPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/12502
2024-12-28[Bug #20989] Ripper: Pass `compile_error`Nobuyoshi Nakada
For the universal parser, `rb_parser_reg_fragment_check` function is shared between the parser and ripper. However `parser_params` struct is partially different, and `compile_error` function depends on that part indirectly. Notes: Merged: https://github.com/ruby/ruby/pull/12482
2024-12-19[Bug #20969] Pass `assignable` from ripperNobuyoshi Nakada
For the universal parser, `rb_reg_named_capture_assign_iter_impl` function is shared between the parser and ripper. However `parser_params` struct is partially different, and `assignable` function depends on that part indirectly. Notes: Merged: https://github.com/ruby/ruby/pull/12400
2024-12-19Prefix asan_poison_object with rbPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/12385
2024-12-19Export asan_poison_objectPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/12385
2024-12-19Make asan_poison_object poison the whole slotPeter Zhu
This change poisons the whole slot of the object rather than just the flags. This allows ASAN to find any reads/writes into the slot after it has been freed. Notes: Merged: https://github.com/ruby/ruby/pull/12385
2024-12-16Detect ASAN when using older GCC versionsAlan Wu
Newer GCCs have __has_feature and older ones have __SANITIZE_ADDRESS__[1]. Relevant since ASAN with GCC 11 on the popular Ubuntu Jammy failed to build previously. [1]: https://gcc.gnu.org/onlinedocs/gcc-4.8.0/cpp/Common-Predefined-Macros.html
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-13Fix use-after-free in ep in Proc#dup for ifunc procsPeter Zhu
[Bug #20950] ifunc proc has the ep allocated in the cfunc_proc_t which is the data of the TypedData object. If an ifunc proc is duplicated, the ep points to the ep of the source object. If the source object is freed, then the ep of the duplicated object now points to a freed memory region. If we try to use the ep we could crash. For example, the following script crashes: p = { a: 1 }.to_proc 100.times do p = p.dup GC.start p.call rescue ArgumentError end This commit changes ifunc proc to also duplicate the ep when it is duplicated. Notes: Merged: https://github.com/ruby/ruby/pull/12319
2024-12-12Implement rb_bug_without_diePeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/12309
2024-12-12Add `rb_warn_reserved_name_at`Nobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/12315
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-12-04Fix ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS for MSANPeter Zhu
There's no case for when RUBY_MSAN_ENABLED, so the macro ends up doing nothing when it should instead have __attribute__((__no_sanitize__("memory"))). Notes: Merged: https://github.com/ruby/ruby/pull/12219
2024-11-26Optimize instructions when creating an array just to call `include?` (#12123)Randy Stauner
* Add opt_duparray_send insn to skip the allocation on `#include?` If the method isn't going to modify the array we don't need to copy it. This avoids the allocation / array copy for things like `[:a, :b].include?(x)`. This adds a BOP for include? and tracks redefinition for it on Array. Co-authored-by: Andrew Novoselac <[email protected]> * YJIT: Implement opt_duparray_send include_p Co-authored-by: Andrew Novoselac <[email protected]> * Update opt_newarray_send to support simple forms of include?(arg) Similar to opt_duparray_send but for non-static arrays. * YJIT: Implement opt_newarray_send include_p --------- Co-authored-by: Andrew Novoselac <[email protected]> Notes: Merged-By: maximecb <[email protected]>
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-20Introduce `Fiber::Scheduler#blocking_operation_wait`. (#12016)Samuel Williams
Redirect `rb_nogvl` blocking operations to the fiber scheduler if possible to prevent stalling the event loop. [Feature #20876] Notes: Merged-By: ioquatix <[email protected]>
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-11-13YJIT: Specialize `String#[]` (`String#slice`) with fixnum arguments (#12069)Randy Stauner
* YJIT: Specialize `String#[]` (`String#slice`) with fixnum arguments String#[] is in the top few C calls of several YJIT benchmarks: liquid-compile rubocop mail sudoku This speeds up these benchmarks by 1-2%. * YJIT: Try harder to get type info for `String#[]` In the large generated code of the mail gem the context doesn't have the type info. In that case if we peek at the stack and add a guard we can still apply the specialization and it speeds up the mail benchmark by 5%. Co-authored-by: Maxime Chevalier-Boisvert <[email protected]> Co-authored-by: Takashi Kokubun (k0kubun) <[email protected]> --------- Co-authored-by: Maxime Chevalier-Boisvert <[email protected]> Co-authored-by: Takashi Kokubun (k0kubun) <[email protected]> Notes: Merged-By: maximecb <[email protected]>
2024-11-13Mark strings returned by Symbol#to_s as chilled (#12065)Jean byroot Boussier
* Use FL_USER0 for ELTS_SHARED This makes space in RString for two bits for chilled strings. * Mark strings returned by `Symbol#to_s` as chilled [Feature #20350] `STR_CHILLED` now spans on two user flags. If one bit is set it marks a chilled string literal, if it's the other it marks a `Symbol#to_s` chilled string. Since it's not possible, and doesn't make much sense to include debug info when `--debug-frozen-string-literal` is set, we can't include allocation source, but we can safely include the symbol name in the warning message, making it much easier to find the source of the issue. Co-Authored-By: Étienne Barrié <[email protected]> --------- Co-authored-by: Étienne Barrié <[email protected]> Co-authored-by: Jean Boussier <[email protected]>
2024-11-13string.c: Directly create strings with the correct encodingJean Boussier
While profiling msgpack-ruby I noticed a very substantial amout of time spent in `rb_enc_associate_index`, called by `rb_utf8_str_new`. On that benchmark, `rb_utf8_str_new` is 33% of the total runtime, in big part because it cause GC to trigger often, but even then `5.3%` of the total runtime is spent in `rb_enc_associate_index` called by `rb_utf8_str_new`. After closer inspection, it appears that it's performing a lot of safety check we can assert we don't need, and other extra useless operations, because strings are first created and filled as ASCII-8BIT and then later reassociated to the desired encoding. By directly allocating the string with the right encoding, it allow to skip a lot of duplicated and useless operations. After this change, the time spent in `rb_utf8_str_new` is down to `28.4%` of total runtime, and most of that is GC. Notes: Merged: https://github.com/ruby/ruby/pull/12076
2024-11-09Add integer overflow check macros for add/sub as well as mulNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/12034
2024-11-08introduce `rb_ec_check_ints()`Koichi Sasada
to avoid TLS issue with N:M threads. Notes: Merged: https://github.com/ruby/ruby/pull/11142
2024-11-08`interrupt_exec`Koichi Sasada
introduce - rb_threadptr_interrupt_exec - rb_ractor_interrupt_exec to intercept the thread/ractor execution. Notes: Merged: https://github.com/ruby/ruby/pull/11142
2024-10-24Fix shared GC with -DRUBY_DEBUGMatt Valentine-House
RUBY_DEBUG enables ractor assertions, which sets up some space at the end of each RVALUE to store the associated ractor ID. We need to make sure the function that does this is visible to shared GC libraries. Notes: Merged: https://github.com/ruby/ruby/pull/11945
2024-10-21Show where mutated chilled strings were allocatedÉtienne Barrié
[Feature #20205] The warning now suggests running with --debug-frozen-string-literal: ``` test.rb:3: warning: literal string will be frozen in the future (run with --debug-frozen-string-literal for more information) ``` When using --debug-frozen-string-literal, the location where the string was created is shown: ``` test.rb:3: warning: literal string will be frozen in the future test.rb:1: info: the string was created here ``` When resurrecting strings and debug mode is not enabled, the overhead is a simple FL_TEST_RAW. When mutating chilled strings and deprecation warnings are not enabled, the overhead is a simple warning category enabled check. Co-authored-by: Jean Boussier <[email protected]> Co-authored-by: Nobuyoshi Nakada <[email protected]> Co-authored-by: Jean Boussier <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/11893