[ruby-core:112906] [Ruby master Bug#19531] ObjectSpace::WeakMap: replaced values still clear the key they were assigned to

Issue #19531 has been reported by byroot (Jean Boussier). ---------------------------------------- Bug #19531: ObjectSpace::WeakMap: replaced values still clear the key they were assigned to https://bugs.ruby-lang.org/issues/19531 * Author: byroot (Jean Boussier) * Status: Open * Priority: Normal * Backport: 2.7: WONTFIX, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: REQUIRED ---------------------------------------- ### Reproduction script ```ruby wmap = ObjectSpace::WeakMap.new a = "A" b = "B" wmap[1] = a wmap[1] = b # the table entry with 1 is still in the list of entries to clear when `a` is GCed a = nil GC.start p wmap[1] # Should be `"B"`, but is `nil` ``` ### Explanation What happens is that when we set `wmap[1] = "A"`, WeakMap internally keeps a list of keys to clear when `"A"` is GCed, e.g. pseudo code: ```ruby class WeakMap def []=(key, value) @hash[key] = value @reverse[value] << key end end ``` But it doesn't clear previously kept mapping when a key is overwritten. I'll work on a fix. ### References https://github.com/protocolbuffers/protobuf/pull/12216 -- https://bugs.ruby-lang.org/

Issue #19531 has been updated by byroot (Jean Boussier). Patch: https://github.com/ruby/ruby/pull/7540 ---------------------------------------- Bug #19531: ObjectSpace::WeakMap: replaced values still clear the key they were assigned to https://bugs.ruby-lang.org/issues/19531#change-102428 * Author: byroot (Jean Boussier) * Status: Open * Priority: Normal * Backport: 2.7: WONTFIX, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: REQUIRED ---------------------------------------- ### Reproduction script ```ruby wmap = ObjectSpace::WeakMap.new a = "A" b = "B" wmap[1] = a wmap[1] = b # the table entry with 1 is still in the list of entries to clear when `a` is GCed a = nil GC.start p wmap[1] # Should be `"B"`, but is `nil` ``` ### Explanation What happens is that when we set `wmap[1] = "A"`, WeakMap internally keeps a list of keys to clear when `"A"` is GCed, e.g. pseudo code: ```ruby class WeakMap def []=(key, value) @hash[key] = value @reverse[value] << key end end ``` But it doesn't clear previously kept mapping when a key is overwritten. I'll work on a fix. ### References https://github.com/protocolbuffers/protobuf/pull/12216 -- https://bugs.ruby-lang.org/

Issue #19531 has been updated by nagachika (Tomoyuki Chikanaga). Backport changed from 2.7: WONTFIX, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: REQUIRED to 2.7: WONTFIX, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: DONE ruby_3_2 46b62f44ce30bf234a76114c8249081e47ce3da4 merged revision(s) 3592b24cdc07ed89eecb39161f21fe721a89a5de. ---------------------------------------- Bug #19531: ObjectSpace::WeakMap: replaced values still clear the key they were assigned to https://bugs.ruby-lang.org/issues/19531#change-103942 * Author: byroot (Jean Boussier) * Status: Closed * Priority: Normal * Backport: 2.7: WONTFIX, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: DONE ---------------------------------------- ### Reproduction script ```ruby wmap = ObjectSpace::WeakMap.new a = "A" b = "B" wmap[1] = a wmap[1] = b # the table entry with 1 is still in the list of entries to clear when `a` is GCed a = nil GC.start p wmap[1] # Should be `"B"`, but is `nil` ``` ### Explanation What happens is that when we set `wmap[1] = "A"`, WeakMap internally keeps a list of keys to clear when `"A"` is GCed, e.g. pseudo code: ```ruby class WeakMap def []=(key, value) @hash[key] = value @reverse[value] << key end end ``` But it doesn't clear previously kept mapping when a key is overwritten. I'll work on a fix. ### References https://github.com/protocolbuffers/protobuf/pull/12216 -- https://bugs.ruby-lang.org/
participants (2)
-
byroot (Jean Boussier)
-
nagachika (Tomoyuki Chikanaga)