Free previously used tables [Bug #18134]

This commit is contained in:
Nobuyoshi Nakada 2021-08-29 16:47:26 +09:00
Родитель 265a725830
Коммит a615885f1e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 7CD2805BFA3770C6
2 изменённых файлов: 16 добавлений и 15 удалений

22
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);

Просмотреть файл

@ -1278,6 +1278,15 @@ class TestHash < Test::Unit::TestCase
assert_raise(FrozenError) { h2.replace(42) }
end
def test_replace_memory_leak
assert_no_memory_leak([], "#{<<-"begin;"}", "#{<<-'end;'}")
h = ("aa".."zz").each_with_index.to_h
10_000.times {h.dup}
begin;
500_000.times {h.dup.replace(h)}
end;
end
def test_size2
assert_equal(0, @cls[].size)
end