<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/test/ruby/test_hash.rb, branch v4.0.4</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>Remove `opt_aref_with` and `opt_aset_with`</title>
<updated>2025-08-26T20:02:17+00:00</updated>
<author>
<name>Aaron Patterson</name>
<email>tenderlove@ruby-lang.org</email>
</author>
<published>2025-08-25T21:31:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=fb6e3a80009a744a4e0b75660f1ce6da65e20e6c'/>
<id>fb6e3a80009a744a4e0b75660f1ce6da65e20e6c</id>
<content type='text'>
When these instructions were introduced it was common to read from a
hash with mutable string literals.  However, these days, I think these
instructions are fairly rare.

I tested this with the lobsters benchmark, and saw no difference in
speed.  In order to be sure, I tracked down every use of this
instruction in the lobsters benchmark, and there were only 4 places
where it was used.

Additionally, this patch fixes a case where "chilled strings" should
emit a warning but they don't.

```ruby
class Foo
  def self.[](x)= x.gsub!(/hello/, "hi")
end

Foo["hello world"]
```

Removing these instructions shows this warning:

```
&gt; ./miniruby -vw test.rb
ruby 3.5.0dev (2025-08-25T21:36:50Z rm-opt_aref_with dca08e286c) +PRISM [arm64-darwin24]
test.rb:2: warning: literal string will be frozen in the future (run with --debug-frozen-string-literal for more information)
```

