diff options
author | Peter Zhu <[email protected]> | 2023-06-29 09:21:11 -0400 |
---|---|---|
committer | Peter Zhu <[email protected]> | 2023-06-29 11:16:50 -0400 |
commit | f0d08d11dcd404f3146c0d71d6ff743bbc6e7193 (patch) | |
tree | 82e6bb0fff741e124915c7a2f6aabe54a484ee71 /hash.c | |
parent | df2b3a29987e9353596af76ed77f35d7366d654e (diff) |
Fix memory leak when copying ST tables
st_copy allocates a st_table, which is not needed for hashes since it is
allocated by VWA and embedded, so this causes a memory leak.
The following script demonstrates the issue:
```ruby
20.times do
100_000.times do
{a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9}
end
puts `ps -o rss= -p #{$$}`
end
```
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/8000
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 7 |
1 files changed, 5 insertions, 2 deletions
@@ -1482,7 +1482,9 @@ hash_copy(VALUE ret, VALUE hash) else { HASH_ASSERT(sizeof(st_table) <= sizeof(ar_table)); - RHASH_ST_TABLE_SET(ret, st_copy(RHASH_ST_TABLE(hash))); + RHASH_SET_ST_FLAG(ret); + st_replace(RHASH_ST_TABLE(ret), RHASH_ST_TABLE(hash)); + rb_gc_writebarrier_remember(ret); } return ret; @@ -1776,7 +1778,8 @@ rb_hash_s_create(int argc, VALUE *argv, VALUE klass) } else { hash = hash_alloc(klass); - hash_copy(hash, tmp); + if (!RHASH_EMPTY_P(tmp)) + hash_copy(hash, tmp); return hash; } } |