Merge
diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index a9a6c5b..51d1fb4 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -724,3 +724,4 @@
 f1021394489da9a3621ba92fd427572abb32413f jdk8u141-b32
 9a342a4d909784cccb664f2293c8cb1463c3ac41 jdk8u144-b00
 57a5aae91b8bdccc4e1910cf373f13598429f03e jdk8u144-b01
+21446f3c909e3ed750def8b4dacbec6074606ed3 jdk8u144-b31
diff --git a/corba/.hgtags b/corba/.hgtags
index bc09f2a..d4b98d5 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -759,3 +759,4 @@
 1bbe5d997ab4e030dd961ab78e11ddae1bc6786c jdk8u141-b32
 77461a27d91fcb53106e6b3234468bff4d0eec9e jdk8u144-b00
 0d5d2e29f93b01ffa4998c2e3a61d2e6eaa96b1b jdk8u144-b01
+d3a4dd903475fd77fae2f6f87deb9219f455dcff jdk8u144-b31
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index e453579..ffb1cb7 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -989,3 +989,4 @@
 ae8cae699f62b845703c891e0e7633e2089a3ec4 jdk8u141-b32
 eea89df81a8e414813d921eeeeef9b6795f56698 jdk8u144-b00
 db36f4d498b1bde975700a800b5ce732941c04b7 jdk8u144-b01
+f5ded236c4130415259efc3234a92cc69fd7d2c5 jdk8u144-b31
diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp
index 38868b2..ec97077 100644
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -96,7 +96,7 @@
 int SymbolTable::_symbols_counted = 0;
 volatile int SymbolTable::_parallel_claimed_idx = 0;
 
-void SymbolTable::buckets_unlink(int start_idx, int end_idx, int* processed, int* removed, size_t* memory_total) {
+void SymbolTable::buckets_unlink(int start_idx, int end_idx, BucketUnlinkContext* context, size_t* memory_total) {
   for (int i = start_idx; i < end_idx; ++i) {
     HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i);
     HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i);
@@ -110,15 +110,14 @@
       }
       Symbol* s = entry->literal();
       (*memory_total) += s->size();
-      (*processed)++;
+      context->_num_processed++;
       assert(s != NULL, "just checking");
       // If reference count is zero, remove.
       if (s->refcount() == 0) {
         assert(!entry->is_shared(), "shared entries should be kept live");
         delete s;
-        (*removed)++;
         *p = entry->next();
-        the_table()->free_entry(entry);
+        context->free_entry(entry);
       } else {
         p = entry->next_addr();
       }
@@ -132,9 +131,14 @@
 // This is done late during GC.
 void SymbolTable::unlink(int* processed, int* removed) {
   size_t memory_total = 0;
-  buckets_unlink(0, the_table()->table_size(), processed, removed, &memory_total);
-  _symbols_removed += *removed;
-  _symbols_counted += *processed;
+  BucketUnlinkContext context;
+  buckets_unlink(0, the_table()->table_size(), &context, &memory_total);
+  _the_table->bulk_free_entries(&context);
+  *processed = context._num_processed;
+  *removed = context._num_removed;
+
+  _symbols_removed = context._num_removed;
+  _symbols_counted = context._num_processed;
   // Exclude printing for normal PrintGCDetails because people parse
   // this output.
   if (PrintGCDetails && Verbose && WizardMode) {
@@ -148,6 +152,7 @@
 
   size_t memory_total = 0;
 
+  BucketUnlinkContext context;
   for (;;) {
     // Grab next set of buckets to scan
     int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
@@ -157,10 +162,15 @@
     }
 
     int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
-    buckets_unlink(start_idx, end_idx, processed, removed, &memory_total);
+    buckets_unlink(start_idx, end_idx, &context, &memory_total);
   }
-  Atomic::add(*processed, &_symbols_counted);
-  Atomic::add(*removed, &_symbols_removed);
+
+  _the_table->bulk_free_entries(&context);
+  *processed = context._num_processed;
+  *removed = context._num_removed;
+
+  Atomic::add(context._num_processed, &_symbols_counted);
+  Atomic::add(context._num_removed, &_symbols_removed);
   // Exclude printing for normal PrintGCDetails because people parse
   // this output.
   if (PrintGCDetails && Verbose && WizardMode) {
@@ -811,7 +821,11 @@
 }
 
 void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) {
-  buckets_unlink_or_oops_do(is_alive, f, 0, the_table()->table_size(), processed, removed);
+  BucketUnlinkContext context;
+  buckets_unlink_or_oops_do(is_alive, f, 0, the_table()->table_size(), &context);
+  _the_table->bulk_free_entries(&context);
+  *processed = context._num_processed;
+  *removed = context._num_removed;
 }
 
 void StringTable::possibly_parallel_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) {
@@ -820,6 +834,7 @@
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   const int limit = the_table()->table_size();
 
+  BucketUnlinkContext context;
   for (;;) {
     // Grab next set of buckets to scan
     int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
@@ -829,8 +844,11 @@
     }
 
     int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
-    buckets_unlink_or_oops_do(is_alive, f, start_idx, end_idx, processed, removed);
+    buckets_unlink_or_oops_do(is_alive, f, start_idx, end_idx, &context);
   }