[Feature #21553]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When these instructions were introduced it was common to read from a
hash with mutable string literals.  However, these days, I think these
instructions are fairly rare.

I tested this with the lobsters benchmark, and saw no difference in
speed.  In order to be sure, I tracked down every use of this
instruction in the lobsters benchmark, and there were only 4 places
where it was used.

Additionally, this patch fixes a case where "chilled strings" should
emit a warning but they don't.

```ruby
class Foo
  def self.[](x)= x.gsub!(/hello/, "hi")
end

Foo["hello world"]
```

Removing these instructions shows this warning:

```
&gt; ./miniruby -vw test.rb
ruby 3.5.0dev (2025-08-25T21:36:50Z rm-opt_aref_with dca08e286c) +PRISM [arm64-darwin24]
test.rb:2: warning: literal string will be frozen in the future (run with --debug-frozen-string-literal for more information)
```

[Feature #21553]
</pre>
</div>
</content>
</entry>
<entry>
<title>Change TestHash#test_inspect to use EnvUtil.with_default_external</title>
<updated>2025-08-19T13:42:52+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2025-08-18T15:09:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=6f1bb06cdc579a3f33afadb18cfad96a4f9ac303'/>
<id>6f1bb06cdc579a3f33afadb18cfad96a4f9ac303</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Change test to avoid stack overflow with MN threads</title>
<updated>2025-05-23T19:28:16+00:00</updated>
<author>
<name>Étienne Barrié</name>
<email>etienne.barrie@gmail.com</email>
</author>
<published>2025-05-23T13:58:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=2a951f62e117549a3e442925886859264fe809e6'/>
<id>2a951f62e117549a3e442925886859264fe809e6</id>
<content type='text'>
When using MN threads (such as running the test in a ractor), this test
failed because it was raising a SystemStackError: stack level too deep.

This is because the machine stack is smaller under MN threads than on
the native main thread.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When using MN threads (such as running the test in a ractor), this test
failed because it was raising a SystemStackError: stack level too deep.

This is because the machine stack is smaller under MN threads than on
the native main thread.
</pre>
</div>
</content>
</entry>
<entry>
<title>[Bug #21357] Fix crash in Hash#merge with block</title>
<updated>2025-05-22T03:25:55+00:00</updated>
<author>
<name>Daniel Colson</name>
<email>danieljamescolson@gmail.com</email>
</author>
<published>2025-05-22T02:00:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=056497319658cbefe22351c6ec5c9fa6e4df72bd'/>
<id>056497319658cbefe22351c6ec5c9fa6e4df72bd</id>
<content type='text'>
Prior to https://github.com/ruby/ruby/commit/49b306ecb9e2e9e06e0b1590bacc5f4b38169c3c
the `optional_arg` passed from `rb_hash_update_block_i` to `tbl_update`
was a hash value (i.e. a VALUE). After that commit it changed to an
`update_call_args`.

If the block sets or changes the value, `tbl_update_modify` will set the
`arg.value` back to an actual value and we won't crash. But in the case
where the block returns the original value we end up calling
`RB_OBJ_WRITTEN` with the `update_call_args` which is not expected and
may crash.

`arg.value` appears to only be used to pass to `RB_OBJ_WRITTEN` (others
who need the `update_call_args` get it from `arg.arg`), so I don't think
it needs to be set to anything upfront. And `tbl_update_modify` will set
the `arg.value` in the cases we need the write barrier.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Prior to https://github.com/ruby/ruby/commit/49b306ecb9e2e9e06e0b1590bacc5f4b38169c3c
the `optional_arg` passed from `rb_hash_update_block_i` to `tbl_update`
was a hash value (i.e. a VALUE). After that commit it changed to an
`update_call_args`.

If the block sets or changes the value, `tbl_update_modify` will set the
`arg.value` back to an actual value and we won't crash. But in the case
where the block returns the original value we end up calling
`RB_OBJ_WRITTEN` with the `update_call_args` which is not expected and
may crash.

`arg.value` appears to only be used to pass to `RB_OBJ_WRITTEN` (others
who need the `update_call_args` get it from `arg.arg`), so I don't think
it needs to be set to anything upfront. And `tbl_update_modify` will set
the `arg.value` in the cases we need the write barrier.
</pre>
</div>
</content>
</entry>
<entry>
<title>[Bug #21333] Prohibit hash modification inside Hash#update block</title>
<updated>2025-05-15T06:39:15+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2025-05-14T18:13:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=49b306ecb9e2e9e06e0b1590bacc5f4b38169c3c'/>
<id>49b306ecb9e2e9e06e0b1590bacc5f4b38169c3c</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>[Bug #21331] Prohibit hash modification during stlike loop</title>
<updated>2025-05-14T01:37:59+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2025-05-14T01:37:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=7793b59c8d2a13c124fe276e11723db23facce04'/>
<id>7793b59c8d2a13c124fe276e11723db23facce04</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "[Bug #21331] Prohibit modification during stlike loop"</title>
<updated>2025-05-14T01:23:16+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2025-05-14T01:23:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=b66c5c3b1b31581960bcb69d49b618d69ae2a87f'/>
<id>b66c5c3b1b31581960bcb69d49b618d69ae2a87f</id>
<content type='text'>
This reverts commit bb180b87b43c45e17ff49735a26d7a188d5c8396, which
caused "malloc during GC" error on wasm.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit bb180b87b43c45e17ff49735a26d7a188d5c8396, which
caused "malloc during GC" error on wasm.
</pre>
</div>
</content>
</entry>
<entry>
<title>[Bug #21331] Prohibit modification during stlike loop</title>
<updated>2025-05-13T14:16:58+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2025-05-13T13:34:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=bb180b87b43c45e17ff49735a26d7a188d5c8396'/>
<id>bb180b87b43c45e17ff49735a26d7a188d5c8396</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix flaky test_AREF_fstring_key</title>
<updated>2025-03-12T17:27:03+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2025-03-12T15:24:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=a8d63ecdb82c33744c0d1fcfa362b0c7247e83c9'/>
<id>a8d63ecdb82c33744c0d1fcfa362b0c7247e83c9</id>
<content type='text'>
The code between the two ObjectSpace.count_objects could trigger a GC,
which could free string objects causing this test to fail.

We can see this failure on CI http://ci.rvm.jp/results/trunk-random2@ruby-sp2-noble-docker/5651016

    TestHashOnly#test_AREF_fstring_key [test/ruby/test_hash.rb:1991]:
    &lt;197483&gt; expected but was
    &lt;129689&gt;.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The code between the two ObjectSpace.count_objects could trigger a GC,
which could free string objects causing this test to fail.

We can see this failure on CI http://ci.rvm.jp/results/trunk-random2@ruby-sp2-noble-docker/5651016

    TestHashOnly#test_AREF_fstring_key [test/ruby/test_hash.rb:1991]:
    &lt;197483&gt; expected but was
    &lt;129689&gt;.
</pre>
</div>
</content>
</entry>
<entry>
<title>Replace tombstone when converting AR to ST hash</title>
<updated>2025-03-05T22:05:24+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2025-03-04T20:54:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=443e2ec27db89c896bd62994f6e04d8d6d48cddb'/>
<id>443e2ec27db89c896bd62994f6e04d8d6d48cddb</id>
<content type='text'>
[Bug #21170]

st_table reserves -1 as a special hash value to indicate that an entry
has been deleted. So that that's a valid value to be returned from the
hash function, do_hash replaces -1 with 0 so that it is not mistaken for
the sentinel.

Previously, when upgrading an AR table to an ST table,
rb_st_add_direct_with_hash was used which did not perform the same
conversion, this could lead to a hash in a broken state where one if its
entries which was supposed to exist being marked as a tombstone.

The hash could then become further corrupted when the ST table required
resizing as the falsely tombstoned entry would be skipped but it would
be counted in num entries, leading to an uninitialized entry at index
15.

In most cases this will be really rare, unless using a very poorly
implemented custom hash function.

This also adds two debug assertions, one that st_add_direct_with_hash
does not receive the reserved hash value, and a second in
rebuild_table_with, which ensures that after we rebuild/compact a table
it contains the expected number of elements.

Co-authored-by: Alan Wu &lt;alanwu@ruby-lang.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[Bug #21170]

st_table reserves -1 as a special hash value to indicate that an entry
has been deleted. So that that's a valid value to be returned from the
hash function, do_hash replaces -1 with 0 so that it is not mistaken for
the sentinel.

Previously, when upgrading an AR table to an ST table,
rb_st_add_direct_with_hash was used which did not perform the same
conversion, this could lead to a hash in a broken state where one if its
entries which was supposed to exist being marked as a tombstone.

The hash could then become further corrupted when the ST table required
resizing as the falsely tombstoned entry would be skipped but it would
be counted in num entries, leading to an uninitialized entry at index
15.

In most cases this will be really rare, unless using a very poorly
implemented custom hash function.

This also adds two debug assertions, one that st_add_direct_with_hash
does not receive the reserved hash value, and a second in
rebuild_table_with, which ensures that after we rebuild/compact a table
it contains the expected number of elements.

Co-authored-by: Alan Wu &lt;alanwu@ruby-lang.org&gt;
</pre>
</div>
</content>
</entry>
</feed>
