summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2021-08-29 16:47:26 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2021-08-29 17:18:58 +0900
commita615885f1e87f4bfbc5398b060fd3a64d5de8c4a (patch)
treec0045c949a33c1e661744e8d8e9f70deb1d36629 /hash.c
parent265a725830a487b846bc32f70346f6438c95a7e9 (diff)
downloadruby-a615885f1e87f4bfbc5398b060fd3a64d5de8c4a.tar.gz
Free previously used tables [Bug #18134]
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c22
1 files changed, 7 insertions, 15 deletions
diff --git a/hash.c b/hash.c
index 6675b81e65..314ac18c5c 100644
--- a/hash.c
+++ b/hash.c
@@ -2951,25 +2951,17 @@ rb_hash_replace(VALUE hash, VALUE hash2)
COPY_DEFAULT(hash, hash2);
if (RHASH_AR_TABLE_P(hash)) {
- if (RHASH_AR_TABLE_P(hash2)) {
- ar_clear(hash);
- }
- else {
- ar_free_and_clear_table(hash);
- RHASH_ST_TABLE_SET(hash, st_init_table_with_size(RHASH_TYPE(hash2), RHASH_SIZE(hash2)));
- }
+ ar_free_and_clear_table(hash);
}
else {
- if (RHASH_AR_TABLE_P(hash2)) {
- st_free_table(RHASH_ST_TABLE(hash));
- RHASH_ST_CLEAR(hash);
- }
- else {
- st_clear(RHASH_ST_TABLE(hash));
- RHASH_TBL_RAW(hash)->type = RHASH_ST_TABLE(hash2)->type;
- }
+ st_free_table(RHASH_ST_TABLE(hash));
+ RHASH_ST_CLEAR(hash);
}
hash_copy(hash, hash2);
+ if (RHASH_EMPTY_P(hash2) && RHASH_ST_TABLE_P(hash2)) {
+ /* ident hash */
+ RHASH_ST_TABLE_SET(hash, st_init_table_with_size(RHASH_TYPE(hash2), 0));
+ }
rb_gc_writebarrier_remember(hash);