diff -r a11aa80cd695 -r d89d36d67c94 src/share/vm/utilities/hashtable.hpp --- a/src/share/vm/utilities/hashtable.hpp Tue Jul 25 22:07:42 2017 -0700 +++ b/src/share/vm/utilities/hashtable.hpp Mon May 15 12:20:15 2017 +0200 @@ -164,11 +164,11 @@ // Instance variables int _table_size; HashtableBucket* _buckets; - BasicHashtableEntry* _free_list; + BasicHashtableEntry* volatile _free_list; char* _first_free_entry; char* _end_block; int _entry_size; - int _number_of_entries; + volatile int _number_of_entries; protected: @@ -215,6 +215,24 @@ // Free the buckets in this hashtable void free_buckets(); + // Helper data structure containing context for the bucket entry unlink process, + // storing the unlinked buckets in a linked list. + // Also avoids the need to pass around these four members as parameters everywhere. + struct BucketUnlinkContext { + int _num_processed; + int _num_removed; + // Head and tail pointers for the linked list of removed entries. + BasicHashtableEntry* _removed_head; + BasicHashtableEntry* _removed_tail; + + BucketUnlinkContext() : _num_processed(0), _num_removed(0), _removed_head(NULL), _removed_tail(NULL) { + } + + void free_entry(BasicHashtableEntry* entry); + }; + // Add of bucket entries linked together in the given context to the global free list. This method + // is mt-safe wrt. to other calls of this method. + void bulk_free_entries(BucketUnlinkContext* context); public: int table_size() { return _table_size; } void set_entry(int index, BasicHashtableEntry* entry);