summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-01-02Prefer dedicated assertionsNobuyoshi Nakada
2026-01-01[ruby/mmtk] Format imports to be each on a new linePeter Zhu
https://github.com/ruby/mmtk/commit/42adba630e
2026-01-01[ruby/prism] Fix spacing in the generated #each_child_nodeBenoit Daloze
https://github.com/ruby/prism/commit/91f60cb736
2026-01-01Thread::Queue use a ring bufferJean Boussier
Thread::Queue spends a significant amount of time in array functions, checking for invariants we know aren't a problem, and whether the backing array need to reordered. By using a ring buffer we can remove a lot of overhead (~23% faster). ``` $ hyperfine './miniruby --yjit /tmp/q.rb' './miniruby-qrb --yjit /tmp/q.rb' Benchmark 1: ./miniruby --yjit /tmp/q.rb Time (mean ± σ): 1.050 s ± 0.191 s [User: 0.988 s, System: 0.004 s] Range (min … max): 0.984 s … 1.595 s 10 runs Benchmark 2: ./miniruby-qrb --yjit /tmp/q.rb Time (mean ± σ): 844.2 ms ± 3.1 ms [User: 840.4 ms, System: 2.8 ms] Range (min … max): 838.6 ms … 848.9 ms 10 runs Summary ./miniruby-qrb --yjit /tmp/q.rb ran 1.24 ± 0.23 times faster than ./miniruby --yjit /tmp/q.rb ``` ``` q = Queue.new([1, 2, 3, 4, 5, 6, 7, 8]) i = 2_000_000 while i > 0 i -= 1 q.push(q.pop) q.push(q.pop) q.push(q.pop) q.push(q.pop) q.push(q.pop) q.push(q.pop) q.push(q.pop) q.push(q.pop) q.push(q.pop) q.push(q.pop) end ```
2025-12-31Use STR_SET_SHARED in str_duplicate_setup_heapPeter Zhu
str_duplicate_setup_heap is missing a call to rb_gc_register_pinning_obj that STR_SET_SHARED correctly calls.
2026-01-01Extract `RBIMPL_TYPEDDATA_PRECONDITION`Nobuyoshi Nakada
2025-12-31Register imemo_ment as a pinning objectPeter Zhu
It sometimes pins itself when it is in the overloaded_cme table.
2025-12-31Use `is_obj_encoding` instead of `is_data_encoding`Nobuyoshi Nakada
The argument to `is_data_encoding` is assumed to be `T_DATA`.
2025-12-31[ruby/mmtk] Split ProcessObjFreeCandidates to parallel and non-parallelPeter Zhu
This makes it easier to visualize in profilers which one is non-parallel. https://github.com/ruby/mmtk/commit/ba68b2ef3b
2025-12-31[ruby/mmtk] Process obj_free candidates in parallelPeter Zhu
This commit allows objects that are safe to be freed in parallel to do so. A decrease in object freeing time can be seen in profiles. The benchmarks don't show much difference. Before: -------------- -------------------- ---------- --------- bench sequential free (ms) stddev (%) RSS (MiB) activerecord 242.3 7.4 84.3 chunky-png 439.1 0.6 75.6 erubi-rails 1221.2 4.2 132.7 hexapdf 1544.8 1.8 429.1 liquid-c 42.7 7.4 48.5 liquid-compile 41.4 8.3 52.2 liquid-render 100.6 3.0 56.8 mail 108.9 2.1 65.1 psych-load 1536.9 0.6 43.4 railsbench 1633.5 2.6 146.2 rubocop 126.5 15.8 142.1 ruby-lsp 129.6 9.7 112.2 sequel 47.9 6.5 44.6 shipit 1152.0 2.7 315.2 -------------- -------------------- ---------- --------- After: -------------- ------------------ ---------- --------- bench parallel free (ms) stddev (%) RSS (MiB) activerecord 235.1 5.5 87.4 chunky-png 440.8 0.8 68.1 erubi-rails 1105.3 0.8 128.0 hexapdf 1578.3 4.1 405.1 liquid-c 42.6 7.1 48.4 liquid-compile 41.5 8.1 52.1 liquid-render 101.2 2.8 53.3 mail 109.7 2.7 64.8 psych-load 1567.7 1.1 44.4 railsbench 1644.9 1.9 150.9 rubocop 125.6 15.4 148.5 ruby-lsp 127.9 5.8 104.6 sequel 48.2 6.1 44.1 shipit 1215.3 4.7 320.5 -------------- ------------------ ---------- --------- https://github.com/ruby/mmtk/commit/4f0b5fd2eb
2025-12-31[ruby/json] Fix non-portable codeNobuyoshi Nakada
A plain `char` may be `signed` or `unsigned` depending on the implementation. Also, bitwise ORing of `signed` values ​​is not guaranteed to be `signed`. To ensure portability, should logical-OR each comparison, but casting to `signed char` is usually sufficient. https://github.com/ruby/json/commit/8ad744c532
2025-12-31[ruby/json] Simplify unescape_unicodeScott Myron
https://github.com/ruby/json/commit/976ba36629 Co-Authored-By: Jean Boussier <jean.boussier@gmail.com>
2025-12-31[ruby/json] Keep track of the the number of additional backslashes to avoid ↵Scott Myron
an extra memchr searching the remaining characters when no more backslashes exist. https://github.com/ruby/json/commit/d21d9362fa
2025-12-31[DOC] Move typed-data related macrosNobuyoshi Nakada
The flags for `rb_data_type_t::flags` are public constants for defining `rb_data_type_t`. The embedded data flag and mask are internal implementation detail.
2025-12-31Make `RTYPEDDATA_EMBEDDABLE_P` internal-use onlyNobuyoshi Nakada
It should not be exposed because it is so implementation specific that it is only used in gc.c even within the entire Ruby source tree.
2025-12-31Introduce typed-data embeddable predicate macrosNobuyoshi Nakada
The combination of `&` and `&&` is confusing.
2025-12-30[ruby/mmtk] Use MMTK_HEAP_COUNT for SIZE_POOL_COUNTPeter Zhu
https://github.com/ruby/mmtk/commit/290a2aec4e
2025-12-31Skip the hang-up test on WindowsNobuyoshi Nakada
2025-12-31Run also test-tool on mingwNobuyoshi Nakada
2025-12-30Add RVALUE_OLD_AGE to GC::INTERNAL_CONSTANTS for MMTkPeter Zhu
2025-12-30Fix generational GC for weak referencesPeter Zhu
Fixes issue pointed out in https://bugs.ruby-lang.org/issues/21084#note-7. The following script crashes: wmap = ObjectSpace::WeakMap.new GC.disable # only manual GCs GC.start GC.start retain = [] 50.times do k = Object.new wmap[k] = true retain << k end GC.start # wmap promoted, other objects still young retain.clear GC.start(full_mark: false) wmap.keys.each(&:itself) # call method on keys to cause crash
2025-12-30Exclude rbs tests which need updates for ↵Benoit Daloze
{Method,UnboundMethod,Proc}#source_location * See https://github.com/ruby/ruby/pull/15580
2025-12-30Update version guards in ruby/specBenoit Daloze
2025-12-30[Bug #21784] Fix the Proc#source_location start_column for stabby lambdasBenoit Daloze
* Consistent with plain `blocks` and `for` blocks and methods where the source_location covers their entire definition. * Matches the documentation which mentions "where the definition starts/ends". * Partially reverts d357d50f0a74409446f4cccec78593373f5adf2f which was a workaround to be compatible with parse.y.
2025-12-30[Bug #21783] Fix documentation of {Method,UnboundMethod,Proc}#source_locationBenoit Daloze
2025-12-30Reapply "[Feature #6012] Extend `source_location` for end positionBenoit Daloze
* This reverts commit 065c48cdf11a1c4cece84db44ed8624d294f8fd5. * This functionality is very valuable and has already taken 14 years to agree on the API. * Let's just document it's byte columns (in the next commit). * See https://bugs.ruby-lang.org/issues/21783#note-9
2025-12-30[Bug #21814] Fix negative bignum moduloNobuyoshi Nakada
If modulo is zero, do not apply bias even if the divisor is zero. `BIGNUM_POSITIVE_P` is true even on bignum zero.
2025-12-30Box: skip checking the current box is the root boxSatoshi Tagomori
Because checking the current box is not a cheap process.
2025-12-30Add 4.0 to the spec_guards workflowNobuyoshi Nakada
2025-12-30Update ruby/setup-ruby action to v1.276.0Nobuyoshi Nakada
2025-12-30Box: allocate classes as boxable when it happens in the root boxSatoshi Tagomori
Without this change, classes (including iclass) are allocated as un-boxable classes after initializing user boxes (after starting script evaluation). Under this situation, iclasses are created as un-boxabled class when core modules are included by a class in the root box, then it causes problems because it's in the root box but it can't have multiple classexts. This change makes it possible to allocate boxable classes even after initializing user boxes. Classes create in the root box will be boxable, and those can have 2 or more classexts.
2025-12-29[ruby/prism] Optimize ruby visitorEarlopain
`compact_child_nodes` allocates an array. We can skip that step by simply yielding the nodes. Benchmark for visiting the rails codebase: ```rb require "prism" require "benchmark/ips" files = Dir.glob("../rails/**/*.rb") results = files.map { Prism.parse_file(it) } visitor = Prism::Visitor.new Benchmark.ips do |x| x.config(warmup: 3, time: 10) x.report do results.each do visitor.visit(it.value) end end end RubyVM::YJIT.enable Benchmark.ips do |x| x.config(warmup: 3, time: 10) x.report do results.each do visitor.visit(it.value) end end end ``` Before: ``` ruby 3.4.8 (2025-12-17 revision https://github.com/ruby/prism/commit/995b59f666) +PRISM [x86_64-linux] Warming up -------------------------------------- 1.000 i/100ms Calculating ------------------------------------- 2.691 (± 0.0%) i/s (371.55 ms/i) - 27.000 in 10.089422s ruby 3.4.8 (2025-12-17 revision https://github.com/ruby/prism/commit/995b59f666) +YJIT +PRISM [x86_64-linux] Warming up -------------------------------------- 1.000 i/100ms Calculating ------------------------------------- 7.278 (±13.7%) i/s (137.39 ms/i) - 70.000 in 10.071568s ``` After: ``` ruby 3.4.8 (2025-12-17 revision https://github.com/ruby/prism/commit/995b59f666) +PRISM [x86_64-linux] Warming up -------------------------------------- 1.000 i/100ms Calculating ------------------------------------- 3.429 (± 0.0%) i/s (291.65 ms/i) - 35.000 in 10.208580s ruby 3.4.8 (2025-12-17 revision https://github.com/ruby/prism/commit/995b59f666) +YJIT +PRISM [x86_64-linux] Warming up -------------------------------------- 1.000 i/100ms Calculating ------------------------------------- 16.815 (± 0.0%) i/s (59.47 ms/i) - 169.000 in 10.054668s ``` ~21% faster on the interpreter, ~56% with YJIT https://github.com/ruby/prism/commit/bf631750cf
2025-12-29[ruby/prism] Report missing end errors at opening tokenThomas Marshall
This commit adds an `expect1_opening` function that expects a token and attaches the error to the opening token location rather than the current position. This is useful for errors about missing closing tokens, where we want to point to the line with the opening token rather than the end of the file. For example: ```ruby def foo def bar def baz ^ expected an `end` to close the `def` statement ^ expected an `end` to close the `def` statement ^ expected an `end` to close the `def` statement ``` This would previously produce three identical errors at the end of the file. After this commit, they would be reported at the opening token location: ```ruby def foo ^~~ expected an `end` to close the `def` statement def bar ^~~ expected an `end` to close the `def` statement def baz ^~~ expected an `end` to close the `def` statement ``` I considered using the end of the line where the opening token is located, but in some cases that would be less useful than the opening token location itself. For example: ```ruby def foo def bar def baz ``` Here the end of the line where the opening token is located would be the same for each of the unclosed `def` nodes. https://github.com/ruby/prism/commit/2d7829f060
2025-12-29[ruby/prism] Add unterminated construct testsThomas Marshall
https://github.com/ruby/prism/commit/166764f794
2025-12-29Implement moving Immix in MMTkPeter Zhu
This commit implements moving Immix in MMTk, which allows objects to move in the GC. The performance of this implementation is not yet amazing. It is very similar to non-moving Immix in many of them and slightly slower in others. The benchmark results is shown below. -------------- ----------------- ---------- --------- bench Moving Immix (ms) stddev (%) RSS (MiB) activerecord 241.9 0.5 86.6 chunky-png 447.8 0.8 74.9 erubi-rails 1183.9 0.8 136.1 hexapdf 1607.9 2.6 402.3 liquid-c 45.4 6.7 44.9 liquid-compile 44.1 9.3 53.0 liquid-render 105.4 4.5 55.9 lobsters 650.1 9.7 418.4 mail 115.4 2.1 64.4 psych-load 1656.8 0.8 43.6 railsbench 1653.5 1.3 149.8 rubocop 127.0 15.6 142.1 ruby-lsp 130.7 10.5 99.4 sequel 52.8 7.2 45.6 shipit 1187.0 3.9 311.0 -------------- ----------------- ---------- --------- -------------- --------------------- ---------- --------- bench Non-moving Immix (ms) stddev (%) RSS (MiB) activerecord 218.9 2.7 86.1 chunky-png 464.6 0.8 66.7 erubi-rails 1119.0 4.3 132.7 hexapdf 1539.8 1.8 425.2 liquid-c 40.6 6.9 45.2 liquid-compile 40.6 8.1 52.9 liquid-render 99.3 2.3 48.3 mail 107.4 5.3 65.4 psych-load 1535.6 1.0 39.5 railsbench 1565.6 1.1 149.6 rubocop 122.5 14.3 146.7 ruby-lsp 128.4 10.7 106.4 sequel 44.1 4.0 45.7 shipit 1154.5 2.7 358.5 -------------- --------------------- ---------- ---------
2025-12-29Add rb_gc_move_obj_during_markingPeter Zhu
2025-12-29Add rb_gc_register_pinning_objPeter Zhu
2025-12-29Move MEMO_NEW to imemo.c and rename to rb_imemo_memo_newPeter Zhu
2025-12-29Prefer `ALLOCV` over `ALLOCA` for unknown sizeNobuyoshi Nakada
`ALLOCA` with too large size may result in stack overflow. Incidentally, this suppresses the GCC false maybe-uninitialized warning in `product_each`. Also shrink `struct product_state` when `sizeof(int) < sizeof(VALUE)`.
2025-12-29[DOC] State that `rb_unexpected_type` is privateNobuyoshi Nakada
2025-12-29Return `NULL` in a `void *` functionNobuyoshi Nakada
2025-12-29Make `rb_check_typeddata` and `rbimpl_check_typeddata` identicalNobuyoshi Nakada
2025-12-29Declare `rb_data_typed_t` parameters and return values as nonullNobuyoshi Nakada
2025-12-29fix underflowLuke Jahnke
2025-12-29Remove deprecated support for to_set taking argumentsJeremy Evans
2025-12-29rtypeddata.h: Add missing `RBIMPL_CAST`Nobuyoshi Nakada
In public headers, casts should be enclosed in `RBIMPL_CAST` for compilation in C++.
2025-12-28Fix maybe uninitialized warnings in random.cPeter Zhu
Fixes the following compiler warnings: random.c: In function `random_init`: random.c:416:38: warning: `rng` may be used uninitialized in this function [-Wmaybe-uninitialized] 416 | unsigned int major = rng->version.major; | ~~~~~~~~~~~~^~~~~~ random.c: In function `random_bytes`: random.c:1284:8: warning: `rng` may be used uninitialized in this function [-Wmaybe-uninitialized] 1284 | rng->get_bytes(rnd, ptr, n); | ~~~^~~~~~~~~~~ random.c:1299:34: note: `rng` was declared here 1299 | const rb_random_interface_t *rng; | ^~~ random.c: In function `rand_random_number`: random.c:1606:12: warning: `rng` may be used uninitialized in this function [-Wmaybe-uninitialized] 1606 | return rand_range(obj, rng, rnd, vmax); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ random.c:1624:34: note: `rng` was declared here 1624 | const rb_random_interface_t *rng; | ^~~ random.c: In function `random_rand`: random.c:1120:15: warning: `rng` may be used uninitialized in this function [-Wmaybe-uninitialized] 1120 | return rng->get_int32(rnd); | ~~~^~~~~~~~~~~ random.c:1573:34: note: `rng` was declared here 1573 | const rb_random_interface_t *rng; | ^~~
2025-12-28[DOC] Japanese for multi-byte charactersBurdette Lamar
2025-12-29Extract `rb_random_interface_t` alongside `rb_random_t` as wellNobuyoshi Nakada
2025-12-29Ensure `T_DATA` before `RTYPEDDATA_P`Nobuyoshi Nakada
For the precondition of `RTYPEDDATA_P` that the argument must be a Ruby object of `::RUBY_T_DATA`.