+  _the_table->bulk_free_entries(&context);
+  *processed = context._num_processed;
+  *removed = context._num_removed;
 }
 
 void StringTable::buckets_oops_do(OopClosure* f, int start_idx, int end_idx) {
@@ -856,7 +874,7 @@
   }
 }
 
-void StringTable::buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed) {
+void StringTable::buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, BucketUnlinkContext* context) {
   const int limit = the_table()->table_size();
 
   assert(0 <= start_idx && start_idx <= limit,
@@ -880,10 +898,9 @@
         p = entry->next_addr();
       } else {
         *p = entry->next();
-        the_table()->free_entry(entry);
-        (*removed)++;
+        context->free_entry(entry);
       }
-      (*processed)++;
+      context->_num_processed++;
       entry = *p;
     }
   }
diff --git a/hotspot/src/share/vm/classfile/symbolTable.hpp b/hotspot/src/share/vm/classfile/symbolTable.hpp
index d658440..58fd223 100644
--- a/hotspot/src/share/vm/classfile/symbolTable.hpp
+++ b/hotspot/src/share/vm/classfile/symbolTable.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -124,8 +124,11 @@
 
   static volatile int _parallel_claimed_idx;
 
-  // Release any dead symbols
-  static void buckets_unlink(int start_idx, int end_idx, int* processed, int* removed, size_t* memory_total);
+  typedef SymbolTable::BucketUnlinkContext BucketUnlinkContext;
+  // Release any dead symbols. Unlinked bucket entries are collected in the given
+  // context to be freed later.
+  // This allows multiple threads to work on the table at once.
+  static void buckets_unlink(int start_idx, int end_idx, BucketUnlinkContext* context, size_t* memory_total);
 public:
   enum {
     symbol_alloc_batch_size = 8,
@@ -274,9 +277,13 @@
   // Apply the give oop closure to the entries to the buckets
   // in the range [start_idx, end_idx).
   static void buckets_oops_do(OopClosure* f, int start_idx, int end_idx);
+
+  typedef StringTable::BucketUnlinkContext BucketUnlinkContext;
   // Unlink or apply the give oop closure to the entries to the buckets
-  // in the range [start_idx, end_idx).
-  static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed);
+  // in the range [start_idx, end_idx). Unlinked bucket entries are collected in the given
+  // context to be freed later.
+  // This allows multiple threads to work on the table at once.
+  static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, BucketUnlinkContext* context);
 
   StringTable() : RehashableHashtable<oop, mtSymbol>((int)StringTableSize,
                               sizeof (HashtableEntry<oop, mtSymbol>)) {}
diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
index 50fc13e..9fa549f 100644
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp
@@ -704,7 +704,7 @@
                                                                                                                                      \
   nonstatic_field(BasicHashtable<mtInternal>, _table_size,                                   int)                                   \
   nonstatic_field(BasicHashtable<mtInternal>, _buckets,                                      HashtableBucket<mtInternal>*)          \
-  nonstatic_field(BasicHashtable<mtInternal>, _free_list,                                    BasicHashtableEntry<mtInternal>*)      \
+  volatile_nonstatic_field(BasicHashtable<mtInternal>,  _free_list,                          BasicHashtableEntry<mtInternal>*)      \
   nonstatic_field(BasicHashtable<mtInternal>, _first_free_entry,                             char*)                                 \
   nonstatic_field(BasicHashtable<mtInternal>, _end_block,                                    char*)                                 \
   nonstatic_field(BasicHashtable<mtInternal>, _entry_size,                                   int)                                   \
diff --git a/hotspot/src/share/vm/utilities/hashtable.cpp b/hotspot/src/share/vm/utilities/hashtable.cpp
index a60fe76..ec260e9 100644
--- a/hotspot/src/share/vm/utilities/hashtable.cpp
+++ b/hotspot/src/share/vm/utilities/hashtable.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -172,6 +172,35 @@
   }
 }
 
