Skip to content

Conversation

@pull
Copy link

@pull pull bot commented Dec 29, 2025

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

nobu and others added 8 commits December 29, 2025 20:26
`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)`.
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
    --------------  ---------------------  ----------  ---------
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.

ruby/prism@2d7829f060
`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 ruby/prism@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 ruby/prism@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 ruby/prism@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 ruby/prism@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

ruby/prism@bf631750cf
@pull pull bot locked and limited conversation to collaborators Dec 29, 2025
@pull pull bot added the ⤵️ pull label Dec 29, 2025
@pull pull bot merged commit 65634d8 into turkdevops:master Dec 29, 2025
1 of 3 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants