utilities/hashtable supports block and free-list allocation of entries. There is a free-list of available entries. When that list is empty, a new entry is obtained from a lazily allocated block of entries. The blocks are recorded in the _entry_blocks array.
_entry_blocks (GrowableArray<...>)
- declared in BasicHashtable
- initialized in BasicHashtable constructors
- entries freed in ~BasicHashtable
- appended to in BasicHashtable::new_entry
It also tries to support direct transfer of entries from one hashtable to another as a mechanism for implementing growth. But that mechanism doesn't work, because it's incomplete.
The function BasicHashtable<>::copy_freelist copies the free-list pointers. But the allocated blocks in _entry_blocks are not transferred. When the original table is deleted, the allocated blocks are deleted. And that's out from under the continuing use of the entries allocated from them that have been moved to the new table.
copy_freelist should also transfer the blocks. Also, a better name might be transfer_freelist, or perhaps merge_freelist, as it's not copying. And it might want to record (for debugging) that such a transfer has happened, with asserts to prevent reuse of the old table for entry management.
The only current user of copy_freelist is G1CodeRootSetTable (by copy_to). It gets away with this because it doesn't use the block allocator. It doesn't call BasicHashtable<>::new_entry. Instead, if the free-list is empty then a new entry is directly C-heap allocated. It also doesn't transfer entries between tables when a new larger table is needed. (And it doesn't do resize in place because of concurrent access.)
_entry_blocks (GrowableArray<...>)
- declared in BasicHashtable
- initialized in BasicHashtable constructors
- entries freed in ~BasicHashtable
- appended to in BasicHashtable::new_entry
It also tries to support direct transfer of entries from one hashtable to another as a mechanism for implementing growth. But that mechanism doesn't work, because it's incomplete.
The function BasicHashtable<>::copy_freelist copies the free-list pointers. But the allocated blocks in _entry_blocks are not transferred. When the original table is deleted, the allocated blocks are deleted. And that's out from under the continuing use of the entries allocated from them that have been moved to the new table.
copy_freelist should also transfer the blocks. Also, a better name might be transfer_freelist, or perhaps merge_freelist, as it's not copying. And it might want to record (for debugging) that such a transfer has happened, with asserts to prevent reuse of the old table for entry management.
The only current user of copy_freelist is G1CodeRootSetTable (by copy_to). It gets away with this because it doesn't use the block allocator. It doesn't call BasicHashtable<>::new_entry. Instead, if the free-list is empty then a new entry is directly C-heap allocated. It also doesn't transfer entries between tables when a new larger table is needed. (And it doesn't do resize in place because of concurrent access.)
- duplicates
-
JDK-8263976 Remove block allocation from BasicHashtable
-
- Resolved
-