< prev index next >

src/hotspot/share/utilities/resourceHash.hpp

Print this page
@@ -104,21 +104,11 @@
    ResourceHashtableBase(unsigned size) : STORAGE(size), _number_of_entries(0) {}
    NONCOPYABLE(ResourceHashtableBase);
  
    ~ResourceHashtableBase() {
      if (ALLOC_TYPE == AnyObj::C_HEAP) {
-       Node* const* bucket = table();
-       const unsigned sz = table_size();
-       while (bucket < bucket_at(sz)) {
-         Node* node = *bucket;
-         while (node != nullptr) {
-           Node* cur = node;
-           node = node->_next;
-           delete cur;
-         }
-         ++bucket;
-       }
+       unlink_all();
      }
    }
  
   public:
    unsigned table_size() const { return STORAGE::table_size(); }

@@ -293,12 +283,15 @@
    // called for each entry in the table.  If do_entry() returns true,
    // the entry is deleted.
    template<class ITER>
    void unlink(ITER* iter) {
      const unsigned sz = table_size();
-     for (unsigned index = 0; index < sz; index++) {
+     int cnt = _number_of_entries;
+ 
+     for (unsigned index = 0; cnt > 0 && index < sz; ++index) {
        Node** ptr = bucket_at(index);
+ 
        while (*ptr != nullptr) {
          Node* node = *ptr;
          // do_entry must clean up the key and value in Node.
          bool clean = iter->do_entry(node->_key, node->_value);
          if (clean) {

@@ -308,12 +301,42 @@
            }
            _number_of_entries --;
          } else {
            ptr = &(node->_next);
          }
+         if (--cnt <= 0) return;
+       }
+     }
+   }
+ 
+   // unlink_all() is a specialized version of unlink() when we decide to remove all elements.
+   // It can not replace unlink(ITER* iter) if user-provided iter releases key/value
+   void unlink_all() {
+     Node** bucket = table();
+     const unsigned sz = table_size();
+ 
+     while (_number_of_entries > 0 && bucket < bucket_at(sz)) {
+       Node* node = *bucket;
+       int n = 0;
+ 
+       while (node != NULL) {
+         Node* cur = node;
+         node = node->_next;
+         if (ALLOC_TYPE == AnyObj::C_HEAP) {
+           delete cur;
+         }
+         n++;
        }
+ 
+       if (n > 0) {
+         *bucket = nullptr;
+         _number_of_entries -= n;
+       }
+       bucket++;
      }
+ 
+     assert(_number_of_entries == 0, "sanity check");
    }
  
    template<typename Function>
    TableStatistics statistics_calculate(Function size_function) const {
      NumberSeq summary;
< prev index next >