+template <MEMFLAGS F> void BasicHashtable<F>::BucketUnlinkContext::free_entry(BasicHashtableEntry<F>* entry) {
+  entry->set_next(_removed_head);
+  _removed_head = entry;
+  if (_removed_tail == NULL) {
+    _removed_tail = entry;
+  }
+  _num_removed++;
+}
+
+template <MEMFLAGS F> void BasicHashtable<F>::bulk_free_entries(BucketUnlinkContext* context) {
+  if (context->_num_removed == 0) {
+    assert(context->_removed_head == NULL && context->_removed_tail == NULL,
+           err_msg("Zero entries in the unlink context, but elements linked from " PTR_FORMAT " to " PTR_FORMAT,
+                   p2i(context->_removed_head), p2i(context->_removed_tail)));
+    return;
+  }
+
+  // MT-safe add of the list of BasicHashTableEntrys from the context to the free list.
+  BasicHashtableEntry<F>* current = _free_list;
+  while (true) {
+    context->_removed_tail->set_next(current);
+    BasicHashtableEntry<F>* old = (BasicHashtableEntry<F>*)Atomic::cmpxchg_ptr(context->_removed_head, &_free_list, current);
+    if (old == current) {
+      break;
+    }
+    current = old;
+  }
+  Atomic::add(-context->_num_removed, &_number_of_entries);
+}
 
 // Copy the table to the shared space.
 
diff --git a/hotspot/src/share/vm/utilities/hashtable.hpp b/hotspot/src/share/vm/utilities/hashtable.hpp
index 6244c4c..d08deff 100644
--- a/hotspot/src/share/vm/utilities/hashtable.hpp
+++ b/hotspot/src/share/vm/utilities/hashtable.hpp
@@ -164,11 +164,11 @@
   // Instance variables
   int               _table_size;
   HashtableBucket<F>*     _buckets;
-  BasicHashtableEntry<F>* _free_list;
+  BasicHashtableEntry<F>* 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<F>* _removed_head;
+    BasicHashtableEntry<F>* _removed_tail;
+
+    BucketUnlinkContext() : _num_processed(0), _num_removed(0), _removed_head(NULL), _removed_tail(NULL) {
+    }
+
+    void free_entry(BasicHashtableEntry<F>* 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<F>* entry);
diff --git a/jaxp/.hgtags b/jaxp/.hgtags
index cd32fd35..549eae7 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -729,3 +729,4 @@
 e1412055ece943882d764224addb0eddd5f703b9 jdk8u141-b32
 4fe0f48f801c4262dfb964635ae5f2e7344326f4 jdk8u144-b00
 330bd721dee5b3680eea869efed01f481fb095df jdk8u144-b01
+ef94006bf28f7217b2ad1633ca3eff81c3320936 jdk8u144-b31
diff --git a/jaxws/.hgtags b/jaxws/.hgtags
index fa6c04d..7511842 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -718,3 +718,4 @@
 e6c85f5c962a5039101cd045b5251f2e92312a5f jdk8u141-b32
 c57e086660a37470793e38b94d7abedb79489ce3 jdk8u144-b00
 d2226ba553ca545f9bf9ffa66254478faca378a2 jdk8u144-b01
+3daeca3e0cc20f90e1141038d990778956e2e149 jdk8u144-b31
diff --git a/jdk/.hgtags b/jdk/.hgtags
index 76bd3be..f7702ce 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -726,3 +726,4 @@
 a3c4020f84aeb0dba467534239951f8818bdfb84 jdk8u141-b32
 b64b1dfdbe7cfe3859f1023c0f1fb0216bce4ae7 jdk8u144-b00
 d2744852f3e64f7b0ba54f3a64ed5e2107e6ee68 jdk8u144-b01
+a05113a4c91c59f44b9894e12aeda07a7534ff7e jdk8u144-b31
diff --git a/langtools/.hgtags b/langtools/.hgtags
index ac0b61e..32b879a 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -726,3 +726,4 @@
 09c2459991619ef7061ad2bc66373ed29f500acf jdk8u141-b32
 4c355f7002c36bb626b42d5c1d42ea91d77ba5d6 jdk8u144-b00
 816907853a15d9b22a87032d07327a400f8568b3 jdk8u144-b01
+e678eb754806df4be677ee27fe235968124faa6a jdk8u144-b31
diff --git a/nashorn/.hgtags b/nashorn/.hgtags
index 6f5ce5c..89d3047 100644
--- a/nashorn/.hgtags
+++ b/nashorn/.hgtags
@@ -705,3 +705,4 @@
 59bf0950e077f66d1f6c5ef4a3f1489b2b2048fa jdk8u141-b32
 6a52d202dfa3395d90cdd7dc24b8c437e5acc03d jdk8u144-b00
 7de0a688b0d910d4ef2cb89da6623b3ded431276 jdk8u144-b01
+a3c23983a7d6ab50f7978f992a979c6d26120775 jdk8u144-b31