Merge JDK-8200758-branch
authorherrick
Fri, 07 Dec 2018 21:07:26 -0500
branchJDK-8200758-branch
changeset 57066 2fd0529702cd
parent 57065 2446962c555c (current diff)
parent 52908 449a2ce77784 (diff)
child 57067 9c17d779808e
Merge
--- a/src/hotspot/cpu/sparc/vm_version_sparc.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/cpu/sparc/vm_version_sparc.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -521,15 +521,3 @@
 void VM_Version::revert() {
   _features = saved_features;
 }
-
-/* Determine a suitable number of threads on this particular machine.
- *
- * FIXME: Simply checking the processor family is insufficient.
- */
-unsigned int VM_Version::calc_parallel_worker_threads() {
-  const int num = 5;
-  const int den = is_post_niagara() ? 16 : 8;
-  const int threshold = 8;
-
-  return nof_parallel_worker_threads(num, den, threshold);
-}
--- a/src/hotspot/cpu/sparc/vm_version_sparc.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/cpu/sparc/vm_version_sparc.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -365,8 +365,12 @@
   //        this properly in order to enable complete page size support.
   static uint page_size_count() { return 2; }
 
-  // Calculates the number of parallel threads
-  static unsigned int calc_parallel_worker_threads();
+  // Override default denominator for ParallelGCThreads.
+  //
+  // FIXME: Simply checking the processor family is insufficient.
+  static uint parallel_worker_threads_denominator() {
+    return is_post_niagara() ? 16 : 8;
+  }
 };
 
 #endif // CPU_SPARC_VM_VM_VERSION_SPARC_HPP
--- a/src/hotspot/share/ci/ciInstanceKlass.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/ci/ciInstanceKlass.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -72,7 +72,7 @@
   // by the GC but need to be strong roots if reachable from a current compilation.
   // InstanceKlass are created for both weak and strong metadata.  Ensuring this metadata
   // alive covers the cases where there are weak roots without performance cost.
-  oop holder = ik->holder_phantom();
+  oop holder = ik->klass_holder();
   if (ik->is_unsafe_anonymous()) {
     // Though ciInstanceKlass records class loader oop, it's not enough to keep
     // VM unsafe anonymous classes alive (loader == NULL). Klass holder should
--- a/src/hotspot/share/classfile/classLoaderData.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/classfile/classLoaderData.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -176,12 +176,12 @@
   void clear_accumulated_modified_oops() { _accumulated_modified_oops = false; }
   bool has_accumulated_modified_oops()   { return _accumulated_modified_oops; }
   oop holder_no_keepalive() const;
+  oop holder_phantom() const;
 
  private:
   void unload();
   bool keep_alive() const       { return _keep_alive > 0; }
 
-  oop holder_phantom() const;
   void classes_do(void f(Klass* const));
   void loaded_classes_do(KlassClosure* klass_closure);
   void classes_do(void f(InstanceKlass*));
--- a/src/hotspot/share/code/codeCache.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/code/codeCache.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -1200,7 +1200,6 @@
 #endif
 }
 
-#ifdef HOTSWAP
 int CodeCache::mark_for_evol_deoptimization(InstanceKlass* dependee) {
   MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   int number_of_marked_CodeBlobs = 0;
@@ -1234,8 +1233,6 @@
 
   return number_of_marked_CodeBlobs;
 }
-#endif // HOTSWAP
-
 
 // Deoptimize all methods
 void CodeCache::mark_all_nmethods_for_deoptimization() {
@@ -1297,8 +1294,8 @@
   }
 }
 
-#ifdef HOTSWAP
-// Flushes compiled methods dependent on dependee in the evolutionary sense
+// Flushes compiled methods dependent on dependee when the dependee is redefined
+// via RedefineClasses
 void CodeCache::flush_evol_dependents_on(InstanceKlass* ev_k) {
   // --- Compile_lock is not held. However we are at a safepoint.
   assert_locked_or_safepoint(Compile_lock);
@@ -1326,8 +1323,6 @@
     make_marked_nmethods_not_entrant();
   }
 }
-#endif // HOTSWAP
-
 
 // Flushes compiled methods dependent on dependee
 void CodeCache::flush_dependents_on_method(const methodHandle& m_h) {
--- a/src/hotspot/share/code/codeCache.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/code/codeCache.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -286,9 +286,7 @@
   // Deoptimization
  private:
   static int  mark_for_deoptimization(KlassDepChange& changes);
-#ifdef HOTSWAP
   static int  mark_for_evol_deoptimization(InstanceKlass* dependee);
-#endif // HOTSWAP
 
  public:
   static void mark_all_nmethods_for_deoptimization();
@@ -297,10 +295,8 @@
 
   // Flushing and deoptimization
   static void flush_dependents_on(InstanceKlass* dependee);
-#ifdef HOTSWAP
   // Flushing and deoptimization in case of evolution
   static void flush_evol_dependents_on(InstanceKlass* dependee);
-#endif // HOTSWAP
   // Support for fullspeed debugging
   static void flush_dependents_on_method(const methodHandle& dependee);
 
--- a/src/hotspot/share/gc/cms/cmsArguments.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/cms/cmsArguments.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -30,10 +30,10 @@
 #include "gc/cms/compactibleFreeListSpace.hpp"
 #include "gc/shared/gcArguments.inline.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/globals_extension.hpp"
-#include "runtime/vm_version.hpp"
 #include "utilities/defaultStream.hpp"
 
 size_t CMSArguments::conservative_max_heap_alignment() {
@@ -46,7 +46,7 @@
   assert(UseConcMarkSweepGC, "CMS is expected to be on here");
 
   if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
-    FLAG_SET_DEFAULT(ParallelGCThreads, VM_Version::parallel_worker_threads());
+    FLAG_SET_DEFAULT(ParallelGCThreads, WorkerPolicy::parallel_worker_threads());
     assert(ParallelGCThreads > 0, "We should always have at least one thread by default");
   } else if (ParallelGCThreads == 0) {
     jio_fprintf(defaultStream::error_stream(),
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -55,12 +55,14 @@
 #include "gc/shared/genOopClosures.inline.hpp"
 #include "gc/shared/isGCActiveMark.hpp"
 #include "gc/shared/oopStorageParState.hpp"
+#include "gc/shared/owstTaskTerminator.hpp"
 #include "gc/shared/referencePolicy.hpp"
 #include "gc/shared/referenceProcessorPhaseTimes.hpp"
 #include "gc/shared/space.inline.hpp"
 #include "gc/shared/strongRootsScope.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
 #include "gc/shared/weakProcessor.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/allocation.hpp"
@@ -2981,7 +2983,7 @@
 // Forward decl
 class CMSConcMarkingTask;
 
-class CMSConcMarkingTerminator: public ParallelTaskTerminator {
+class CMSConcMarkingParallelTerminator: public ParallelTaskTerminator {
   CMSCollector*       _collector;
   CMSConcMarkingTask* _task;
  public:
@@ -2991,7 +2993,7 @@
   // "queue_set" is a set of work queues of other threads.
   // "collector" is the CMS collector associated with this task terminator.
   // "yield" indicates whether we need the gang as a whole to yield.
-  CMSConcMarkingTerminator(int n_threads, TaskQueueSetSuper* queue_set, CMSCollector* collector) :
+  CMSConcMarkingParallelTerminator(int n_threads, TaskQueueSetSuper* queue_set, CMSCollector* collector) :
     ParallelTaskTerminator(n_threads, queue_set),
     _collector(collector) { }
 
@@ -3000,6 +3002,45 @@
   }
 };
 
+class CMSConcMarkingOWSTTerminator: public OWSTTaskTerminator {
+  CMSCollector*       _collector;
+  CMSConcMarkingTask* _task;
+ public:
+  virtual void yield();
+
+  // "n_threads" is the number of threads to be terminated.
+  // "queue_set" is a set of work queues of other threads.
+  // "collector" is the CMS collector associated with this task terminator.
+  // "yield" indicates whether we need the gang as a whole to yield.
+  CMSConcMarkingOWSTTerminator(int n_threads, TaskQueueSetSuper* queue_set, CMSCollector* collector) :
+    OWSTTaskTerminator(n_threads, queue_set),
+    _collector(collector) { }
+
+  void set_task(CMSConcMarkingTask* task) {
+    _task = task;
+  }
+};
+
+class CMSConcMarkingTaskTerminator {
+ private:
+  ParallelTaskTerminator* _term;
+ public:
+  CMSConcMarkingTaskTerminator(int n_threads, TaskQueueSetSuper* queue_set, CMSCollector* collector) {
+    if (UseOWSTTaskTerminator) {
+      _term = new CMSConcMarkingOWSTTerminator(n_threads, queue_set, collector);
+    } else {
+      _term = new CMSConcMarkingParallelTerminator(n_threads, queue_set, collector);
+    }
+  }
+  ~CMSConcMarkingTaskTerminator() {
+    assert(_term != NULL, "Must not be NULL");
+    delete _term;
+  }
+
+  void set_task(CMSConcMarkingTask* task);
+  ParallelTaskTerminator* terminator() const { return _term; }
+};
+
 class CMSConcMarkingTerminatorTerminator: public TerminatorTerminator {
   CMSConcMarkingTask* _task;
  public:
@@ -3027,7 +3068,7 @@
   OopTaskQueueSet*  _task_queues;
 
   // Termination (and yielding) support
-  CMSConcMarkingTerminator _term;
+  CMSConcMarkingTaskTerminator       _term;
   CMSConcMarkingTerminatorTerminator _term_term;
 
  public:
@@ -3057,7 +3098,7 @@
 
   HeapWord* volatile* global_finger_addr() { return &_global_finger; }
 
-  CMSConcMarkingTerminator* terminator() { return &_term; }
+  ParallelTaskTerminator* terminator() { return _term.terminator(); }
 
   virtual void set_for_termination(uint active_workers) {
     terminator()->reset_for_reuse(active_workers);
@@ -3075,7 +3116,7 @@
   void reset(HeapWord* ra) {
     assert(_global_finger >= _cms_space->end(),  "Postcondition of ::work(i)");
     _restart_addr = _global_finger = ra;
-    _term.reset_for_reuse();
+    _term.terminator()->reset_for_reuse();
   }
 
   static bool get_work_from_overflow_stack(CMSMarkStack* ovflw_stk,
@@ -3096,7 +3137,7 @@
   // thread has yielded.
 }
 
-void CMSConcMarkingTerminator::yield() {
+void CMSConcMarkingParallelTerminator::yield() {
   if (_task->should_yield()) {
     _task->yield();
   } else {
@@ -3104,6 +3145,22 @@
   }
 }
 
+void CMSConcMarkingOWSTTerminator::yield() {
+  if (_task->should_yield()) {
+    _task->yield();
+  } else {
+    OWSTTaskTerminator::yield();
+  }
+}
+
+void CMSConcMarkingTaskTerminator::set_task(CMSConcMarkingTask* task) {
+  if (UseOWSTTaskTerminator) {
+    ((CMSConcMarkingOWSTTerminator*)_term)->set_task(task);
+  } else {
+    ((CMSConcMarkingParallelTerminator*)_term)->set_task(task);
+  }
+}
+
 ////////////////////////////////////////////////////////////////
 // Concurrent Marking Algorithm Sketch
 ////////////////////////////////////////////////////////////////
@@ -3488,9 +3545,9 @@
 
 bool CMSCollector::do_marking_mt() {
   assert(ConcGCThreads > 0 && conc_workers() != NULL, "precondition");
-  uint num_workers = AdaptiveSizePolicy::calc_active_conc_workers(conc_workers()->total_workers(),
-                                                                  conc_workers()->active_workers(),
-                                                                  Threads::number_of_non_daemon_threads());
+  uint num_workers = WorkerPolicy::calc_active_conc_workers(conc_workers()->total_workers(),
+                                                            conc_workers()->active_workers(),
+                                                            Threads::number_of_non_daemon_threads());
   num_workers = conc_workers()->update_active_workers(num_workers);
   log_info(gc,task)("Using %u workers of %u for marking", num_workers, conc_workers()->total_workers());
 
@@ -4292,7 +4349,7 @@
 
   // The per-thread work queues, available here for stealing.
   OopTaskQueueSet*       _task_queues;
-  ParallelTaskTerminator _term;
+  TaskTerminator         _term;
   StrongRootsScope*      _strong_roots_scope;
 
  public:
@@ -4314,7 +4371,7 @@
 
   OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
 
-  ParallelTaskTerminator* terminator() { return &_term; }
+  ParallelTaskTerminator* terminator() { return _term.terminator(); }
   uint n_workers() { return _n_workers; }
 
   void work(uint worker_id);
@@ -5002,11 +5059,11 @@
 ////////////////////////////////////////////////////////
 class AbstractGangTaskWOopQueues : public AbstractGangTask {
   OopTaskQueueSet*       _queues;
-  ParallelTaskTerminator _terminator;
+  TaskTerminator         _terminator;
  public:
   AbstractGangTaskWOopQueues(const char* name, OopTaskQueueSet* queues, uint n_threads) :
     AbstractGangTask(name), _queues(queues), _terminator(n_threads, _queues) {}
-  ParallelTaskTerminator* terminator() { return &_terminator; }
+  ParallelTaskTerminator* terminator() { return _terminator.terminator(); }
   OopTaskQueueSet* queues() { return _queues; }
 };
 
--- a/src/hotspot/share/gc/cms/parNewGeneration.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/cms/parNewGeneration.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -49,6 +49,7 @@
 #include "gc/shared/taskqueue.inline.hpp"
 #include "gc/shared/weakProcessor.hpp"
 #include "gc/shared/workgroup.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/iterator.inline.hpp"
@@ -74,7 +75,7 @@
                                        Stack<oop, mtGC>* overflow_stacks_,
                                        PreservedMarks* preserved_marks_,
                                        size_t desired_plab_sz_,
-                                       ParallelTaskTerminator& term_) :
+                                       TaskTerminator& term_) :
   _work_queue(work_queue_set_->queue(thread_num_)),
   _overflow_stack(overflow_stacks_ ? overflow_stacks_ + thread_num_ : NULL),
   _preserved_marks(preserved_marks_),
@@ -86,7 +87,7 @@
   _old_gen_root_closure(young_gen_, this),
   _evacuate_followers(this, &_to_space_closure, &_old_gen_closure,
                       &_to_space_root_closure, young_gen_, &_old_gen_root_closure,
-                      work_queue_set_, &term_),
+                      work_queue_set_, term_.terminator()),
   _is_alive_closure(young_gen_),
   _scan_weak_ref_closure(young_gen_, this),
   _keep_alive_closure(&_scan_weak_ref_closure),
@@ -305,7 +306,7 @@
                         Stack<oop, mtGC>*       overflow_stacks_,
                         PreservedMarksSet&      preserved_marks_set,
                         size_t                  desired_plab_sz,
-                        ParallelTaskTerminator& term);
+                        TaskTerminator& term);
 
   ~ParScanThreadStateSet() { TASKQUEUE_STATS_ONLY(reset_stats()); }
 
@@ -326,14 +327,14 @@
   #endif // TASKQUEUE_STATS
 
 private:
-  ParallelTaskTerminator& _term;
+  TaskTerminator&         _term;
   ParNewGeneration&       _young_gen;
   Generation&             _old_gen;
   ParScanThreadState*     _per_thread_states;
   const int               _num_threads;
  public:
   bool is_valid(int id) const { return id < _num_threads; }
-  ParallelTaskTerminator* terminator() { return &_term; }
+  ParallelTaskTerminator* terminator() { return _term.terminator(); }
 };
 
 ParScanThreadStateSet::ParScanThreadStateSet(int num_threads,
@@ -344,7 +345,7 @@
                                              Stack<oop, mtGC>* overflow_stacks,
                                              PreservedMarksSet& preserved_marks_set,
                                              size_t desired_plab_sz,
-                                             ParallelTaskTerminator& term)
+                                             TaskTerminator& term)
   : _term(term),
     _young_gen(young_gen),
     _old_gen(old_gen),
@@ -378,7 +379,7 @@
 }
 
 void ParScanThreadStateSet::reset(uint active_threads, bool promotion_failed) {
-  _term.reset_for_reuse(active_threads);
+  _term.terminator()->reset_for_reuse(active_threads);
   if (promotion_failed) {
     for (int i = 0; i < _num_threads; ++i) {
       thread_state(i).print_promotion_failure_size();
@@ -866,9 +867,9 @@
   WorkGang* workers = gch->workers();
   assert(workers != NULL, "Need workgang for parallel work");
   uint active_workers =
-       AdaptiveSizePolicy::calc_active_workers(workers->total_workers(),
-                                               workers->active_workers(),
-                                               Threads::number_of_non_daemon_threads());
+      WorkerPolicy::calc_active_workers(workers->total_workers(),
+                                        workers->active_workers(),
+                                        Threads::number_of_non_daemon_threads());
   active_workers = workers->update_active_workers(active_workers);
   log_info(gc,task)("Using %u workers of %u for evacuation", active_workers, workers->total_workers());
 
@@ -903,7 +904,7 @@
 
   // Always set the terminator for the active number of workers
   // because only those workers go through the termination protocol.
-  ParallelTaskTerminator _term(active_workers, task_queues());
+  TaskTerminator _term(active_workers, task_queues());
   ParScanThreadStateSet thread_state_set(active_workers,
                                          *to(), *this, *_old_gen, *task_queues(),
                                          _overflow_stacks, _preserved_marks_set,
--- a/src/hotspot/share/gc/cms/parNewGeneration.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/cms/parNewGeneration.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -133,7 +133,7 @@
                      Stack<oop, mtGC>* overflow_stacks_,
                      PreservedMarks* preserved_marks_,
                      size_t desired_plab_sz_,
-                     ParallelTaskTerminator& term_);
+                     TaskTerminator& term_);
 
  public:
   AgeTable* age_table() {return &_ageTable;}
--- a/src/hotspot/share/gc/g1/g1Arguments.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1Arguments.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -30,9 +30,9 @@
 #include "gc/g1/g1HeapVerifier.hpp"
 #include "gc/g1/heapRegion.hpp"
 #include "gc/shared/gcArguments.inline.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/globals_extension.hpp"
-#include "runtime/vm_version.hpp"
 
 size_t G1Arguments::conservative_max_heap_alignment() {
   return HeapRegion::max_region_size();
@@ -77,7 +77,7 @@
 void G1Arguments::initialize() {
   GCArguments::initialize();
   assert(UseG1GC, "Error");
-  FLAG_SET_DEFAULT(ParallelGCThreads, VM_Version::parallel_worker_threads());
+  FLAG_SET_DEFAULT(ParallelGCThreads, WorkerPolicy::parallel_worker_threads());
   if (ParallelGCThreads == 0) {
     assert(!FLAG_IS_DEFAULT(ParallelGCThreads), "The default value for ParallelGCThreads should not be 0.");
     vm_exit_during_initialization("The flag -XX:+UseG1GC can not be combined with -XX:ParallelGCThreads=0", NULL);
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -61,7 +61,6 @@
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/g1/heapRegionSet.inline.hpp"
-#include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/gcBehaviours.hpp"
 #include "gc/shared/gcHeapSummary.hpp"
 #include "gc/shared/gcId.hpp"
@@ -78,6 +77,7 @@
 #include "gc/shared/referenceProcessor.inline.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
 #include "gc/shared/weakProcessor.inline.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "memory/iterator.hpp"
@@ -2912,9 +2912,9 @@
     }
     GCTraceTime(Info, gc) tm(gc_string, NULL, gc_cause(), true);
 
-    uint active_workers = AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(),
-                                                                  workers()->active_workers(),
-                                                                  Threads::number_of_non_daemon_threads());
+    uint active_workers = WorkerPolicy::calc_active_workers(workers()->total_workers(),
+                                                            workers()->active_workers(),
+                                                            Threads::number_of_non_daemon_threads());
     active_workers = workers()->update_active_workers(active_workers);
     log_info(gc,task)("Using %u workers of %u for evacuation", active_workers, workers()->total_workers());
 
@@ -3215,7 +3215,7 @@
   G1ParScanThreadStateSet* _pss;
   RefToScanQueueSet*       _queues;
   G1RootProcessor*         _root_processor;
-  ParallelTaskTerminator   _terminator;
+  TaskTerminator           _terminator;
   uint                     _n_workers;
 
 public:
@@ -3260,7 +3260,7 @@
       size_t evac_term_attempts = 0;
       {
         double start = os::elapsedTime();
-        G1ParEvacuateFollowersClosure evac(_g1h, pss, _queues, &_terminator, G1GCPhaseTimes::ObjCopy);
+        G1ParEvacuateFollowersClosure evac(_g1h, pss, _queues, _terminator.terminator(), G1GCPhaseTimes::ObjCopy);
         evac.do_void();
 
         evac_term_attempts = evac.term_attempts();
@@ -3572,8 +3572,8 @@
   assert(_workers->active_workers() >= ergo_workers,
          "Ergonomically chosen workers (%u) should be less than or equal to active workers (%u)",
          ergo_workers, _workers->active_workers());
-  ParallelTaskTerminator terminator(ergo_workers, _queues);
-  G1STWRefProcTaskProxy proc_task_proxy(proc_task, _g1h, _pss, _queues, &terminator);
+  TaskTerminator terminator(ergo_workers, _queues);
+  G1STWRefProcTaskProxy proc_task_proxy(proc_task, _g1h, _pss, _queues, terminator.terminator());
 
   _workers->run_task(&proc_task_proxy, ergo_workers);
 }
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -39,7 +39,6 @@
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/g1/heapRegionSet.inline.hpp"
-#include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/gcId.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
@@ -51,6 +50,7 @@
 #include "gc/shared/suspendibleThreadSet.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
 #include "gc/shared/weakProcessor.inline.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "include/jvm.h"
 #include "logging/log.hpp"
 #include "memory/allocation.hpp"
@@ -378,7 +378,7 @@
   // _tasks set inside the constructor
 
   _task_queues(new G1CMTaskQueueSet((int) _max_num_tasks)),
-  _terminator(ParallelTaskTerminator((int) _max_num_tasks, _task_queues)),
+  _terminator((int) _max_num_tasks, _task_queues),
 
   _first_overflow_barrier_sync(),
   _second_overflow_barrier_sync(),
@@ -588,7 +588,7 @@
   _num_active_tasks = active_tasks;
   // Need to update the three data structures below according to the
   // number of active threads for this phase.
-  _terminator = ParallelTaskTerminator((int) active_tasks, _task_queues);
+  _terminator = TaskTerminator((int) active_tasks, _task_queues);
   _first_overflow_barrier_sync.set_n_workers((int) active_tasks);
   _second_overflow_barrier_sync.set_n_workers((int) active_tasks);
 }
@@ -858,10 +858,10 @@
     result = _max_concurrent_workers;
   } else {
     result =
-      AdaptiveSizePolicy::calc_default_active_workers(_max_concurrent_workers,
-                                                      1, /* Minimum workers */
-                                                      _num_concurrent_workers,
-                                                      Threads::number_of_non_daemon_threads());
+      WorkerPolicy::calc_default_active_workers(_max_concurrent_workers,
+                                                1, /* Minimum workers */
+                                                _num_concurrent_workers,
+                                                Threads::number_of_non_daemon_threads());
     // Don't scale the result down by scale_concurrent_workers() because
     // that scaling has already gone into "_max_concurrent_workers".
   }
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -325,8 +325,8 @@
   uint                    _num_active_tasks; // Number of tasks currently active
   G1CMTask**              _tasks;            // Task queue array (max_worker_id length)
 
-  G1CMTaskQueueSet*       _task_queues;      // Task queue set
-  ParallelTaskTerminator  _terminator;       // For termination
+  G1CMTaskQueueSet*       _task_queues; // Task queue set
+  TaskTerminator          _terminator;  // For termination
 
   // Two sync barriers that are used to synchronize tasks when an
   // overflow occurs. The algorithm is the following. All tasks enter
@@ -412,10 +412,10 @@
   // Prints all gathered CM-related statistics
   void print_stats();
 
-  HeapWord*               finger()          { return _finger;   }
-  bool                    concurrent()      { return _concurrent; }
-  uint                    active_tasks()    { return _num_active_tasks; }
-  ParallelTaskTerminator* terminator()      { return &_terminator; }
+  HeapWord*               finger()           { return _finger;   }
+  bool                    concurrent()       { return _concurrent; }
+  uint                    active_tasks()     { return _num_active_tasks; }
+  ParallelTaskTerminator* terminator() const { return _terminator.terminator(); }
 
   // Claims the next available region to be scanned by a marking
   // task/thread. It might return NULL if the next region is empty or
--- a/src/hotspot/share/gc/g1/g1FullCollector.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -37,11 +37,11 @@
 #include "gc/g1/g1OopClosures.hpp"
 #include "gc/g1/g1Policy.hpp"
 #include "gc/g1/g1StringDedup.hpp"
-#include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/preservedMarks.hpp"
 #include "gc/shared/referenceProcessor.hpp"
 #include "gc/shared/weakProcessor.inline.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "logging/log.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/handles.inline.hpp"
@@ -88,15 +88,15 @@
   uint waste_worker_count = MAX2((max_wasted_regions_allowed * 2) , 1u);
   uint heap_waste_worker_limit = MIN2(waste_worker_count, max_worker_count);
 
-  // Also consider HeapSizePerGCThread by calling AdaptiveSizePolicy to calculate
+  // Also consider HeapSizePerGCThread by calling WorkerPolicy to calculate
   // the number of workers.
   uint current_active_workers = heap->workers()->active_workers();
-  uint adaptive_worker_limit = AdaptiveSizePolicy::calc_active_workers(max_worker_count, current_active_workers, 0);
+  uint active_worker_limit = WorkerPolicy::calc_active_workers(max_worker_count, current_active_workers, 0);
 
   // Update active workers to the lower of the limits.
-  uint worker_count = MIN2(heap_waste_worker_limit, adaptive_worker_limit);
+  uint worker_count = MIN2(heap_waste_worker_limit, active_worker_limit);
   log_debug(gc, task)("Requesting %u active workers for full compaction (waste limited workers: %u, adaptive workers: %u)",
-                      worker_count, heap_waste_worker_limit, adaptive_worker_limit);
+                      worker_count, heap_waste_worker_limit, active_worker_limit);
   worker_count = heap->workers()->update_active_workers(worker_count);
   log_info(gc, task)("Using %u workers of %u for full compaction", worker_count, max_worker_count);
 
--- a/src/hotspot/share/gc/g1/g1FullGCMarkTask.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1FullGCMarkTask.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -61,7 +61,7 @@
   }
 
   // Mark stack is populated, now process and drain it.
-  marker->complete_marking(collector()->oop_queue_set(), collector()->array_queue_set(), &_terminator);
+  marker->complete_marking(collector()->oop_queue_set(), collector()->array_queue_set(), _terminator.terminator());
 
   // This is the point where the entire marking should have completed.
   assert(marker->oop_stack()->is_empty(), "Marking should have completed");
--- a/src/hotspot/share/gc/g1/g1FullGCMarkTask.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1FullGCMarkTask.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -36,7 +36,7 @@
 
 class G1FullGCMarkTask : public G1FullGCTask {
   G1RootProcessor          _root_processor;
-  ParallelTaskTerminator   _terminator;
+  TaskTerminator           _terminator;
 
 public:
   G1FullGCMarkTask(G1FullCollector* collector);
--- a/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -165,7 +165,7 @@
 }
 
 inline void G1FullGCMarker::follow_klass(Klass* k) {
-  oop op = k->klass_holder();
+  oop op = k->class_loader_data()->holder_no_keepalive();
   mark_and_push(&op);
 }
 
--- a/src/hotspot/share/gc/g1/g1FullGCReferenceProcessorExecutor.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1FullGCReferenceProcessorExecutor.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -32,6 +32,7 @@
 #include "gc/g1/g1StringDedup.hpp"
 #include "gc/g1/heapRegionManager.hpp"
 #include "gc/shared/referenceProcessor.hpp"
+#include "gc/shared/taskqueue.hpp"
 #include "utilities/ticks.hpp"
 
 class G1FullGCTracer;
@@ -58,9 +59,9 @@
 
   class G1RefProcTaskProxy : public AbstractGangTask {
     typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
-    ProcessTask&             _proc_task;
-    G1FullCollector*         _collector;
-    ParallelTaskTerminator   _terminator;
+    ProcessTask&                  _proc_task;
+    G1FullCollector*              _collector;
+    TaskTerminator                _terminator;
 
   public:
     G1RefProcTaskProxy(ProcessTask& proc_task,
--- a/src/hotspot/share/gc/parallel/gcTaskManager.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/parallel/gcTaskManager.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -27,6 +27,7 @@
 #include "gc/parallel/gcTaskThread.hpp"
 #include "gc/shared/gcId.hpp"
 #include "gc/shared/workerManager.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/allocation.hpp"
@@ -494,9 +495,9 @@
 
 void GCTaskManager::set_active_gang() {
   _active_workers =
-    AdaptiveSizePolicy::calc_active_workers(workers(),
-                                 active_workers(),
-                                 Threads::number_of_non_daemon_threads());
+    WorkerPolicy::calc_active_workers(workers(),
+                                      active_workers(),
+                                      Threads::number_of_non_daemon_threads());
 
   assert(!all_workers_active() || active_workers() == ParallelGCThreads,
          "all_workers_active() is  incorrect: "
--- a/src/hotspot/share/gc/parallel/parallelArguments.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/parallel/parallelArguments.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -29,10 +29,10 @@
 #include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcArguments.inline.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
-#include "runtime/vm_version.hpp"
 #include "utilities/defaultStream.hpp"
 
 size_t ParallelArguments::conservative_max_heap_alignment() {
@@ -51,7 +51,7 @@
   // If no heap maximum was requested explicitly, use some reasonable fraction
   // of the physical memory, up to a maximum of 1GB.
   FLAG_SET_DEFAULT(ParallelGCThreads,
-                   VM_Version::parallel_worker_threads());
+                   WorkerPolicy::parallel_worker_threads());
   if (ParallelGCThreads == 0) {
     jio_fprintf(defaultStream::error_stream(),
         "The Parallel GC can not be combined with -XX:ParallelGCThreads=0\n");
--- a/src/hotspot/share/gc/parallel/pcTasks.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/parallel/pcTasks.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -158,14 +158,15 @@
          "Ergonomically chosen workers (%u) must be equal to active workers (%u)",
          ergo_workers, active_gc_threads);
   OopTaskQueueSet* qset = ParCompactionManager::stack_array();
-  ParallelTaskTerminator terminator(active_gc_threads, qset);
+  TaskTerminator terminator(active_gc_threads, qset);
+
   GCTaskQueue* q = GCTaskQueue::create();
   for(uint i=0; i<active_gc_threads; i++) {
     q->enqueue(new RefProcTaskProxy(task, i));
   }
   if (task.marks_oops_alive() && (active_gc_threads>1)) {
     for (uint j=0; j<active_gc_threads; j++) {
-      q->enqueue(new StealMarkingTask(&terminator));
+      q->enqueue(new StealMarkingTask(terminator.terminator()));
     }
   }
   PSParallelCompact::gc_task_manager()->execute_and_wait(q);
--- a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -117,7 +117,7 @@
 }
 
 inline void ParCompactionManager::follow_klass(Klass* klass) {
-  oop holder = klass->klass_holder();
+  oop holder = klass->class_loader_data()->holder_no_keepalive();
   mark_and_push(&holder);
 }
 
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -2100,7 +2100,7 @@
   uint parallel_gc_threads = heap->gc_task_manager()->workers();
   uint active_gc_threads = heap->gc_task_manager()->active_workers();
   TaskQueueSetSuper* qset = ParCompactionManager::stack_array();
-  ParallelTaskTerminator terminator(active_gc_threads, qset);
+  TaskTerminator terminator(active_gc_threads, qset);
 
   PCMarkAndPushClosure mark_and_push_closure(cm);
   ParCompactionManager::FollowStackClosure follow_stack_closure(cm);
@@ -2129,7 +2129,7 @@
 
     if (active_gc_threads > 1) {
       for (uint j = 0; j < active_gc_threads; j++) {
-        q->enqueue(new StealMarkingTask(&terminator));
+        q->enqueue(new StealMarkingTask(terminator.terminator()));
       }
     }
 
@@ -2459,12 +2459,12 @@
   uint parallel_gc_threads = heap->gc_task_manager()->workers();
   uint active_gc_threads = heap->gc_task_manager()->active_workers();
   TaskQueueSetSuper* qset = ParCompactionManager::region_array();
-  ParallelTaskTerminator terminator(active_gc_threads, qset);
+  TaskTerminator terminator(active_gc_threads, qset);
 
   GCTaskQueue* q = GCTaskQueue::create();
   prepare_region_draining_tasks(q, active_gc_threads);
   enqueue_dense_prefix_tasks(q, active_gc_threads);
-  enqueue_region_stealing_tasks(q, &terminator, active_gc_threads);
+  enqueue_region_stealing_tasks(q, terminator.terminator(), active_gc_threads);
 
   {
     GCTraceTime(Trace, gc, phases) tm("Par Compact", &_gc_timer);
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -168,11 +168,11 @@
   for(uint i=0; i < active_workers; i++) {
     q->enqueue(new PSRefProcTaskProxy(task, i));
   }
-  ParallelTaskTerminator terminator(active_workers,
-                                    (TaskQueueSetSuper*) PSPromotionManager::stack_array_depth());
+  TaskTerminator terminator(active_workers,
+                            (TaskQueueSetSuper*) PSPromotionManager::stack_array_depth());
   if (task.marks_oops_alive() && active_workers > 1) {
     for (uint j = 0; j < active_workers; j++) {
-      q->enqueue(new StealTask(&terminator));
+      q->enqueue(new StealTask(terminator.terminator()));
     }
   }
   manager->execute_and_wait(q);
@@ -380,16 +380,15 @@
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache));
 
-      ParallelTaskTerminator terminator(
-        active_workers,
-                  (TaskQueueSetSuper*) promotion_manager->stack_array_depth());
+      TaskTerminator terminator(active_workers,
+                                (TaskQueueSetSuper*) promotion_manager->stack_array_depth());
         // If active_workers can exceed 1, add a StrealTask.
         // PSPromotionManager::drain_stacks_depth() does not fully drain its
         // stacks and expects a StealTask to complete the draining if
         // ParallelGCThreads is > 1.
         if (gc_task_manager()->workers() > 1) {
           for (uint j = 0; j < active_workers; j++) {
-            q->enqueue(new StealTask(&terminator));
+            q->enqueue(new StealTask(terminator.terminator()));
           }
         }
 
--- a/src/hotspot/share/gc/serial/markSweep.inline.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/serial/markSweep.inline.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -57,7 +57,7 @@
 }
 
 inline void MarkSweep::follow_klass(Klass* klass) {
-  oop op = klass->klass_holder();
+  oop op = klass->class_loader_data()->holder_no_keepalive();
   MarkSweep::mark_and_push(&op);
 }
 
--- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2018, 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
@@ -24,18 +24,14 @@
 
 #include "precompiled.hpp"
 #include "gc/shared/adaptiveSizePolicy.hpp"
-#include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/gcUtil.inline.hpp"
 #include "gc/shared/softRefPolicy.hpp"
-#include "gc/shared/workgroup.hpp"
 #include "logging/log.hpp"
 #include "runtime/timer.hpp"
-#include "utilities/ostream.hpp"
 
 elapsedTimer AdaptiveSizePolicy::_minor_timer;
 elapsedTimer AdaptiveSizePolicy::_major_timer;
-bool AdaptiveSizePolicy::_debug_perturbation = false;
 
 // The throughput goal is implemented as
 //      _throughput_goal = 1 - ( 1 / (1 + gc_cost_ratio))
@@ -94,129 +90,6 @@
   _young_gen_policy_is_ready = false;
 }
 
-//  If the number of GC threads was set on the command line,
-// use it.
-//  Else
-//    Calculate the number of GC threads based on the number of Java threads.
-//    Calculate the number of GC threads based on the size of the heap.
-//    Use the larger.
-
-uint AdaptiveSizePolicy::calc_default_active_workers(uintx total_workers,
-                                                     const uintx min_workers,
-                                                     uintx active_workers,
-                                                     uintx application_workers) {
-  // If the user has specifically set the number of
-  // GC threads, use them.
-
-  // If the user has turned off using a dynamic number of GC threads
-  // or the users has requested a specific number, set the active
-  // number of workers to all the workers.
-
-  uintx new_active_workers = total_workers;
-  uintx prev_active_workers = active_workers;
-  uintx active_workers_by_JT = 0;
-  uintx active_workers_by_heap_size = 0;
-
-  // Always use at least min_workers but use up to
-  // GCThreadsPerJavaThreads * application threads.
-  active_workers_by_JT =
-    MAX2((uintx) GCWorkersPerJavaThread * application_workers,
-         min_workers);
-
-  // Choose a number of GC threads based on the current size
-  // of the heap.  This may be complicated because the size of
-  // the heap depends on factors such as the throughput goal.
-  // Still a large heap should be collected by more GC threads.
-  active_workers_by_heap_size =
-      MAX2((size_t) 2U, Universe::heap()->capacity() / HeapSizePerGCThread);
-
-  uintx max_active_workers =
-    MAX2(active_workers_by_JT, active_workers_by_heap_size);
-
-  new_active_workers = MIN2(max_active_workers, (uintx) total_workers);
-
-  // Increase GC workers instantly but decrease them more
-  // slowly.
-  if (new_active_workers < prev_active_workers) {
-    new_active_workers =
-      MAX2(min_workers, (prev_active_workers + new_active_workers) / 2);
-  }
-
-  // Check once more that the number of workers is within the limits.
-  assert(min_workers <= total_workers, "Minimum workers not consistent with total workers");
-  assert(new_active_workers >= min_workers, "Minimum workers not observed");
-  assert(new_active_workers <= total_workers, "Total workers not observed");
-
-  if (ForceDynamicNumberOfGCThreads) {
-    // Assume this is debugging and jiggle the number of GC threads.
-    if (new_active_workers == prev_active_workers) {
-      if (new_active_workers < total_workers) {
-        new_active_workers++;
-      } else if (new_active_workers > min_workers) {
-        new_active_workers--;
-      }
-    }
-    if (new_active_workers == total_workers) {
-      if (_debug_perturbation) {
-        new_active_workers =  min_workers;
-      }
-      _debug_perturbation = !_debug_perturbation;
-    }
-    assert((new_active_workers <= ParallelGCThreads) &&
-           (new_active_workers >= min_workers),
-      "Jiggled active workers too much");
-  }
-
-  log_trace(gc, task)("GCTaskManager::calc_default_active_workers() : "
-     "active_workers(): " UINTX_FORMAT "  new_active_workers: " UINTX_FORMAT "  "
-     "prev_active_workers: " UINTX_FORMAT "\n"
-     " active_workers_by_JT: " UINTX_FORMAT "  active_workers_by_heap_size: " UINTX_FORMAT,
-     active_workers, new_active_workers, prev_active_workers,
-     active_workers_by_JT, active_workers_by_heap_size);
-  assert(new_active_workers > 0, "Always need at least 1");
-  return new_active_workers;
-}
-
-uint AdaptiveSizePolicy::calc_active_workers(uintx total_workers,
-                                             uintx active_workers,
-                                             uintx application_workers) {
-  // If the user has specifically set the number of
-  // GC threads, use them.
-
-  // If the user has turned off using a dynamic number of GC threads
-  // or the users has requested a specific number, set the active
-  // number of workers to all the workers.
-
-  uint new_active_workers;
-  if (!UseDynamicNumberOfGCThreads ||
-     (!FLAG_IS_DEFAULT(ParallelGCThreads) && !ForceDynamicNumberOfGCThreads)) {
-    new_active_workers = total_workers;
-  } else {
-    uintx min_workers = (total_workers == 1) ? 1 : 2;
-    new_active_workers = calc_default_active_workers(total_workers,
-                                                     min_workers,
-                                                     active_workers,
-                                                     application_workers);
-  }
-  assert(new_active_workers > 0, "Always need at least 1");
-  return new_active_workers;
-}
-
-uint AdaptiveSizePolicy::calc_active_conc_workers(uintx total_workers,
-                                                  uintx active_workers,
-                                                  uintx application_workers) {
-  if (!UseDynamicNumberOfGCThreads ||
-     (!FLAG_IS_DEFAULT(ConcGCThreads) && !ForceDynamicNumberOfGCThreads)) {
-    return ConcGCThreads;
-  } else {
-    uint no_of_gc_threads = calc_default_active_workers(total_workers,
-                                                        1, /* Minimum number of workers */
-                                                        active_workers,
-                                                        application_workers);
-    return no_of_gc_threads;
-  }
-}
-
 bool AdaptiveSizePolicy::tenuring_threshold_change() const {
   return decrement_tenuring_threshold_for_gc_cost() ||
          increment_tenuring_threshold_for_gc_cost() ||
--- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -25,12 +25,9 @@
 #ifndef SHARE_VM_GC_SHARED_ADAPTIVESIZEPOLICY_HPP
 #define SHARE_VM_GC_SHARED_ADAPTIVESIZEPOLICY_HPP
 
-#include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/gcUtil.hpp"
-#include "logging/log.hpp"
 #include "memory/allocation.hpp"
-#include "memory/universe.hpp"
 
 // This class keeps statistical information and computes the
 // size of the heap.
@@ -188,8 +185,6 @@
   julong _young_gen_change_for_minor_throughput;
   julong _old_gen_change_for_major_throughput;
 
-  static const uint GCWorkersPerJavaThread  = 2;
-
   // Accessors
 
   double gc_pause_goal_sec() const { return _gc_pause_goal_sec; }
@@ -334,8 +329,6 @@
   // Return true if the policy suggested a change.
   bool tenuring_threshold_change() const;
 
-  static bool _debug_perturbation;
-
  public:
   AdaptiveSizePolicy(size_t init_eden_size,
                      size_t init_promo_size,
@@ -343,32 +336,6 @@
                      double gc_pause_goal_sec,
                      uint gc_cost_ratio);
 
-  // Return number default  GC threads to use in the next GC.
-  static uint calc_default_active_workers(uintx total_workers,
-                                          const uintx min_workers,
-                                          uintx active_workers,
-                                          uintx application_workers);
-
-  // Return number of GC threads to use in the next GC.
-  // This is called sparingly so as not to change the
-  // number of GC workers gratuitously.
-  //   For ParNew collections
-  //   For PS scavenge and ParOld collections
-  //   For G1 evacuation pauses (subject to update)
-  //   For G1 Full GCs (subject to update)
-  // Other collection phases inherit the number of
-  // GC workers from the calls above.  For example,
-  // a CMS parallel remark uses the same number of GC
-  // workers as the most recent ParNew collection.
-  static uint calc_active_workers(uintx total_workers,
-                                  uintx active_workers,
-                                  uintx application_workers);
-
-  // Return number of GC threads to use in the next concurrent GC phase.
-  static uint calc_active_conc_workers(uintx total_workers,
-                                       uintx active_workers,
-                                       uintx application_workers);
-
   bool is_gc_cms_adaptive_size_policy() {
     return kind() == _gc_cms_adaptive_size_policy;
   }
--- a/src/hotspot/share/gc/shared/gc_globals.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/shared/gc_globals.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -348,6 +348,10 @@
   develop(uintx, PromotionFailureALotInterval, 5,                           \
           "Total collections between promotion failures a lot")             \
                                                                             \
+  diagnostic(bool, UseOWSTTaskTerminator, true,                             \
+          "Use Optimized Work Stealing Threads task termination "           \
+          "protocol")                                                       \
+                                                                            \
   experimental(uintx, WorkStealingSleepMillis, 1,                           \
           "Sleep time when sleep is used for yields")                       \
                                                                             \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/owstTaskTerminator.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#include "gc/shared/owstTaskTerminator.hpp"
+#include "logging/log.hpp"
+
+bool OWSTTaskTerminator::exit_termination(size_t tasks, TerminatorTerminator* terminator) {
+  return tasks > 0 || (terminator != NULL && terminator->should_exit_termination());
+}
+
+bool OWSTTaskTerminator::offer_termination(TerminatorTerminator* terminator) {
+  assert(_n_threads > 0, "Initialization is incorrect");
+  assert(_offered_termination < _n_threads, "Invariant");
+  assert(_blocker != NULL, "Invariant");
+
+  // Single worker, done
+  if (_n_threads == 1) {
+    _offered_termination = 1;
+    return true;
+  }
+
+  _blocker->lock_without_safepoint_check();
+  // All arrived, done
+  _offered_termination++;
+  if (_offered_termination == _n_threads) {
+    _blocker->notify_all();
+    _blocker->unlock();
+    return true;
+  }
+
+  Thread* the_thread = Thread::current();
+  while (true) {
+    if (_spin_master == NULL) {
+      _spin_master = the_thread;
+
+      _blocker->unlock();
+
+      if (do_spin_master_work(terminator)) {
+        assert(_offered_termination == _n_threads, "termination condition");
+        return true;
+      } else {
+        _blocker->lock_without_safepoint_check();
+      }
+    } else {
+      _blocker->wait(true, WorkStealingSleepMillis);
+
+      if (_offered_termination == _n_threads) {
+        _blocker->unlock();
+        return true;
+      }
+    }
+
+    size_t tasks = tasks_in_queue_set();
+    if (exit_termination(tasks, terminator)) {
+      _offered_termination--;
+      _blocker->unlock();
+      return false;
+    }
+  }
+}
+
+bool OWSTTaskTerminator::do_spin_master_work(TerminatorTerminator* terminator) {
+  uint yield_count = 0;
+  // Number of hard spin loops done since last yield
+  uint hard_spin_count = 0;
+  // Number of iterations in the hard spin loop.
+  uint hard_spin_limit = WorkStealingHardSpins;
+
+  // If WorkStealingSpinToYieldRatio is 0, no hard spinning is done.
+  // If it is greater than 0, then start with a small number
+  // of spins and increase number with each turn at spinning until
+  // the count of hard spins exceeds WorkStealingSpinToYieldRatio.
+  // Then do a yield() call and start spinning afresh.
+  if (WorkStealingSpinToYieldRatio > 0) {
+    hard_spin_limit = WorkStealingHardSpins >> WorkStealingSpinToYieldRatio;
+    hard_spin_limit = MAX2(hard_spin_limit, 1U);
+  }
+  // Remember the initial spin limit.
+  uint hard_spin_start = hard_spin_limit;
+
+  // Loop waiting for all threads to offer termination or
+  // more work.
+  while (true) {
+    // Look for more work.
+    // Periodically sleep() instead of yield() to give threads
+    // waiting on the cores the chance to grab this code
+    if (yield_count <= WorkStealingYieldsBeforeSleep) {
+      // Do a yield or hardspin.  For purposes of deciding whether
+      // to sleep, count this as a yield.
+      yield_count++;
+
+      // Periodically call yield() instead spinning
+      // After WorkStealingSpinToYieldRatio spins, do a yield() call
+      // and reset the counts and starting limit.
+      if (hard_spin_count > WorkStealingSpinToYieldRatio) {
+        yield();
+        hard_spin_count = 0;
+        hard_spin_limit = hard_spin_start;
+#ifdef TRACESPINNING
+        _total_yields++;
+#endif
+      } else {
+        // Hard spin this time
+        // Increase the hard spinning period but only up to a limit.
+        hard_spin_limit = MIN2(2*hard_spin_limit,
+                               (uint) WorkStealingHardSpins);
+        for (uint j = 0; j < hard_spin_limit; j++) {
+          SpinPause();
+        }
+        hard_spin_count++;
+#ifdef TRACESPINNING
+        _total_spins++;
+#endif
+      }
+    } else {
+      log_develop_trace(gc, task)("OWSTTaskTerminator::do_spin_master_work() thread " PTR_FORMAT " sleeps after %u yields",
+                                  p2i(Thread::current()), yield_count);
+      yield_count = 0;
+
+      MonitorLockerEx locker(_blocker, Mutex::_no_safepoint_check_flag);
+      _spin_master = NULL;
+      locker.wait(Mutex::_no_safepoint_check_flag, WorkStealingSleepMillis);
+      if (_spin_master == NULL) {
+        _spin_master = Thread::current();
+      } else {
+        return false;
+      }
+    }
+
+#ifdef TRACESPINNING
+      _total_peeks++;
+#endif
+    size_t tasks = tasks_in_queue_set();
+    if (exit_termination(tasks, terminator)) {
+      MonitorLockerEx locker(_blocker, Mutex::_no_safepoint_check_flag);
+      if (tasks >= _offered_termination - 1) {
+        locker.notify_all();
+      } else {
+        for (; tasks > 1; tasks--) {
+          locker.notify();
+        }
+      }
+      _spin_master = NULL;
+      return false;
+    } else if (_offered_termination == _n_threads) {
+      return true;
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/owstTaskTerminator.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef SHARE_VM_GC_SHARED_OWSTTASKTERMINATOR_HPP
+#define SHARE_VM_GC_SHARED_OWSTTASKTERMINATOR_HPP
+
+#include "gc/shared/taskqueue.hpp"
+#include "runtime/mutex.hpp"
+#include "runtime/thread.hpp"
+
+/*
+ * OWST stands for Optimized Work Stealing Threads
+ *
+ * This is an enhanced implementation of Google's work stealing
+ * protocol, which is described in the paper:
+ * "Wessam Hassanein. 2016. Understanding and improving JVM GC work
+ * stealing at the data center scale. In Proceedings of the 2016 ACM
+ * SIGPLAN International Symposium on Memory Management (ISMM 2016). ACM,
+ * New York, NY, USA, 46-54. DOI: https://doi.org/10.1145/2926697.2926706"
+ *
+ * Instead of a dedicated spin-master, our implementation will let spin-master relinquish
+ * the role before it goes to sleep/wait, allowing newly arrived threads to compete for the role.
+ * The intention of above enhancement is to reduce spin-master's latency on detecting new tasks
+ * for stealing and termination condition.
+ */
+
+class OWSTTaskTerminator: public ParallelTaskTerminator {
+private:
+  Monitor*    _blocker;
+  Thread*     _spin_master;
+
+public:
+  OWSTTaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set) :
+    ParallelTaskTerminator(n_threads, queue_set), _spin_master(NULL) {
+    _blocker = new Monitor(Mutex::leaf, "OWSTTaskTerminator", false, Monitor::_safepoint_check_never);
+  }
+
+  virtual ~OWSTTaskTerminator() {
+    assert(_blocker != NULL, "Can not be NULL");
+    delete _blocker;
+  }
+
+  bool offer_termination(TerminatorTerminator* terminator);
+
+protected:
+  // If should exit current termination protocol
+  virtual bool exit_termination(size_t tasks, TerminatorTerminator* terminator);
+
+private:
+  size_t tasks_in_queue_set() { return _queue_set->tasks(); }
+
+  /*
+   * Perform spin-master task.
+   * Return true if termination condition is detected, otherwise return false
+   */
+  bool do_spin_master_work(TerminatorTerminator* terminator);
+};
+
+
+#endif // SHARE_VM_GC_SHARED_OWSTTASKTERMINATOR_HPP
--- a/src/hotspot/share/gc/shared/taskqueue.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/shared/taskqueue.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/shared/taskqueue.hpp"
+#include "gc/shared/owstTaskTerminator.hpp"
 #include "oops/oop.inline.hpp"
 #include "logging/log.hpp"
 #include "runtime/atomic.hpp"
@@ -247,3 +248,25 @@
   reset_for_reuse();
   _n_threads = n_threads;
 }
+
+TaskTerminator::TaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set) :
+  _terminator(UseOWSTTaskTerminator ? new OWSTTaskTerminator(n_threads, queue_set)
+                                    : new ParallelTaskTerminator(n_threads, queue_set)) {
+}
+
+TaskTerminator::~TaskTerminator() {
+  if (_terminator != NULL) {
+    delete _terminator;
+  }
+}
+
+// Move assignment
+TaskTerminator& TaskTerminator::operator=(const TaskTerminator& o) {
+  if (_terminator != NULL) {
+    delete _terminator;
+  }
+  _terminator = o.terminator();
+  const_cast<TaskTerminator&>(o)._terminator = NULL;
+  return *this;
+}
+
--- a/src/hotspot/share/gc/shared/taskqueue.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/shared/taskqueue.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -447,8 +447,8 @@
 
 #undef TRACESPINNING
 
-class ParallelTaskTerminator: public StackObj {
-private:
+class ParallelTaskTerminator: public CHeapObj<mtGC> {
+protected:
   uint _n_threads;
   TaskQueueSetSuper* _queue_set;
   volatile uint _offered_termination;
@@ -481,7 +481,7 @@
   // As above, but it also terminates if the should_exit_termination()
   // method of the terminator parameter returns true. If terminator is
   // NULL, then it is ignored.
-  bool offer_termination(TerminatorTerminator* terminator);
+  virtual bool offer_termination(TerminatorTerminator* terminator);
 
   // Reset the terminator, so that it may be reused again.
   // The caller is responsible for ensuring that this is done
@@ -500,6 +500,38 @@
 #endif
 };
 
+#ifdef _MSC_VER
+#pragma warning(push)
+// warning C4521: multiple copy constructors specified
+#pragma warning(disable:4521)
+// warning C4522: multiple assignment operators specified
+#pragma warning(disable:4522)
+#endif
+
+class TaskTerminator : public StackObj {
+private:
+  ParallelTaskTerminator*  _terminator;
+
+  // Disable following copy constructors and assignment operator
+  TaskTerminator(TaskTerminator& o) { }
+  TaskTerminator(const TaskTerminator& o) { }
+  TaskTerminator& operator=(TaskTerminator& o) { return *this; }
+public:
+  TaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set);
+  ~TaskTerminator();
+
+  // Move assignment
+  TaskTerminator& operator=(const TaskTerminator& o);
+
+  ParallelTaskTerminator* terminator() const {
+    return _terminator;
+  }
+};
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+
 typedef GenericTaskQueue<oop, mtGC>             OopTaskQueue;
 typedef GenericTaskQueueSet<OopTaskQueue, mtGC> OopTaskQueueSet;
 
--- a/src/hotspot/share/gc/shared/workerManager.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/gc/shared/workerManager.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, 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
@@ -25,7 +25,11 @@
 #ifndef SHARE_VM_GC_SHARED_WORKERMANAGER_HPP
 #define SHARE_VM_GC_SHARED_WORKERMANAGER_HPP
 
-#include "gc/shared/adaptiveSizePolicy.hpp"
+#include "logging/log.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/os.inline.hpp"
+#include "runtime/thread.inline.hpp"
+#include "utilities/globalDefinitions.hpp"
 
 class WorkerManager : public AllStatic {
  public:
@@ -51,35 +55,7 @@
                            uint total_workers,
                            uint created_workers,
                            os::ThreadType worker_type,
-                           bool initializing) {
-    uint start = created_workers;
-    uint end = MIN2(active_workers, total_workers);
-    for (uint worker_id = start; worker_id < end; worker_id += 1) {
-      WorkerThread* new_worker = NULL;
-      if (initializing || !InjectGCWorkerCreationFailure) {
-        new_worker = holder->install_worker(worker_id);
-      }
-      if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) {
-        log_trace(gc, task)("WorkerManager::add_workers() : "
-                            "creation failed due to failed allocation of native %s",
-                            new_worker == NULL ?  "memory" : "thread");
-        if (new_worker != NULL) {
-           delete new_worker;
-        }
-        if (initializing) {
-          vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create worker GC thread. Out of system resources.");
-        }
-        break;
-      }
-      created_workers++;
-      os::start_thread(new_worker);
-    }
-
-    log_trace(gc, task)("WorkerManager::add_workers() : "
-                        "created_workers: %u", created_workers);
-
-    return created_workers;
-  }
+                           bool initializing);
 
   // Log (at trace level) a change in the number of created workers.
   template <class WorkerType>
@@ -87,12 +63,56 @@
                                   uint previous_created_workers,
                                   uint active_workers,
                                   uint created_workers,
-                                  bool initializing) {
-    if (previous_created_workers < created_workers) {
-      const char* initializing_msg =  initializing ? "Adding initial" : "Creating additional";
-      log_trace(gc, task)("%s %s(s) previously created workers %u active workers %u total created workers %u",
-                          initializing_msg, holder->group_name(), previous_created_workers, active_workers, created_workers);
+                                  bool initializing);
+};
+
+template <class WorkerType>
+uint WorkerManager::add_workers(WorkerType* holder,
+                                uint active_workers,
+                                uint total_workers,
+                                uint created_workers,
+                                os::ThreadType worker_type,
+                                bool initializing) {
+  uint start = created_workers;
+  uint end = MIN2(active_workers, total_workers);
+  for (uint worker_id = start; worker_id < end; worker_id += 1) {
+    WorkerThread* new_worker = NULL;
+    if (initializing || !InjectGCWorkerCreationFailure) {
+      new_worker = holder->install_worker(worker_id);
     }
+    if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) {
+      log_trace(gc, task)("WorkerManager::add_workers() : "
+                          "creation failed due to failed allocation of native %s",
+                          new_worker == NULL ? "memory" : "thread");
+      if (new_worker != NULL) {
+        delete new_worker;
+      }
+      if (initializing) {
+        vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create worker GC thread. Out of system resources.");
+      }
+      break;
+    }
+    created_workers++;
+    os::start_thread(new_worker);
   }
-};
+
+  log_trace(gc, task)("WorkerManager::add_workers() : "
+                      "created_workers: %u", created_workers);
+
+  return created_workers;
+}
+
+template <class WorkerType>
+void WorkerManager::log_worker_creation(WorkerType* holder,
+                                        uint previous_created_workers,
+                                        uint active_workers,
+                                        uint created_workers,
+                                        bool initializing) {
+  if (previous_created_workers < created_workers) {
+    const char* initializing_msg = initializing ? "Adding initial" : "Creating additional";
+    log_trace(gc, task)("%s %s(s) previously created workers %u active workers %u total created workers %u",
+                        initializing_msg, holder->group_name(), previous_created_workers, active_workers, created_workers);
+  }
+}
+
 #endif // SHARE_VM_GC_SHARED_WORKERMANAGER_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/workerPolicy.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2018, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "gc/shared/workerPolicy.hpp"
+#include "logging/log.hpp"
+#include "memory/universe.hpp"
+#include "runtime/os.inline.hpp"
+#include "runtime/vm_version.hpp"
+
+bool WorkerPolicy::_debug_perturbation = false;
+uint WorkerPolicy::_parallel_worker_threads = 0;
+bool WorkerPolicy::_parallel_worker_threads_initialized = false;
+
+uint WorkerPolicy::nof_parallel_worker_threads(uint num,
+                                               uint den,
+                                               uint switch_pt) {
+  if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
+    assert(ParallelGCThreads == 0, "Default ParallelGCThreads is not 0");
+    uint threads;
+    // For very large machines, there are diminishing returns
+    // for large numbers of worker threads.  Instead of
+    // hogging the whole system, use a fraction of the workers for every
+    // processor after the first 8.  For example, on a 72 cpu machine
+    // and a chosen fraction of 5/8
+    // use 8 + (72 - 8) * (5/8) == 48 worker threads.
+    uint ncpus = (uint) os::initial_active_processor_count();
+    threads = (ncpus <= switch_pt) ?
+              ncpus :
+              (switch_pt + ((ncpus - switch_pt) * num) / den);
+#ifndef _LP64
+    // On 32-bit binaries the virtual address space available to the JVM
+    // is usually limited to 2-3 GB (depends on the platform).
+    // Do not use up address space with too many threads (stacks and per-thread
+    // data). Note that x86 apps running on Win64 have 2 stacks per thread.
+    // GC may more generally scale down threads by max heap size (etc), but the
+    // consequences of over-provisioning threads are higher on 32-bit JVMS,
+    // so add hard limit here:
+    threads = MIN2(threads, (2 * switch_pt));
+#endif
+    return threads;
+  } else {
+    return ParallelGCThreads;
+  }
+}
+
+uint WorkerPolicy::calc_parallel_worker_threads() {
+  uint den = VM_Version::parallel_worker_threads_denominator();
+  return nof_parallel_worker_threads(5, den, 8);
+}
+
+uint WorkerPolicy::parallel_worker_threads() {
+  if (!_parallel_worker_threads_initialized) {
+    if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
+      _parallel_worker_threads = WorkerPolicy::calc_parallel_worker_threads();
+    } else {
+      _parallel_worker_threads = ParallelGCThreads;
+    }
+    _parallel_worker_threads_initialized = true;
+  }
+  return _parallel_worker_threads;
+}
+
+//  If the number of GC threads was set on the command line, use it.
+//  Else
+//    Calculate the number of GC threads based on the number of Java threads.
+//    Calculate the number of GC threads based on the size of the heap.
+//    Use the larger.
+uint WorkerPolicy::calc_default_active_workers(uintx total_workers,
+                                               const uintx min_workers,
+                                               uintx active_workers,
+                                               uintx application_workers) {
+  // If the user has specifically set the number of GC threads, use them.
+
+  // If the user has turned off using a dynamic number of GC threads
+  // or the users has requested a specific number, set the active
+  // number of workers to all the workers.
+
+  uintx new_active_workers = total_workers;
+  uintx prev_active_workers = active_workers;
+  uintx active_workers_by_JT = 0;
+  uintx active_workers_by_heap_size = 0;
+
+  // Always use at least min_workers but use up to
+  // GCThreadsPerJavaThreads * application threads.
+  active_workers_by_JT =
+    MAX2((uintx) GCWorkersPerJavaThread * application_workers,
+         min_workers);
+
+  // Choose a number of GC threads based on the current size
+  // of the heap.  This may be complicated because the size of
+  // the heap depends on factors such as the throughput goal.
+  // Still a large heap should be collected by more GC threads.
+  active_workers_by_heap_size =
+    MAX2((size_t) 2U, Universe::heap()->capacity() / HeapSizePerGCThread);
+
+  uintx max_active_workers =
+    MAX2(active_workers_by_JT, active_workers_by_heap_size);
+
+  new_active_workers = MIN2(max_active_workers, (uintx) total_workers);
+
+  // Increase GC workers instantly but decrease them more
+  // slowly.
+  if (new_active_workers < prev_active_workers) {
+    new_active_workers =
+      MAX2(min_workers, (prev_active_workers + new_active_workers) / 2);
+  }
+
+  // Check once more that the number of workers is within the limits.
+  assert(min_workers <= total_workers, "Minimum workers not consistent with total workers");
+  assert(new_active_workers >= min_workers, "Minimum workers not observed");
+  assert(new_active_workers <= total_workers, "Total workers not observed");
+
+  if (ForceDynamicNumberOfGCThreads) {
+    // Assume this is debugging and jiggle the number of GC threads.
+    if (new_active_workers == prev_active_workers) {
+      if (new_active_workers < total_workers) {
+        new_active_workers++;
+      } else if (new_active_workers > min_workers) {
+        new_active_workers--;
+      }
+    }
+    if (new_active_workers == total_workers) {
+      if (_debug_perturbation) {
+        new_active_workers =  min_workers;
+      }
+      _debug_perturbation = !_debug_perturbation;
+    }
+    assert((new_active_workers <= ParallelGCThreads) &&
+           (new_active_workers >= min_workers),
+           "Jiggled active workers too much");
+  }
+
+  log_trace(gc, task)("WorkerPolicy::calc_default_active_workers() : "
+    "active_workers(): " UINTX_FORMAT "  new_active_workers: " UINTX_FORMAT "  "
+    "prev_active_workers: " UINTX_FORMAT "\n"
+    " active_workers_by_JT: " UINTX_FORMAT "  active_workers_by_heap_size: " UINTX_FORMAT,
+    active_workers, new_active_workers, prev_active_workers,
+    active_workers_by_JT, active_workers_by_heap_size);
+  assert(new_active_workers > 0, "Always need at least 1");
+  return new_active_workers;
+}
+
+uint WorkerPolicy::calc_active_workers(uintx total_workers,
+                                       uintx active_workers,
+                                       uintx application_workers) {
+  // If the user has specifically set the number of GC threads, use them.
+
+  // If the user has turned off using a dynamic number of GC threads
+  // or the users has requested a specific number, set the active
+  // number of workers to all the workers.
+
+  uint new_active_workers;
+  if (!UseDynamicNumberOfGCThreads ||
+     (!FLAG_IS_DEFAULT(ParallelGCThreads) && !ForceDynamicNumberOfGCThreads)) {
+    new_active_workers = total_workers;
+  } else {
+    uintx min_workers = (total_workers == 1) ? 1 : 2;
+    new_active_workers = calc_default_active_workers(total_workers,
+                                                     min_workers,
+                                                     active_workers,
+                                                     application_workers);
+  }
+  assert(new_active_workers > 0, "Always need at least 1");
+  return new_active_workers;
+}
+
+uint WorkerPolicy::calc_active_conc_workers(uintx total_workers,
+                                            uintx active_workers,
+                                            uintx application_workers) {
+  if (!UseDynamicNumberOfGCThreads ||
+     (!FLAG_IS_DEFAULT(ConcGCThreads) && !ForceDynamicNumberOfGCThreads)) {
+    return ConcGCThreads;
+  } else {
+    uint no_of_gc_threads = calc_default_active_workers(total_workers,
+                                                        1, /* Minimum number of workers */
+                                                        active_workers,
+                                                        application_workers);
+    return no_of_gc_threads;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/workerPolicy.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2018, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_WORKERPOLICY_HPP
+#define SHARE_VM_GC_SHARED_WORKERPOLICY_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class WorkerPolicy : public AllStatic {
+  static const uint GCWorkersPerJavaThread = 2;
+
+  static bool _debug_perturbation;
+  static uint _parallel_worker_threads;
+  static bool _parallel_worker_threads_initialized;
+
+  static uint nof_parallel_worker_threads(uint num,
+                                          uint den,
+                                          uint switch_pt);
+
+  // Calculates and returns the number of parallel GC threads. May
+  // be CPU-architecture-specific.
+  static uint calc_parallel_worker_threads();
+
+public:
+  // Returns the number of parallel threads to be used as default value of
+  // ParallelGCThreads. If that number has not been calculated, do so and
+  // save it.  Returns ParallelGCThreads if it is set on the
+  // command line.
+  static uint parallel_worker_threads();
+
+  // Return number default GC threads to use in the next GC.
+  static uint calc_default_active_workers(uintx total_workers,
+                                          const uintx min_workers,
+                                          uintx active_workers,
+                                          uintx application_workers);
+
+  // Return number of GC threads to use in the next GC.
+  // This is called sparingly so as not to change the
+  // number of GC workers gratuitously.
+  //   For ParNew collections
+  //   For PS scavenge and ParOld collections
+  //   For G1 evacuation pauses (subject to update)
+  //   For G1 Full GCs (subject to update)
+  // Other collection phases inherit the number of
+  // GC workers from the calls above.  For example,
+  // a CMS parallel remark uses the same number of GC
+  // workers as the most recent ParNew collection.
+  static uint calc_active_workers(uintx total_workers,
+                                  uintx active_workers,
+                                  uintx application_workers);
+
+  // Return number of GC threads to use in the next concurrent GC phase.
+  static uint calc_active_conc_workers(uintx total_workers,
+                                       uintx active_workers,
+                                       uintx application_workers);
+
+};
+
+#endif // SHARE_VM_GC_SHARED_WORKERPOLICY_HPP
--- a/src/hotspot/share/interpreter/templateInterpreter.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/interpreter/templateInterpreter.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -111,9 +111,7 @@
   static address    _throw_StackOverflowError_entry;
 
   static address    _remove_activation_entry;                   // continuation address if an exception is not handled by current frame
-#ifdef HOTSWAP
   static address    _remove_activation_preserving_args_entry;   // continuation address when current frame is being popped
-#endif // HOTSWAP
 
 #ifndef PRODUCT
   static EntryPoint _trace_code;
@@ -146,9 +144,7 @@
  public:
 
   static address    remove_activation_early_entry(TosState state) { return _earlyret_entry.entry(state); }
-#ifdef HOTSWAP
-  static address    remove_activation_preserving_args_entry()   { return _remove_activation_preserving_args_entry; }
-#endif // HOTSWAP
+  static address    remove_activation_preserving_args_entry()     { return _remove_activation_preserving_args_entry; }
 
   static address    remove_activation_entry()                   { return _remove_activation_entry; }
   static address    throw_exception_entry()                     { return _throw_exception_entry; }
--- a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -30,7 +30,6 @@
 
 class frame;
 class JavaThread;
-class JfrCheckpointSystem;
 class JfrCheckpointWriter;
 class JfrChunkWriter;
 class Method;
@@ -55,7 +54,7 @@
   JfrStackFrame(const traceid& id, int bci, int type, const Method* method) :
     _method(method), _methodid(id), _line(0), _bci(bci), _type(type) {}
   JfrStackFrame(const traceid& id, int bci, int type, int lineno) :
-    _method(NULL), _methodid(id), _line(0), _bci(bci), _type(type) {}
+    _method(NULL), _methodid(id), _line(lineno), _bci(bci), _type(type) {}
   bool equals(const JfrStackFrame& rhs) const;
   void write(JfrChunkWriter& cw) const;
   void write(JfrCheckpointWriter& cpw) const;
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -49,14 +49,14 @@
   _thread = thread;
   _klass = klass;
   if (klass != NULL) {
-    _holder = Handle(_thread, klass->holder_phantom());
+    _holder = Handle(_thread, klass->klass_holder());
   }
 }
 
 JVMCIKlassHandle& JVMCIKlassHandle::operator=(Klass* klass) {
   _klass = klass;
   if (klass != NULL) {
-    _holder = Handle(_thread, klass->holder_phantom());
+    _holder = Handle(_thread, klass->klass_holder());
   }
   return *this;
 }
--- a/src/hotspot/share/oops/instanceKlass.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/oops/instanceKlass.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -678,12 +678,6 @@
     }
   }
 
-  // Oop that keeps the metadata for this class from being unloaded
-  // in places where the metadata is stored in other places, like nmethods
-  oop klass_holder() const {
-    return (is_unsafe_anonymous()) ? java_mirror() : class_loader();
-  }
-
   bool is_contended() const                {
     return (_misc_flags & _misc_is_contended) != 0;
   }
--- a/src/hotspot/share/oops/klass.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/oops/klass.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -467,10 +467,6 @@
   }
 }
 
-oop Klass::holder_phantom() const {
-  return class_loader_data()->holder_phantom();
-}
-
 void Klass::clean_weak_klass_links(bool unloading_occurred, bool clean_alive_klasses) {
   if (!ClassUnloading || !unloading_occurred) {
     return;
--- a/src/hotspot/share/oops/klass.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/oops/klass.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -500,7 +500,11 @@
 
   oop class_loader() const;
 
-  virtual oop klass_holder() const      { return class_loader(); }
+  // This loads the klass's holder as a phantom. This is useful when a weak Klass
+  // pointer has been "peeked" and then must be kept alive before it may
+  // be used safely.  All uses of klass_holder need to apply the appropriate barriers,
+  // except during GC.
+  oop klass_holder() const { return class_loader_data()->holder_phantom(); }
 
  protected:
   virtual Klass* array_klass_impl(bool or_null, int rank, TRAPS);
@@ -655,11 +659,6 @@
   // unloading, and hence during concurrent class unloading.
   bool is_loader_alive() const { return class_loader_data()->is_alive(); }
 
-  // Load the klass's holder as a phantom. This is useful when a weak Klass
-  // pointer has been "peeked" and then must be kept alive before it may
-  // be used safely.
-  oop holder_phantom() const;
-
   void clean_subklass();
 
   static void clean_weak_klass_links(bool unloading_occurred, bool clean_alive_klasses = true);
--- a/src/hotspot/share/opto/output.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/opto/output.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -1704,7 +1704,9 @@
   _current_latency = NEW_ARENA_ARRAY(arena, unsigned short, node_max);
 
   // Clear the arrays
-  memset(_node_bundling_base, 0, node_max * sizeof(Bundle));
+  for (uint i = 0; i < node_max; i++) {
+    ::new (&_node_bundling_base[i]) Bundle();
+  }
   memset(_node_latency,       0, node_max * sizeof(unsigned short));
   memset(_uses,               0, node_max * sizeof(short));
   memset(_current_latency,    0, node_max * sizeof(unsigned short));
--- a/src/hotspot/share/runtime/vm_version.cpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/runtime/vm_version.cpp	Fri Dec 07 21:07:26 2018 -0500
@@ -81,8 +81,6 @@
 int Abstract_VM_Version::_vm_security_version = VERSION_UPDATE;
 int Abstract_VM_Version::_vm_patch_version = VERSION_PATCH;
 int Abstract_VM_Version::_vm_build_number = VERSION_BUILD;
-unsigned int Abstract_VM_Version::_parallel_worker_threads = 0;
-bool Abstract_VM_Version::_parallel_worker_threads_initialized = false;
 
 #if defined(_LP64)
   #define VMLP "64-Bit "
@@ -312,55 +310,3 @@
     os::print_cpu_info(&ls, buf, sizeof(buf));
   }
 }
-
-unsigned int Abstract_VM_Version::nof_parallel_worker_threads(
-                                                      unsigned int num,
-                                                      unsigned int den,
-                                                      unsigned int switch_pt) {
-  if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
-    assert(ParallelGCThreads == 0, "Default ParallelGCThreads is not 0");
-    unsigned int threads;
-    // For very large machines, there are diminishing returns
-    // for large numbers of worker threads.  Instead of
-    // hogging the whole system, use a fraction of the workers for every
-    // processor after the first 8.  For example, on a 72 cpu machine
-    // and a chosen fraction of 5/8
-    // use 8 + (72 - 8) * (5/8) == 48 worker threads.
-    unsigned int ncpus = (unsigned int) os::initial_active_processor_count();
-    threads = (ncpus <= switch_pt) ?
-             ncpus :
-             (switch_pt + ((ncpus - switch_pt) * num) / den);
-#ifndef _LP64
-    // On 32-bit binaries the virtual address space available to the JVM
-    // is usually limited to 2-3 GB (depends on the platform).
-    // Do not use up address space with too many threads (stacks and per-thread
-    // data). Note that x86 apps running on Win64 have 2 stacks per thread.
-    // GC may more generally scale down threads by max heap size (etc), but the
-    // consequences of over-provisioning threads are higher on 32-bit JVMS,
-    // so add hard limit here:
-    threads = MIN2(threads, (2*switch_pt));
-#endif
-    return threads;
-  } else {
-    return ParallelGCThreads;
-  }
-}
-
-unsigned int Abstract_VM_Version::calc_parallel_worker_threads() {
-  return nof_parallel_worker_threads(5, 8, 8);
-}
-
-
-// Does not set the _initialized flag since it is
-// a global flag.
-unsigned int Abstract_VM_Version::parallel_worker_threads() {
-  if (!_parallel_worker_threads_initialized) {
-    if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
-      _parallel_worker_threads = VM_Version::calc_parallel_worker_threads();
-    } else {
-      _parallel_worker_threads = ParallelGCThreads;
-    }
-    _parallel_worker_threads_initialized = true;
-  }
-  return _parallel_worker_threads;
-}
--- a/src/hotspot/share/runtime/vm_version.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/runtime/vm_version.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -56,12 +56,7 @@
   static int          _vm_security_version;
   static int          _vm_patch_version;
   static int          _vm_build_number;
-  static unsigned int _parallel_worker_threads;
-  static bool         _parallel_worker_threads_initialized;
 
-  static unsigned int nof_parallel_worker_threads(unsigned int num,
-                                                  unsigned int dem,
-                                                  unsigned int switch_pt);
  public:
   // Called as part of the runtime services initialization which is
   // called from the management module initialization (via init_globals())
@@ -153,9 +148,10 @@
   // save it.  Returns ParallelGCThreads if it is set on the
   // command line.
   static unsigned int parallel_worker_threads();
-  // Calculates and returns the number of parallel threads.  May
-  // be VM version specific.
-  static unsigned int calc_parallel_worker_threads();
+
+  // Denominator for computing default ParallelGCThreads for machines with
+  // a large number of cores.
+  static uint parallel_worker_threads_denominator() { return 8; }
 
   // Does this CPU support spin wait instruction?
   static bool supports_on_spin_wait() { return false; }
--- a/src/hotspot/share/utilities/globalDefinitions.hpp	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/hotspot/share/utilities/globalDefinitions.hpp	Fri Dec 07 21:07:26 2018 -0500
@@ -422,14 +422,6 @@
 const size_t defaultSymbolTableSize = 32768; // 2^15
 const size_t minimumSymbolTableSize = 1024;
 
-
-//----------------------------------------------------------------------------------------------------
-// HotSwap - for JVMTI   aka Class File Replacement and PopFrame
-//
-// Determines whether on-the-fly class replacement and frame popping are enabled.
-
-#define HOTSWAP
-
 //----------------------------------------------------------------------------------------------------
 // Object alignment, in units of HeapWords.
 //
--- a/src/java.base/share/classes/com/sun/java/util/jar/pack/ConstantPool.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/com/sun/java/util/jar/pack/ConstantPool.java	Fri Dec 07 21:07:26 2018 -0500
@@ -1366,7 +1366,7 @@
             }
             if (tag == CONSTANT_Utf8) {
                 // Special case:  First Utf8 must always be empty string.
-                assert(cpMap.length == 0 || cpMap[0].stringValue().equals(""));
+                assert(cpMap.length == 0 || cpMap[0].stringValue().isEmpty());
             }
             indexByTag[tag] = ix;
             // decache indexes derived from this one:
--- a/src/java.base/share/classes/com/sun/java/util/jar/pack/Driver.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/com/sun/java/util/jar/pack/Driver.java	Fri Dec 07 21:07:26 2018 -0500
@@ -208,7 +208,7 @@
             }
         }
 
-        if (logFile != null && !logFile.equals("")) {
+        if (logFile != null && !logFile.isEmpty()) {
             if (logFile.equals("-")) {
                 System.setErr(System.out);
             } else {
@@ -246,7 +246,7 @@
             }
             newfile = packfile;
             // The optional second argument is the source JAR file.
-            if (jarfile.equals("")) {
+            if (jarfile.isEmpty()) {
                 // If only one file is given, it is the only JAR.
                 // It serves as both input and output.
                 jarfile = newfile;
@@ -352,7 +352,7 @@
                 if (Utils.isGZIPMagic(Utils.readMagic(inBuf))) {
                     in = new GZIPInputStream(in);
                 }
-                String outfile = newfile.equals("")? jarfile: newfile;
+                String outfile = newfile.isEmpty()? jarfile: newfile;
                 OutputStream fileOut;
                 if (outfile.equals("-"))
                     fileOut = System.out;
@@ -366,7 +366,7 @@
                 // At this point, we have a good jarfile (or newfile, if -r)
             }
 
-            if (!bakfile.equals("")) {
+            if (!bakfile.isEmpty()) {
                         // On success, abort jarfile recovery bracket.
                         new File(bakfile).delete();
                         bakfile = "";
@@ -374,13 +374,13 @@
 
         } finally {
             // Close jarfile recovery bracket.
-            if (!bakfile.equals("")) {
+            if (!bakfile.isEmpty()) {
                 File jarFile = new File(jarfile);
                 jarFile.delete(); // Win32 requires this, see above
                 new File(bakfile).renameTo(jarFile);
             }
             // In all cases, delete temporary *.pack.
-            if (!tmpfile.equals(""))
+            if (!tmpfile.isEmpty())
                 new File(tmpfile).delete();
         }
     }
--- a/src/java.base/share/classes/com/sun/java/util/jar/pack/Package.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/com/sun/java/util/jar/pack/Package.java	Fri Dec 07 21:07:26 2018 -0500
@@ -685,7 +685,7 @@
                 return;  // do not choose yet
             }
             String canonName = canonicalFileName();
-            if (file.nameString.equals("")) {
+            if (file.nameString.isEmpty()) {
                 file.nameString = canonName;
             }
             if (file.nameString.equals(canonName)) {
@@ -706,7 +706,7 @@
 
         public java.io.File getFileName(java.io.File parent) {
             String name = file.name.stringValue();
-            if (name.equals(""))
+            if (name.isEmpty())
                 name = canonicalFileName();
             String fname = name.replace('/', java.io.File.separatorChar);
             return new java.io.File(parent, fname);
@@ -779,7 +779,7 @@
         }
         public boolean isTrivialClassStub() {
             return isClassStub()
-                && name.stringValue().equals("")
+                && name.stringValue().isEmpty()
                 && (modtime == NO_MODTIME || modtime == default_modtime)
                 && (options &~ FO_IS_CLASS_STUB) == 0;
         }
--- a/src/java.base/share/classes/com/sun/java/util/jar/pack/PackageWriter.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/com/sun/java/util/jar/pack/PackageWriter.java	Fri Dec 07 21:07:26 2018 -0500
@@ -646,7 +646,7 @@
             return;  // nothing to write
 
         // The first element must always be the empty string.
-        assert(cpMap[0].stringValue().equals(""));
+        assert(cpMap[0].stringValue().isEmpty());
         final int SUFFIX_SKIP_1 = 1;
         final int PREFIX_SKIP_2 = 2;
 
--- a/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java	Fri Dec 07 21:07:26 2018 -0500
@@ -237,7 +237,7 @@
         final long segmentLimit;
         {
             long limit;
-            if (props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals(""))
+            if (props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").isEmpty())
                 limit = -1;
             else
                 limit = props.getLong(Pack200.Packer.SEGMENT_LIMIT);
--- a/src/java.base/share/classes/java/io/File.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/java/io/File.java	Fri Dec 07 21:07:26 2018 -0500
@@ -257,7 +257,7 @@
      */
     private File(String child, File parent) {
         assert parent.path != null;
-        assert (!parent.path.equals(""));
+        assert (!parent.path.isEmpty());
         this.path = fs.resolve(parent.path, child);
         this.prefixLength = parent.prefixLength;
     }
@@ -316,7 +316,7 @@
             throw new NullPointerException();
         }
         if (parent != null) {
-            if (parent.equals("")) {
+            if (parent.isEmpty()) {
                 this.path = fs.resolve(fs.getDefaultParent(),
                                        fs.normalize(child));
             } else {
@@ -359,7 +359,7 @@
             throw new NullPointerException();
         }
         if (parent != null) {
-            if (parent.path.equals("")) {
+            if (parent.path.isEmpty()) {
                 this.path = fs.resolve(fs.getDefaultParent(),
                                        fs.normalize(child));
             } else {
@@ -426,7 +426,7 @@
         if (uri.getRawQuery() != null)
             throw new IllegalArgumentException("URI has a query component");
         String p = uri.getPath();
-        if (p.equals(""))
+        if (p.isEmpty())
             throw new IllegalArgumentException("URI path component is empty");
 
         // Okay, now initialize
--- a/src/java.base/share/classes/java/lang/SecurityManager.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/java/lang/SecurityManager.java	Fri Dec 07 21:07:26 2018 -0500
@@ -1201,7 +1201,7 @@
 
     private static String[] getPackages(String p) {
         String packages[] = null;
-        if (p != null && !p.equals("")) {
+        if (p != null && !p.isEmpty()) {
             java.util.StringTokenizer tok =
                 new java.util.StringTokenizer(p, ",");
             int n = tok.countTokens();
--- a/src/java.base/share/classes/java/lang/System.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/java/lang/System.java	Fri Dec 07 21:07:26 2018 -0500
@@ -970,7 +970,7 @@
         if (key == null) {
             throw new NullPointerException("key can't be null");
         }
-        if (key.equals("")) {
+        if (key.isEmpty()) {
             throw new IllegalArgumentException("key can't be empty");
         }
     }
--- a/src/java.base/share/classes/java/lang/reflect/Parameter.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/java/lang/reflect/Parameter.java	Fri Dec 07 21:07:26 2018 -0500
@@ -174,9 +174,9 @@
      */
     public String getName() {
         // Note: empty strings as parameter names are now outlawed.
-        // The .equals("") is for compatibility with current JVM
+        // The .isEmpty() is for compatibility with current JVM
         // behavior.  It may be removed at some point.
-        if(name == null || name.equals(""))
+        if(name == null || name.isEmpty())
             return "arg" + index;
         else
             return name;
--- a/src/java.base/share/classes/java/net/HostPortrange.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/java/net/HostPortrange.java	Fri Dec 07 21:07:26 2018 -0500
@@ -241,7 +241,7 @@
     int[] parsePort(String port)
     {
 
-        if (port == null || port.equals("")) {
+        if (port == null || port.isEmpty()) {
             return defaultPort();
         }
 
@@ -260,13 +260,13 @@
                 String high = port.substring(dash+1);
                 int l,h;
 
-                if (low.equals("")) {
+                if (low.isEmpty()) {
                     l = PORT_MIN;
                 } else {
                     l = Integer.parseInt(low);
                 }
 
-                if (high.equals("")) {
+                if (high.isEmpty()) {
                     h = PORT_MAX;
                 } else {
                     h = Integer.parseInt(high);
--- a/src/java.base/share/classes/java/net/InetAddress.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/java/net/InetAddress.java	Fri Dec 07 21:07:26 2018 -0500
@@ -1009,7 +1009,7 @@
                         + " not found ");
             }
 
-            if ((host == null) || (host.equals("")) || (host.equals(" "))) {
+            if ((host == null) || (host.isEmpty()) || (host.equals(" "))) {
                 throw new UnknownHostException("Requested address "
                         + addrString
                         + " resolves to an invalid entry in hosts file "
@@ -1046,7 +1046,7 @@
                         hostEntry = removeComments(hostEntry);
                         if (hostEntry.contains(host)) {
                             addrStr = extractHostAddr(hostEntry, host);
-                            if ((addrStr != null) && (!addrStr.equals(""))) {
+                            if ((addrStr != null) && (!addrStr.isEmpty())) {
                                 addr = createAddressByteArray(addrStr);
                                 if (inetAddresses == null) {
                                     inetAddresses = new ArrayList<>(1);
--- a/src/java.base/share/classes/java/net/SocketPermission.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/java/net/SocketPermission.java	Fri Dec 07 21:07:26 2018 -0500
@@ -305,7 +305,7 @@
     }
 
     private static String getHost(String host) {
-        if (host.equals("")) {
+        if (host.isEmpty()) {
             return "localhost";
         } else {
             /* IPv6 literal address used in this context should follow
@@ -344,7 +344,7 @@
         throws Exception
     {
 
-        if (port == null || port.equals("") || port.equals("*")) {
+        if (port == null || port.isEmpty() || port.equals("*")) {
             return new int[] {PORT_MIN, PORT_MAX};
         }
 
@@ -358,13 +358,13 @@
             String high = port.substring(dash+1);
             int l,h;
 
-            if (low.equals("")) {
+            if (low.isEmpty()) {
                 l = PORT_MIN;
             } else {
                 l = Integer.parseInt(low);
             }
 
-            if (high.equals("")) {
+            if (high.isEmpty()) {
                 h = PORT_MAX;
             } else {
                 h = Integer.parseInt(high);
@@ -496,7 +496,7 @@
             throw new NullPointerException("action can't be null");
         }
 
-        if (action.equals("")) {
+        if (action.isEmpty()) {
             throw new IllegalArgumentException("action can't be empty");
         }
 
--- a/src/java.base/share/classes/java/net/URLPermission.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/java/net/URLPermission.java	Fri Dec 07 21:07:26 2018 -0500
@@ -533,11 +533,11 @@
             String thishost = this.p.hostname();
             String thathost = that.p.hostname();
 
-            if (p.wildcard() && thishost.equals("")) {
+            if (p.wildcard() && thishost.isEmpty()) {
                 // this "*" implies all others
                 return true;
             }
-            if (that.p.wildcard() && thathost.equals("")) {
+            if (that.p.wildcard() && thathost.isEmpty()) {
                 // that "*" can only be implied by this "*"
                 return false;
             }
--- a/src/java.base/share/classes/java/net/URLStreamHandler.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/java/net/URLStreamHandler.java	Fri Dec 07 21:07:26 2018 -0500
@@ -437,7 +437,7 @@
             return u.hostAddress;
 
         String host = u.getHost();
-        if (host == null || host.equals("")) {
+        if (host == null || host.isEmpty()) {
             return null;
         } else {
             try {
--- a/src/java.base/share/classes/java/util/Locale.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/java/util/Locale.java	Fri Dec 07 21:07:26 2018 -0500
@@ -2226,10 +2226,10 @@
             default:
                 return Arrays.stream(stringList).reduce("",
                     (s1, s2) -> {
-                        if (s1.equals("")) {
+                        if (s1.isEmpty()) {
                             return s2;
                         }
-                        if (s2.equals("")) {
+                        if (s2.isEmpty()) {
                             return s1;
                         }
                         return MessageFormat.format(pattern, s1, s2);
@@ -3069,7 +3069,7 @@
 
         private static boolean isSubtagIllFormed(String subtag,
                                                  boolean isFirstSubtag) {
-            if (subtag.equals("") || subtag.length() > 8) {
+            if (subtag.isEmpty() || subtag.length() > 8) {
                 return true;
             } else if (subtag.equals("*")) {
                 return false;
--- a/src/java.base/share/classes/java/util/jar/Pack200.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/java/util/jar/Pack200.java	Fri Dec 07 21:07:26 2018 -0500
@@ -704,7 +704,7 @@
             if (impl == null) {
                 // The first time, we must decide which class to use.
                 implName = GetPropertyAction.privilegedGetProperty(prop,"");
-                if (implName != null && !implName.equals(""))
+                if (implName != null && !implName.isEmpty())
                     impl = Class.forName(implName);
                 else if (PACK_PROVIDER.equals(prop))
                     impl = com.sun.java.util.jar.pack.PackerImpl.class;
--- a/src/java.base/share/classes/java/util/regex/Pattern.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/java/util/regex/Pattern.java	Fri Dec 07 21:07:26 2018 -0500
@@ -1290,7 +1290,7 @@
         // Construct result
         int resultSize = matchList.size();
         if (limit == 0)
-            while (resultSize > 0 && matchList.get(resultSize-1).equals(""))
+            while (resultSize > 0 && matchList.get(resultSize-1).isEmpty())
                 resultSize--;
         String[] result = new String[resultSize];
         return matchList.subList(0, resultSize).toArray(result);
--- a/src/java.base/share/classes/javax/crypto/Cipher.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/javax/crypto/Cipher.java	Fri Dec 07 21:07:26 2018 -0500
@@ -531,7 +531,7 @@
     public static final Cipher getInstance(String transformation)
             throws NoSuchAlgorithmException, NoSuchPaddingException
     {
-        if ((transformation == null) || transformation.equals("")) {
+        if ((transformation == null) || transformation.isEmpty()) {
             throw new NoSuchAlgorithmException("Null or empty transformation");
         }
         List<Transform> transforms = getTransforms(transformation);
@@ -631,7 +631,7 @@
             throws NoSuchAlgorithmException, NoSuchProviderException,
             NoSuchPaddingException
     {
-        if ((transformation == null) || transformation.equals("")) {
+        if ((transformation == null) || transformation.isEmpty()) {
             throw new NoSuchAlgorithmException("Null or empty transformation");
         }
         if ((provider == null) || (provider.length() == 0)) {
@@ -698,7 +698,7 @@
                                            Provider provider)
             throws NoSuchAlgorithmException, NoSuchPaddingException
     {
-        if ((transformation == null) || transformation.equals("")) {
+        if ((transformation == null) || transformation.isEmpty()) {
             throw new NoSuchAlgorithmException("Null or empty transformation");
         }
         if (provider == null) {
@@ -2840,4 +2840,4 @@
         sb.append(", algorithm from: ").append(getProviderName());
         return sb.toString();
     }
-}
\ No newline at end of file
+}
--- a/src/java.base/share/classes/javax/net/ssl/SSLParameters.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/javax/net/ssl/SSLParameters.java	Fri Dec 07 21:07:26 2018 -0500
@@ -668,7 +668,7 @@
         String[] tempProtocols = protocols.clone();
 
         for (String p : tempProtocols) {
-            if (p == null || p.equals("")) {
+            if (p == null || p.isEmpty()) {
                 throw new IllegalArgumentException(
                     "An element of protocols was null/empty");
             }
--- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Fri Dec 07 21:07:26 2018 -0500
@@ -97,10 +97,10 @@
         JAVA_VERSION = props.getProperty("java.version");
         DEBUG = (props.getProperty("sun.misc.URLClassPath.debug") != null);
         String p = props.getProperty("sun.misc.URLClassPath.disableJarChecking");
-        DISABLE_JAR_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
+        DISABLE_JAR_CHECKING = p != null ? p.equals("true") || p.isEmpty() : false;
 
         p = props.getProperty("jdk.net.URLClassPath.disableRestrictedPermissions");
-        DISABLE_ACC_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
+        DISABLE_ACC_CHECKING = p != null ? p.equals("true") || p.isEmpty() : false;
 
         // This property will be removed in a later release
         p = props.getProperty("jdk.net.URLClassPath.disableClassPathURLCheck", "true");
--- a/src/java.base/share/classes/sun/net/www/protocol/jar/URLJarFile.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/sun/net/www/protocol/jar/URLJarFile.java	Fri Dec 07 21:07:26 2018 -0500
@@ -111,7 +111,7 @@
              * 'file:' URLs can be accessible through ftp.
              */
             String host = url.getHost();
-            if (host == null || host.equals("") || host.equals("~") ||
+            if (host == null || host.isEmpty() || host.equals("~") ||
                 host.equalsIgnoreCase("localhost"))
                 return true;
         }
--- a/src/java.base/share/classes/sun/net/www/protocol/mailto/Handler.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/sun/net/www/protocol/mailto/Handler.java	Fri Dec 07 21:07:26 2018 -0500
@@ -127,7 +127,7 @@
          * Let's just make sure we DO have an Email address in the URL.
          */
         boolean nogood = false;
-        if (file == null || file.equals(""))
+        if (file == null || file.isEmpty())
             nogood = true;
         else {
             boolean allwhites = true;
--- a/src/java.base/share/classes/sun/security/provider/PolicyFile.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/sun/security/provider/PolicyFile.java	Fri Dec 07 21:07:26 2018 -0500
@@ -1608,7 +1608,7 @@
             if (u.getProtocol().equals("file")) {
                 boolean isLocalFile = false;
                 String host = u.getHost();
-                isLocalFile = (host == null || host.equals("") ||
+                isLocalFile = (host == null || host.isEmpty() ||
                     host.equals("~") || host.equalsIgnoreCase("localhost"));
 
                 if (isLocalFile) {
--- a/src/java.base/share/classes/sun/security/util/ConsoleCallbackHandler.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/sun/security/util/ConsoleCallbackHandler.java	Fri Dec 07 21:07:26 2018 -0500
@@ -103,7 +103,7 @@
                 System.err.flush();
 
                 String result = readLine();
-                if (result.equals("")) {
+                if (result.isEmpty()) {
                     result = nc.getDefaultName();
                 }
 
@@ -212,7 +212,7 @@
             prompt = "";
         }
         prompt = prefix + prompt;
-        if (!prompt.equals("")) {
+        if (!prompt.isEmpty()) {
             System.err.println(prompt);
         }
 
--- a/src/java.base/share/classes/sun/security/util/DomainName.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/share/classes/sun/security/util/DomainName.java	Fri Dec 07 21:07:26 2018 -0500
@@ -363,7 +363,7 @@
             }
 
             private static int numLabels(String rule) {
-                if (rule.equals("")) {
+                if (rule.isEmpty()) {
                     return 0;
                 }
                 int len = rule.length();
--- a/src/java.base/unix/classes/java/io/UnixFileSystem.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/unix/classes/java/io/UnixFileSystem.java	Fri Dec 07 21:07:26 2018 -0500
@@ -103,7 +103,7 @@
     }
 
     public String resolve(String parent, String child) {
-        if (child.equals("")) return parent;
+        if (child.isEmpty()) return parent;
         if (child.charAt(0) == '/') {
             if (parent.equals("/")) return child;
             return parent + child;
--- a/src/java.base/unix/classes/sun/net/www/protocol/file/Handler.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/unix/classes/sun/net/www/protocol/file/Handler.java	Fri Dec 07 21:07:26 2018 -0500
@@ -75,7 +75,7 @@
     public synchronized URLConnection openConnection(URL u, Proxy p)
            throws IOException {
         String host = u.getHost();
-        if (host == null || host.equals("") || host.equals("~") ||
+        if (host == null || host.isEmpty() || host.equals("~") ||
             host.equalsIgnoreCase("localhost")) {
             File file = new File(ParseUtil.decode(u.getPath()));
             return createFileURLConnection(u, file);
--- a/src/java.base/windows/classes/jdk/internal/loader/FileURLMapper.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/windows/classes/jdk/internal/loader/FileURLMapper.java	Fri Dec 07 21:07:26 2018 -0500
@@ -55,7 +55,7 @@
             return file;
         }
         String host = url.getHost();
-        if (host != null && !host.equals("") &&
+        if (host != null && !host.isEmpty() &&
             !"localhost".equalsIgnoreCase(host)) {
             String rest = url.getFile();
             String s = host + ParseUtil.decode (url.getFile());
--- a/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java	Fri Dec 07 21:07:26 2018 -0500
@@ -83,7 +83,7 @@
         path = path.replace('/', '\\');
         path = path.replace('|', ':');
 
-        if ((host == null) || host.equals("") ||
+        if ((host == null) || host.isEmpty() ||
                 host.equalsIgnoreCase("localhost") ||
                 host.equals("~")) {
            return createFileURLConnection(url, new File(path));
--- a/src/java.base/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java	Fri Dec 07 21:07:26 2018 -0500
@@ -76,7 +76,7 @@
             // Deal with UNC pathnames specially. See 4180841
 
             String host = url.getHost();
-            if (host != null && !host.equals("") &&
+            if (host != null && !host.isEmpty() &&
                 !host.equalsIgnoreCase("localhost")) {
 
                 url = new URL("file", "", "//" + host + url.getPath());
--- a/src/java.base/windows/classes/sun/nio/fs/WindowsUriSupport.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.base/windows/classes/sun/nio/fs/WindowsUriSupport.java	Fri Dec 07 21:07:26 2018 -0500
@@ -128,12 +128,12 @@
         if (uri.getRawQuery() != null)
             throw new IllegalArgumentException("URI has a query component");
         String path = uri.getPath();
-        if (path.equals(""))
+        if (path.isEmpty())
             throw new IllegalArgumentException("URI path component is empty");
 
         // UNC
         String auth = uri.getRawAuthority();
-        if (auth != null && !auth.equals("")) {
+        if (auth != null && !auth.isEmpty()) {
             String host = uri.getHost();
             if (host == null)
                 throw new IllegalArgumentException("URI authority component has undefined host");
--- a/src/java.logging/share/classes/java/util/logging/LogManager.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.logging/share/classes/java/util/logging/LogManager.java	Fri Dec 07 21:07:26 2018 -0500
@@ -890,7 +890,7 @@
         // Gets a node in our tree of logger nodes.
         // If necessary, create it.
         LogNode getNode(String name) {
-            if (name == null || name.equals("")) {
+            if (name == null || name.isEmpty()) {
                 return root;
             }
             LogNode node = root;
@@ -1486,7 +1486,7 @@
 
         // Reset Logger level
         String name = logger.getName();
-        if (name != null && name.equals("")) {
+        if (name != null && name.isEmpty()) {
             // This is the root logger.
             logger.setLevel(defaultLevel);
         } else {
--- a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectorServer.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectorServer.java	Fri Dec 07 21:07:26 2018 -0500
@@ -289,7 +289,7 @@
                 throw new MalformedURLException(msg);
             }
             final String urlPath = url.getURLPath();
-            if (!urlPath.equals("")
+            if (!urlPath.isEmpty()
                 && !urlPath.equals("/")
                 && !urlPath.startsWith("/jndi/")) {
                 final String msg = "URL path must be empty or start with " +
@@ -746,7 +746,7 @@
             port = 0;
         } else {
             protocol = address.getProtocol();
-            host = (address.getHost().equals("")) ? null : address.getHost();
+            host = (address.getHost().isEmpty()) ? null : address.getHost();
             port = address.getPort();
         }
 
--- a/src/java.management/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.management/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java	Fri Dec 07 21:07:26 2018 -0500
@@ -114,7 +114,7 @@
 
         // 6238731: set the default domain if no domain is set.
         ObjectName nn = name;
-        if (name.getDomain() == null || name.getDomain().equals("")) {
+        if (name.getDomain() == null || name.getDomain().isEmpty()) {
             try {
                 nn = ObjectName.getInstance(mbeanServer.getDefaultDomain(),
                                             name.getKeyPropertyList());
--- a/src/java.management/share/classes/javax/management/ImmutableDescriptor.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.management/share/classes/javax/management/ImmutableDescriptor.java	Fri Dec 07 21:07:26 2018 -0500
@@ -110,7 +110,7 @@
                 new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);
         for (Map.Entry<String, ?> entry : fields.entrySet()) {
             String name = entry.getKey();
-            if (name == null || name.equals(""))
+            if (name == null || name.isEmpty())
                 throw new IllegalArgumentException("Empty or null field name");
             if (map.containsKey(name))
                 throw new IllegalArgumentException("Duplicate name: " + name);
@@ -166,7 +166,7 @@
                 new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);
         for (int i = 0; i < fieldNames.length; i++) {
             String name = fieldNames[i];
-            if (name == null || name.equals(""))
+            if (name == null || name.isEmpty())
                 throw new IllegalArgumentException("Empty or null field name");
             Object old = map.put(name, fieldValues[i]);
             if (old != null) {
@@ -333,7 +333,7 @@
         Object[] result = new Object[fieldNames.length];
         for (int i = 0; i < fieldNames.length; i++) {
             String name = fieldNames[i];
-            if (name != null && !name.equals(""))
+            if (name != null && !name.isEmpty())
                 result[i] = getFieldValue(name);
         }
         return result;
@@ -543,7 +543,7 @@
     }
 
     private static void checkIllegalFieldName(String name) {
-        if (name == null || name.equals(""))
+        if (name == null || name.isEmpty())
             illegal("Null or empty field name");
     }
 
--- a/src/java.management/share/classes/javax/management/MBeanPermission.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.management/share/classes/javax/management/MBeanPermission.java	Fri Dec 07 21:07:26 2018 -0500
@@ -256,7 +256,7 @@
         if (actions == null)
             throw new IllegalArgumentException("MBeanPermission: " +
                                                "actions can't be null");
-        if (actions.equals(""))
+        if (actions.isEmpty())
             throw new IllegalArgumentException("MBeanPermission: " +
                                                "actions can't be empty");
 
@@ -279,7 +279,7 @@
             throw new IllegalArgumentException("MBeanPermission name " +
                                                "cannot be null");
 
-        if (name.equals(""))
+        if (name.isEmpty())
             throw new IllegalArgumentException("MBeanPermission name " +
                                                "cannot be empty");
 
@@ -310,7 +310,7 @@
                     //
                     String on = name.substring(openingBracket + 1,
                                                name.length() - 1);
-                    if (on.equals(""))
+                    if (on.isEmpty())
                         objectName = ObjectName.WILDCARD;
                     else if (on.equals("-"))
                         objectName = null;
@@ -359,7 +359,7 @@
         if (className == null || className.equals("-")) {
             classNamePrefix = null;
             classNameExactMatch = false;
-        } else if (className.equals("") || className.equals("*")) {
+        } else if (className.isEmpty() || className.equals("*")) {
             classNamePrefix = "";
             classNameExactMatch = false;
         } else if (className.endsWith(".*")) {
@@ -375,7 +375,7 @@
     private void setMember(String member) {
         if (member == null || member.equals("-"))
             this.member = null;
-        else if (member.equals(""))
+        else if (member.isEmpty())
             this.member = "*";
         else
             this.member = member;
--- a/src/java.management/share/classes/javax/management/modelmbean/DescriptorSupport.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.management/share/classes/javax/management/modelmbean/DescriptorSupport.java	Fri Dec 07 21:07:26 2018 -0500
@@ -443,7 +443,7 @@
         init(null);
 
         for (int i=0; i < fields.length; i++) {
-            if ((fields[i] == null) || (fields[i].equals(""))) {
+            if ((fields[i] == null) || (fields[i].isEmpty())) {
                 continue;
             }
             int eq_separator = fields[i].indexOf('=');
@@ -467,7 +467,7 @@
                 fieldValue = fields[i].substring(eq_separator+1);
             }
 
-            if (fieldName.equals("")) {
+            if (fieldName.isEmpty()) {
                 if (MODELMBEAN_LOGGER.isLoggable(Level.TRACE)) {
                     MODELMBEAN_LOGGER.log(Level.TRACE,
                             "Descriptor(String... fields) " +
@@ -500,7 +500,7 @@
     public synchronized Object getFieldValue(String fieldName)
             throws RuntimeOperationsException {
 
-        if ((fieldName == null) || (fieldName.equals(""))) {
+        if ((fieldName == null) || (fieldName.isEmpty())) {
             if (MODELMBEAN_LOGGER.isLoggable(Level.TRACE)) {
                 MODELMBEAN_LOGGER.log(Level.TRACE,
                         "Illegal arguments: null field name");
@@ -522,7 +522,7 @@
             throws RuntimeOperationsException {
 
         // field name cannot be null or empty
-        if ((fieldName == null) || (fieldName.equals(""))) {
+        if ((fieldName == null) || (fieldName.isEmpty())) {
             if (MODELMBEAN_LOGGER.isLoggable(Level.TRACE)) {
                 MODELMBEAN_LOGGER.log(Level.TRACE,
                         "Illegal arguments: null or empty field name");
@@ -664,7 +664,7 @@
                 responseFields[i++] = value;
         } else {
             for (i=0; i < fieldNames.length; i++) {
-                if ((fieldNames[i] == null) || (fieldNames[i].equals(""))) {
+                if ((fieldNames[i] == null) || (fieldNames[i].isEmpty())) {
                     responseFields[i] = null;
                 } else {
                     responseFields[i] = getFieldValue(fieldNames[i]);
@@ -700,7 +700,7 @@
         }
 
         for (int i=0; i < fieldNames.length; i++) {
-            if (( fieldNames[i] == null) || (fieldNames[i].equals(""))) {
+            if (( fieldNames[i] == null) || (fieldNames[i].isEmpty())) {
                 if (MODELMBEAN_LOGGER.isLoggable(Level.TRACE)) {
                     MODELMBEAN_LOGGER.log(Level.TRACE,
                             "Null field name encountered at element " + i);
@@ -733,7 +733,7 @@
     }
 
     public synchronized void removeField(String fieldName) {
-        if ((fieldName == null) || (fieldName.equals(""))) {
+        if ((fieldName == null) || (fieldName.isEmpty())) {
             return;
         }
 
@@ -862,7 +862,7 @@
         String thisDescType = (String)(getFieldValue("descriptorType"));
 
         if ((thisName == null) || (thisDescType == null) ||
-            (thisName.equals("")) || (thisDescType.equals(""))) {
+            (thisName.isEmpty()) || (thisDescType.isEmpty())) {
             return false;
         }
 
@@ -912,7 +912,7 @@
 
 
     private boolean validateField(String fldName, Object fldValue) {
-        if ((fldName == null) || (fldName.equals("")))
+        if ((fldName == null) || (fldName.isEmpty()))
             return false;
         String SfldValue = "";
         boolean isAString = false;
@@ -931,7 +931,7 @@
             fldName.equalsIgnoreCase("Class")) {
             if (fldValue == null || !isAString)
                 return false;
-            if (nameOrDescriptorType && SfldValue.equals(""))
+            if (nameOrDescriptorType && SfldValue.isEmpty())
                 return false;
             return true;
         } else if (fldName.equalsIgnoreCase("visibility")) {
--- a/src/java.management/share/classes/javax/management/modelmbean/ModelMBeanInfoSupport.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.management/share/classes/javax/management/modelmbean/ModelMBeanInfoSupport.java	Fri Dec 07 21:07:26 2018 -0500
@@ -367,7 +367,7 @@
             MODELMBEAN_LOGGER.log(Level.TRACE, "Entry");
         }
 
-        if ((inDescriptorType == null) || (inDescriptorType.equals(""))) {
+        if ((inDescriptorType == null) || (inDescriptorType.isEmpty())) {
             inDescriptorType = "all";
         }
 
@@ -600,7 +600,7 @@
             inDescriptor = new DescriptorSupport();
         }
 
-        if ((inDescriptorType == null) || (inDescriptorType.equals(""))) {
+        if ((inDescriptorType == null) || (inDescriptorType.isEmpty())) {
             inDescriptorType =
                     (String) inDescriptor.getFieldValue("descriptorType");
 
--- a/src/java.management/share/classes/javax/management/openmbean/CompositeType.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.management/share/classes/javax/management/openmbean/CompositeType.java	Fri Dec 07 21:07:26 2018 -0500
@@ -171,7 +171,7 @@
 
     private static void checkForEmptyString(String[] arg, String argName) {
         for (int i=0; i<arg.length; i++) {
-            if (arg[i].trim().equals("")) {
+            if (arg[i].trim().isEmpty()) {
                 throw new IllegalArgumentException("Argument's element "+ argName +"["+ i +"] cannot be an empty string.");
             }
         }
--- a/src/java.management/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.management/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java	Fri Dec 07 21:07:26 2018 -0500
@@ -456,11 +456,11 @@
             throw new IllegalArgumentException("OpenType cannot be null");
 
         if (info.getName() == null ||
-                info.getName().trim().equals(""))
+                info.getName().trim().isEmpty())
             throw new IllegalArgumentException("Name cannot be null or empty");
 
         if (info.getDescription() == null ||
-                info.getDescription().trim().equals(""))
+                info.getDescription().trim().isEmpty())
             throw new IllegalArgumentException("Description cannot be null or empty");
 
         // Check and initialize defaultValue
--- a/src/java.management/share/classes/javax/management/openmbean/OpenMBeanConstructorInfoSupport.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.management/share/classes/javax/management/openmbean/OpenMBeanConstructorInfoSupport.java	Fri Dec 07 21:07:26 2018 -0500
@@ -124,11 +124,11 @@
         // check parameters that should not be null or empty
         // (unfortunately it is not done in superclass :-( ! )
         //
-        if (name == null || name.trim().equals("")) {
+        if (name == null || name.trim().isEmpty()) {
             throw new IllegalArgumentException("Argument name cannot be " +
                                                "null or empty");
         }
-        if (description == null || description.trim().equals("")) {
+        if (description == null || description.trim().isEmpty()) {
             throw new IllegalArgumentException("Argument description cannot " +
                                                "be null or empty");
         }
--- a/src/java.management/share/classes/javax/management/openmbean/OpenMBeanOperationInfoSupport.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.management/share/classes/javax/management/openmbean/OpenMBeanOperationInfoSupport.java	Fri Dec 07 21:07:26 2018 -0500
@@ -163,11 +163,11 @@
         // check parameters that should not be null or empty
         // (unfortunately it is not done in superclass :-( ! )
         //
-        if (name == null || name.trim().equals("")) {
+        if (name == null || name.trim().isEmpty()) {
             throw new IllegalArgumentException("Argument name cannot " +
                                                "be null or empty");
         }
-        if (description == null || description.trim().equals("")) {
+        if (description == null || description.trim().isEmpty()) {
             throw new IllegalArgumentException("Argument description cannot " +
                                                "be null or empty");
         }
--- a/src/java.management/share/classes/javax/management/openmbean/OpenType.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.management/share/classes/javax/management/openmbean/OpenType.java	Fri Dec 07 21:07:26 2018 -0500
@@ -268,7 +268,7 @@
     /* Return argValue.trim() provided argValue is neither null nor empty;
        otherwise throw IllegalArgumentException.  */
     private static String valid(String argName, String argValue) {
-        if (argValue == null || (argValue = argValue.trim()).equals(""))
+        if (argValue == null || (argValue = argValue.trim()).isEmpty())
             throw new IllegalArgumentException("Argument " + argName +
                                                " cannot be null or empty");
         return argValue;
--- a/src/java.management/share/classes/javax/management/openmbean/TabularType.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.management/share/classes/javax/management/openmbean/TabularType.java	Fri Dec 07 21:07:26 2018 -0500
@@ -165,7 +165,7 @@
      */
     private static void checkForEmptyString(String[] arg, String argName) {
         for (int i=0; i<arg.length; i++) {
-            if (arg[i].trim().equals("")) {
+            if (arg[i].trim().isEmpty()) {
                 throw new IllegalArgumentException("Argument's element "+ argName +"["+ i +"] cannot be an empty string.");
             }
         }
--- a/src/java.management/share/classes/javax/management/remote/JMXConnectorFactory.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.management/share/classes/javax/management/remote/JMXConnectorFactory.java	Fri Dec 07 21:07:26 2018 -0500
@@ -405,7 +405,7 @@
         }
 
         final String pkgs = (String) pkgsObject;
-        if (pkgs.trim().equals(""))
+        if (pkgs.trim().isEmpty())
             return null;
 
         // pkgs may not contain an empty element
--- a/src/java.management/share/classes/sun/management/MappedMXBeanType.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.management/share/classes/sun/management/MappedMXBeanType.java	Fri Dec 07 21:07:26 2018 -0500
@@ -663,7 +663,7 @@
                         continue;
                     }
 
-                    if (rest.equals("") ||
+                    if (rest.isEmpty() ||
                         method.getParameterTypes().length > 0 ||
                         type == void.class ||
                         rest.equals("Class")) {
--- a/src/java.naming/share/classes/com/sun/jndi/ldap/Filter.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.naming/share/classes/com/sun/jndi/ldap/Filter.java	Fri Dec 07 21:07:26 2018 -0500
@@ -53,7 +53,7 @@
     static void encodeFilterString(BerEncoder ber, String filterStr,
         boolean isLdapv3) throws IOException, NamingException {
 
-        if ((filterStr == null) || (filterStr.equals(""))) {
+        if ((filterStr == null) || (filterStr.isEmpty())) {
             throw new InvalidSearchFilterException("Empty filter");
         }
         byte[] filter;
--- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java	Fri Dec 07 21:07:26 2018 -0500
@@ -915,7 +915,7 @@
         boolean directUpdate) throws NamingException {
 
             // Handle the empty name
-            if (dn.equals("")) {
+            if (dn.isEmpty()) {
                 return attrs;
             }
 
@@ -1271,7 +1271,7 @@
         int prefixLast = prefix.size() - 1;
 
         if (name.isEmpty() || prefix.isEmpty() ||
-                name.get(0).equals("") || prefix.get(prefixLast).equals("")) {
+                name.get(0).isEmpty() || prefix.get(prefixLast).isEmpty()) {
             return super.composeName(name, prefix);
         }
 
@@ -1300,9 +1300,9 @@
 
     // used by LdapSearchEnumeration
     private static String concatNames(String lesser, String greater) {
-        if (lesser == null || lesser.equals("")) {
+        if (lesser == null || lesser.isEmpty()) {
             return greater;
-        } else if (greater == null || greater.equals("")) {
+        } else if (greater == null || greater.isEmpty()) {
             return lesser;
         } else {
             return (lesser + "," + greater);
@@ -3036,7 +3036,7 @@
             }
 
             // extract SLAPD-style referrals from errorMessage
-            if ((res.errorMessage != null) && (!res.errorMessage.equals(""))) {
+            if ((res.errorMessage != null) && (!res.errorMessage.isEmpty())) {
                 res.referrals = extractURLs(res.errorMessage);
             } else {
                 e = new PartialResultException(msg);
--- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapReferralContext.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapReferralContext.java	Fri Dec 07 21:07:26 2018 -0500
@@ -182,7 +182,7 @@
         if (urlString == null) {
             urlName = null;
         } else {
-            urlName = urlString.equals("") ? new CompositeName() :
+            urlName = urlString.isEmpty() ? new CompositeName() :
                 new CompositeName().add(urlString);
         }
     }
@@ -888,7 +888,7 @@
 
     // ---------------------- Private methods  ---------------------
     private Name toName(String name) throws InvalidNameException {
-        return name.equals("") ? new CompositeName() :
+        return name.isEmpty() ? new CompositeName() :
             new CompositeName().add(name);
     }
 
--- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java	Fri Dec 07 21:07:26 2018 -0500
@@ -97,13 +97,13 @@
 
         // Name relative to search context
         CompositeName cn = new CompositeName();
-        if (!relStart.equals("")) {
+        if (!relStart.isEmpty()) {
             cn.add(relStart);
         }
 
         // Name relative to homeCtx
         CompositeName rcn = new CompositeName();
-        if (!relHome.equals("")) {
+        if (!relHome.isEmpty()) {
             rcn.add(relHome);
         }
         //System.err.println("relStart: " + cn);
--- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java	Fri Dec 07 21:07:26 2018 -0500
@@ -197,7 +197,7 @@
 
         // path begins with a '/' or is empty
 
-        if (path.equals("")) {
+        if (path.isEmpty()) {
             return;
         }
 
--- a/src/java.naming/share/classes/com/sun/jndi/ldap/NamingEventNotifier.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.naming/share/classes/com/sun/jndi/ldap/NamingEventNotifier.java	Fri Dec 07 21:07:26 2018 -0500
@@ -115,7 +115,7 @@
         try {
             Continuation cont = new Continuation();
             cont.setError(this, info.name);
-            Name nm = (info.name == null || info.name.equals("")) ?
+            Name nm = (info.name == null || info.name.isEmpty()) ?
                 new CompositeName() : new CompositeName().add(info.name);
 
             results = context.searchAux(nm, info.filter, info.controls,
--- a/src/java.naming/share/classes/com/sun/jndi/toolkit/ctx/AtomicContext.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.naming/share/classes/com/sun/jndi/toolkit/ctx/AtomicContext.java	Fri Dec 07 21:07:26 2018 -0500
@@ -243,7 +243,7 @@
 
 
     protected boolean isEmpty(String name) {
-        return name == null || name.equals("");
+        return name == null || name.isEmpty();
     }
 
 // ------ implementations of c_  and c_*_nns methods using
@@ -510,7 +510,7 @@
       */
     protected void a_processJunction_nns(String name, Continuation cont)
         throws NamingException {
-            if (name.equals("")) {
+            if (name.isEmpty()) {
                 NameNotFoundException e = new NameNotFoundException();
                 cont.setErrorNNS(this, name);
                 throw cont.fillInException(e);
--- a/src/java.naming/share/classes/com/sun/jndi/toolkit/ctx/ComponentContext.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.naming/share/classes/com/sun/jndi/toolkit/ctx/ComponentContext.java	Fri Dec 07 21:07:26 2018 -0500
@@ -105,7 +105,7 @@
         throws NamingException {
         int separator;
         // if no name to parse, or if we're already at boundary
-        if (name.isEmpty() ||  name.get(0).equals("")) {
+        if (name.isEmpty() ||  name.get(0).isEmpty()) {
             separator = 0;
         } else {
             separator = 1;
@@ -379,7 +379,7 @@
         if (tail == null || tail.isEmpty()) {
 //System.out.println("terminal : " + head);
             ret = TERMINAL_COMPONENT;
-        } else if (!tail.get(0).equals("")) {
+        } else if (!tail.get(0).isEmpty()) {
             // tail does not begin with "/"
 /*
             if (head.isEmpty()) {
@@ -468,7 +468,7 @@
     void checkAndAdjustRemainingName(Name rname) throws InvalidNameException {
         int count;
         if (rname != null && (count=rname.size()) > 1 &&
-            rname.get(count-1).equals("")) {
+            rname.get(count-1).isEmpty()) {
             rname.remove(count-1);
         }
     }
@@ -477,7 +477,7 @@
     protected boolean isAllEmpty(Name n) {
         int count = n.size();
         for (int i =0; i < count; i++ ) {
-            if (!n.get(i).equals("")) {
+            if (!n.get(i).isEmpty()) {
                 return false;
             }
         }
--- a/src/java.naming/share/classes/com/sun/jndi/toolkit/ctx/Continuation.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.naming/share/classes/com/sun/jndi/toolkit/ctx/Continuation.java	Fri Dec 07 21:07:26 2018 -0500
@@ -203,7 +203,7 @@
     public void setErrorNNS(Object resObj, String remain) {
         CompositeName rname = new CompositeName();
         try {
-            if (remain != null && !remain.equals(""))
+            if (remain != null && !remain.isEmpty())
                 rname.add(remain);
 
             rname.add("");
@@ -247,7 +247,7 @@
      */
     public void setError(Object resObj, String remain) {
         CompositeName rname = new CompositeName();
-        if (remain != null && !remain.equals("")) {
+        if (remain != null && !remain.isEmpty()) {
             try {
                 rname.add(remain);
             } catch (InvalidNameException e) {
@@ -375,14 +375,14 @@
     public void setContinue(Object obj, String relResName,
         Context currCtx, String remain) {
         CompositeName relname = new CompositeName();
-        if (!relResName.equals("")) {
+        if (!relResName.isEmpty()) {
             try {
                 relname.add(relResName);
             } catch (NamingException e){}
         }
 
         CompositeName rname = new CompositeName();
-        if (!remain.equals("")) {
+        if (!remain.isEmpty()) {
             try {
                 rname.add(remain);
             } catch (NamingException e) {
--- a/src/java.naming/share/classes/com/sun/jndi/toolkit/ctx/PartialCompositeContext.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.naming/share/classes/com/sun/jndi/toolkit/ctx/PartialCompositeContext.java	Fri Dec 07 21:07:26 2018 -0500
@@ -477,9 +477,9 @@
         int len = prefix.size();
 
         if (!allEmpty(prefix) && !allEmpty(name)) {
-            if (res.get(len - 1).equals("")) {
+            if (res.get(len - 1).isEmpty()) {
                 res.remove(len - 1);
-            } else if (res.get(len).equals("")) {
+            } else if (res.get(len).isEmpty()) {
                 res.remove(len);
             }
         }
--- a/src/java.naming/share/classes/com/sun/jndi/toolkit/dir/ContextEnumerator.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.naming/share/classes/com/sun/jndi/toolkit/dir/ContextEnumerator.java	Fri Dec 07 21:07:26 2018 -0500
@@ -138,7 +138,7 @@
         // if the name is relative, we need to add it to the name of this
         // context to keep it relative w.r.t. the root context we are
         // enumerating
-        if(oldBinding.isRelative() && !contextName.equals("")) {
+        if(oldBinding.isRelative() && !contextName.isEmpty()) {
             NameParser parser = root.getNameParser("");
             Name newName = parser.parse(contextName);
             newName.add(oldBinding.getName());
--- a/src/java.naming/share/classes/com/sun/jndi/toolkit/url/GenericURLContext.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.naming/share/classes/com/sun/jndi/toolkit/url/GenericURLContext.java	Fri Dec 07 21:07:26 2018 -0500
@@ -476,9 +476,9 @@
 
     public String composeName(String name, String prefix)
         throws NamingException {
-            if (prefix.equals("")) {
+            if (prefix.isEmpty()) {
                 return name;
-            } else if (name.equals("")) {
+            } else if (name.isEmpty()) {
                 return prefix;
             } else {
                 return (prefix + "/" + name);
--- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java	Fri Dec 07 21:07:26 2018 -0500
@@ -201,13 +201,13 @@
     private String getPathAndQuery(URI uri) {
         String path = uri.getRawPath();
         String query = uri.getRawQuery();
-        if (path == null || path.equals("")) {
+        if (path == null || path.isEmpty()) {
             path = "/";
         }
         if (query == null) {
             query = "";
         }
-        if (query.equals("")) {
+        if (query.isEmpty()) {
             return Utils.encode(path);
         } else {
             return Utils.encode(path + "?" + query);
--- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java	Fri Dec 07 21:07:26 2018 -0500
@@ -190,7 +190,7 @@
     @Override
     public HttpRequest.Builder method(String method, BodyPublisher body) {
         requireNonNull(method);
-        if (method.equals(""))
+        if (method.isEmpty())
             throw newIAE("illegal method <empty string>");
         if (method.equals("CONNECT"))
             throw newIAE("method CONNECT is not supported");
@@ -205,7 +205,7 @@
 
     private HttpRequest.Builder method0(String method, BodyPublisher body) {
         assert method != null;
-        assert !method.equals("");
+        assert !method.isEmpty();
         this.method = method;
         this.bodyPublisher = body;
         return this;
--- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseContent.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseContent.java	Fri Dec 07 21:07:26 2018 -0500
@@ -84,7 +84,7 @@
         if (contentLength == -1) {
             String tc = headers.firstValue("Transfer-Encoding")
                                .orElse("");
-            if (!tc.equals("")) {
+            if (!tc.isEmpty()) {
                 if (tc.equalsIgnoreCase("chunked")) {
                     chunkedContent = true;
                 } else {
--- a/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java	Fri Dec 07 21:07:26 2018 -0500
@@ -97,7 +97,7 @@
     private static final ByteBuffer NOTHING = ByteBuffer.allocate(0);
     private static final String monProp = Utils.getProperty("jdk.internal.httpclient.monitorFlowDelegate");
     private static final boolean isMonitored =
-            monProp != null && (monProp.equals("") || monProp.equalsIgnoreCase("true"));
+            monProp != null && (monProp.isEmpty() || monProp.equalsIgnoreCase("true"));
 
     final Executor exec;
     final Reader reader;
--- a/src/java.prefs/share/classes/java/util/prefs/AbstractPreferences.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.prefs/share/classes/java/util/prefs/AbstractPreferences.java	Fri Dec 07 21:07:26 2018 -0500
@@ -203,7 +203,7 @@
      */
     protected AbstractPreferences(AbstractPreferences parent, String name) {
         if (parent==null) {
-            if (!name.equals(""))
+            if (!name.isEmpty())
                 throw new IllegalArgumentException("Root name '"+name+
                                                    "' must be \"\"");
             this.absolutePath = "/";
@@ -212,7 +212,7 @@
             if (name.indexOf('/') != -1)
                 throw new IllegalArgumentException("Name '" + name +
                                                  "' contains '/'");
-            if (name.equals(""))
+            if (name.isEmpty())
               throw new IllegalArgumentException("Illegal name: empty string");
 
             root = parent.root;
@@ -848,7 +848,7 @@
         synchronized(lock) {
             if (removed)
                 throw new IllegalStateException("Node has been removed.");
-            if (path.equals(""))
+            if (path.isEmpty())
                 return this;
             if (path.equals("/"))
                 return root;
@@ -911,7 +911,7 @@
         throws BackingStoreException
     {
         synchronized(lock) {
-            if (path.equals(""))
+            if (path.isEmpty())
                 return !removed;
             if (removed)
                 throw new IllegalStateException("Node has been removed.");
--- a/src/java.rmi/share/classes/com/sun/rmi/rmid/ExecOptionPermission.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.rmi/share/classes/com/sun/rmi/rmid/ExecOptionPermission.java	Fri Dec 07 21:07:26 2018 -0500
@@ -189,7 +189,7 @@
         if (name == null)
             throw new NullPointerException("name can't be null");
 
-        if (name.equals("")) {
+        if (name.isEmpty()) {
             throw new IllegalArgumentException("name can't be empty");
         }
 
--- a/src/java.rmi/share/classes/java/rmi/Naming.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.rmi/share/classes/java/rmi/Naming.java	Fri Dec 07 21:07:26 2018 -0500
@@ -199,7 +199,7 @@
         Registry registry = getRegistry(parsed);
 
         String prefix = "";
-        if (parsed.port > 0 || !parsed.host.equals(""))
+        if (parsed.port > 0 || !parsed.host.isEmpty())
             prefix += "//" + parsed.host;
         if (parsed.port > 0)
             prefix += ":" + parsed.port;
--- a/src/java.rmi/share/classes/sun/rmi/server/ActivatableRef.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.rmi/share/classes/sun/rmi/server/ActivatableRef.java	Fri Dec 07 21:07:26 2018 -0500
@@ -370,7 +370,7 @@
         ref = null;
         String className = in.readUTF();
 
-        if (className.equals("")) return;
+        if (className.isEmpty()) return;
 
         try {
             Class<?> refClass = Class.forName(RemoteRef.packagePrefix + "." +
--- a/src/java.rmi/share/classes/sun/rmi/server/Activation.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.rmi/share/classes/sun/rmi/server/Activation.java	Fri Dec 07 21:07:26 2018 -0500
@@ -1857,7 +1857,7 @@
                         checkPermission(perms,
                             new ExecOptionPermission(option));
                     } catch (AccessControlException e) {
-                        if (value.equals("")) {
+                        if (value.isEmpty()) {
                             checkPermission(perms,
                                 new ExecOptionPermission("-D" + name));
                         } else {
@@ -2101,7 +2101,7 @@
              * Initialize method for activation exec policy.
              */
             if (!execPolicyClassName.equals("none")) {
-                if (execPolicyClassName.equals("") ||
+                if (execPolicyClassName.isEmpty() ||
                     execPolicyClassName.equals("default"))
                 {
                     execPolicyClassName = DefaultExecPolicy.class.getName();
--- a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java	Fri Dec 07 21:07:26 2018 -0500
@@ -738,7 +738,7 @@
                 }
                 hostName = f.getHost();
 
-                if ((hostName == null) || (hostName.equals(""))
+                if ((hostName == null) || (hostName.isEmpty())
                     || (hostName.indexOf('.') < 0 )) {
 
                     hostName = hostAddress;
--- a/src/java.scripting/share/classes/com/sun/tools/script/shell/Main.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.scripting/share/classes/com/sun/tools/script/shell/Main.java	Fri Dec 07 21:07:26 2018 -0500
@@ -114,7 +114,7 @@
                     System.setProperty(value.substring(0, eq),
                             value.substring(eq + 1));
                 } else {
-                    if (!value.equals("")) {
+                    if (!value.isEmpty()) {
                         System.setProperty(value, "");
                     } else {
                         // do not allow empty property name
--- a/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java	Fri Dec 07 21:07:26 2018 -0500
@@ -593,7 +593,7 @@
 
         super.setCommand(cmd);
 
-        if(!buildTableName(cmd).equals("")) {
+        if(!buildTableName(cmd).isEmpty()) {
             this.setTableName(buildTableName(cmd));
         }
     }
@@ -7069,7 +7069,7 @@
     public void setMatchColumn(String[] columnNames) throws SQLException {
 
         for(int j = 0; j < columnNames.length; j++) {
-           if( columnNames[j] == null || columnNames[j].equals("")) {
+           if( columnNames[j] == null || columnNames[j].isEmpty()) {
               throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString());
            }
         }
@@ -7124,7 +7124,7 @@
      */
     public void setMatchColumn(String columnName) throws SQLException {
         // validate, if col is ok to be set
-        if(columnName == null || (columnName= columnName.trim()).equals("") ) {
+        if(columnName == null || (columnName= columnName.trim()).isEmpty() ) {
             throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString());
         } else {
             // set strMatchColumn
--- a/src/java.sql.rowset/share/classes/com/sun/rowset/JdbcRowSetImpl.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.sql.rowset/share/classes/com/sun/rowset/JdbcRowSetImpl.java	Fri Dec 07 21:07:26 2018 -0500
@@ -624,7 +624,7 @@
                     (getDataSourceName());
                 //return ds.getConnection(getUsername(),getPassword());
 
-                if(getUsername() != null && !getUsername().equals("")) {
+                if(getUsername() != null && !getUsername().isEmpty()) {
                      return ds.getConnection(getUsername(),getPassword());
                 } else {
                      return ds.getConnection();
@@ -3873,7 +3873,7 @@
     public void setMatchColumn(String[] columnNames) throws SQLException {
 
         for(int j = 0; j < columnNames.length; j++) {
-           if( columnNames[j] == null || columnNames[j].equals("")) {
+           if( columnNames[j] == null || columnNames[j].isEmpty()) {
               throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols2").toString());
            }
         }
@@ -3928,7 +3928,7 @@
      */
     public void setMatchColumn(String columnName) throws SQLException {
         // validate, if col is ok to be set
-        if(columnName == null || (columnName= columnName.trim()).equals("")) {
+        if(columnName == null || (columnName= columnName.trim()).isEmpty()) {
             throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols2").toString());
         } else {
             // set strMatchColumn
--- a/src/java.sql.rowset/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.sql.rowset/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java	Fri Dec 07 21:07:26 2018 -0500
@@ -537,7 +537,7 @@
     private void writeStringData(String s) throws java.io.IOException {
         if (s == null) {
             writeNull();
-        } else if (s.equals("")) {
+        } else if (s.isEmpty()) {
             writeEmptyString();
         } else {
 
--- a/src/java.sql.rowset/share/classes/javax/sql/rowset/BaseRowSet.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.sql.rowset/share/classes/javax/sql/rowset/BaseRowSet.java	Fri Dec 07 21:07:26 2018 -0500
@@ -852,7 +852,7 @@
 
         if (name == null) {
             dataSource = null;
-        } else if (name.equals("")) {
+        } else if (name.isEmpty()) {
            throw new SQLException("DataSource name cannot be empty string");
         } else {
            dataSource = name;
--- a/src/java.sql/share/classes/java/sql/DriverManager.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.sql/share/classes/java/sql/DriverManager.java	Fri Dec 07 21:07:26 2018 -0500
@@ -622,7 +622,7 @@
 
             println("DriverManager.initialize: jdbc.drivers = " + drivers);
 
-            if (drivers != null && !drivers.equals("")) {
+            if (drivers != null && !drivers.isEmpty()) {
                 String[] driversList = drivers.split(":");
                 println("number of Drivers:" + driversList.length);
                 for (String aDriver : driversList) {
--- a/src/java.xml/share/classes/com/sun/xml/internal/stream/events/AttributeImpl.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.xml/share/classes/com/sun/xml/internal/stream/events/AttributeImpl.java	Fri Dec 07 21:07:26 2018 -0500
@@ -85,7 +85,7 @@
         init();
         fQName = qname ;
         fValue = value ;
-        if(type != null && !type.equals(""))
+        if(type != null && !type.isEmpty())
             fAttributeType = type;
 
         fNonNormalizedvalue = nonNormalizedvalue;
--- a/src/java.xml/share/classes/com/sun/xml/internal/stream/events/StartDocumentEvent.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.xml/share/classes/com/sun/xml/internal/stream/events/StartDocumentEvent.java	Fri Dec 07 21:07:26 2018 -0500
@@ -73,7 +73,7 @@
         this.fEncodingScheam = encoding;
         this.fVersion = version;
         this.fStandalone = standalone;
-        if (encoding != null && !encoding.equals(""))
+        if (encoding != null && !encoding.isEmpty())
             this.fEncodingSchemeSet = true;
         else {
             this.fEncodingSchemeSet = false;
--- a/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLDOMWriterImpl.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLDOMWriterImpl.java	Fri Dec 07 21:07:26 2018 -0500
@@ -219,7 +219,7 @@
             }
 
             String qualifiedName = null;
-            if(prefix.equals("")){
+            if(prefix.isEmpty()){
                 qualifiedName = localName;
             }else{
                 qualifiedName = getQName(prefix,localName);
@@ -254,7 +254,7 @@
                 throw new XMLStreamException("prefix cannot be null");
             }
             String qualifiedName = null;
-            if(prefix.equals("")){
+            if(prefix.isEmpty()){
                 qualifiedName = localName;
             }else{
 
@@ -502,7 +502,7 @@
 
         String qname = null;
 
-        if (prefix.equals("")) {
+        if (prefix.isEmpty()) {
             qname = XMLConstants.XMLNS_ATTRIBUTE;
         } else {
             qname = getQName(XMLConstants.XMLNS_ATTRIBUTE,prefix);
@@ -669,7 +669,7 @@
                 throw new XMLStreamException("Prefix cannot be null");
             }
 
-            if(prefix.equals("")){
+            if(prefix.isEmpty()){
                 qname = localName;
             }else{
                 qname = getQName(prefix,localName);
--- a/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java	Fri Dec 07 21:07:26 2018 -0500
@@ -628,8 +628,8 @@
             }
 
             if (!fIsRepairingNamespace) {
-                if (prefix == null || prefix.equals("")){
-                    if (!namespaceURI.equals("")) {
+                if (prefix == null || prefix.isEmpty()){
+                    if (!namespaceURI.isEmpty()) {
                         throw new XMLStreamException("prefix cannot be null or empty");
                     } else {
                         writeAttributeWithPrefix(null, localName, value);
@@ -908,7 +908,7 @@
                 } else {
                     fWriter.write(OPEN_END_TAG);
 
-                    if ((elem.prefix != null) && !(elem.prefix).equals("")) {
+                    if ((elem.prefix != null) && !(elem.prefix).isEmpty()) {
                         fWriter.write(elem.prefix);
                         fWriter.write(":");
                     }
@@ -945,7 +945,7 @@
             fWriter.write(OPEN_END_TAG);
 
             if ((currentElement.prefix != null) &&
-                    !(currentElement.prefix).equals("")) {
+                    !(currentElement.prefix).isEmpty()) {
                 fWriter.write(currentElement.prefix);
                 fWriter.write(":");
             }
@@ -1180,19 +1180,19 @@
             }
 
             // Verify the encoding before writing anything
-            if (encoding != null && !encoding.equals("")) {
+            if (encoding != null && !encoding.isEmpty()) {
                 verifyEncoding(encoding);
             }
 
             fWriter.write("<?xml version=\"");
 
-            if ((version == null) || version.equals("")) {
+            if ((version == null) || version.isEmpty()) {
                 fWriter.write(DEFAULT_XML_VERSION);
             } else {
                 fWriter.write(version);
             }
 
-            if (encoding != null && !encoding.equals("")) {
+            if (encoding != null && !encoding.isEmpty()) {
                 fWriter.write("\" encoding=\"");
                 fWriter.write(encoding);
             }
@@ -1584,7 +1584,7 @@
                     attr = fAttributeCache.get(j);
 
                     if ((attr.prefix != null) && (attr.uri != null)) {
-                        if (!attr.prefix.equals("") && !attr.uri.equals("") ) {
+                        if (!attr.prefix.isEmpty() && !attr.uri.isEmpty() ) {
                             String tmp = fInternalNamespaceContext.getPrefix(attr.uri);
 
                             if ((tmp == null) || (!tmp.equals(attr.prefix))) {
@@ -1765,7 +1765,7 @@
 
         for(int i=0 ; i< fAttributeCache.size();i++){
             attr = fAttributeCache.get(i);
-            if((attr.prefix != null && !attr.prefix.equals("")) || (attr.uri != null && !attr.uri.equals(""))) {
+            if((attr.prefix != null && !attr.prefix.isEmpty()) || (attr.uri != null && !attr.uri.isEmpty())) {
                 correctPrefix(currentElement,attr);
             }
         }
@@ -1773,7 +1773,7 @@
         if (!isDeclared(currentElement)) {
             if ((currentElement.prefix != null) &&
                     (currentElement.uri != null)) {
-                if ((!currentElement.prefix.equals("")) && (!currentElement.uri.equals(""))) {
+                if ((!currentElement.prefix.isEmpty()) && (!currentElement.uri.isEmpty())) {
                     fNamespaceDecls.add(currentElement);
                 }
             }
@@ -1798,7 +1798,7 @@
             /* If 'attr' is an attribute and it is in no namespace(which means that prefix="", uri=""), attr's
                namespace should not be redinded. See [http://www.w3.org/TR/REC-xml-names/#defaulting].
              */
-            if (attr.prefix != null && attr.prefix.equals("") && attr.uri != null && attr.uri.equals("")){
+            if (attr.prefix != null && attr.prefix.isEmpty() && attr.uri != null && attr.uri.isEmpty()){
                 repairNamespaceDecl(attr);
             }
         }
--- a/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java	Fri Dec 07 21:07:26 2018 -0500
@@ -619,13 +619,13 @@
     private boolean getSystemProperty(Feature cf, String sysPropertyName) {
         if (cf.hasSystemProperty()) {
             String value = SecuritySupport.getSystemProperty(sysPropertyName);
-            if (value != null && !value.equals("")) {
+            if (value != null && !value.isEmpty()) {
                 setProperty(cf, State.SYSTEMPROPERTY, value);
                 return true;
             }
 
             value = SecuritySupport.readJAXPProperty(sysPropertyName);
-            if (value != null && !value.equals("")) {
+            if (value != null && !value.isEmpty()) {
                 setProperty(cf, State.JAXPDOTPROPERTIES, value);
                 return true;
             }
--- a/src/java.xml/share/classes/javax/xml/catalog/Util.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.xml/share/classes/javax/xml/catalog/Util.java	Fri Dec 07 21:07:26 2018 -0500
@@ -221,7 +221,7 @@
      */
     static String[] getCatalogFiles(String sysPropertyName) {
         String value = SecuritySupport.getJAXPSystemProperty(sysPropertyName);
-        if (value != null && !value.equals("")) {
+        if (value != null && !value.isEmpty()) {
             return value.split(";");
         }
         return null;
--- a/src/java.xml/share/classes/jdk/xml/internal/JdkXmlFeatures.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/java.xml/share/classes/jdk/xml/internal/JdkXmlFeatures.java	Fri Dec 07 21:07:26 2018 -0500
@@ -383,13 +383,13 @@
     private boolean getSystemProperty(XmlFeature feature, String sysPropertyName) {
         try {
             String value = SecuritySupport.getSystemProperty(sysPropertyName);
-            if (value != null && !value.equals("")) {
+            if (value != null && !value.isEmpty()) {
                 setFeature(feature, State.SYSTEMPROPERTY, Boolean.parseBoolean(value));
                 return true;
             }
 
             value = SecuritySupport.readJAXPProperty(sysPropertyName);
-            if (value != null && !value.equals("")) {
+            if (value != null && !value.isEmpty()) {
                 setFeature(feature, State.JAXPDOTPROPERTIES, Boolean.parseBoolean(value));
                 return true;
             }
--- a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java	Fri Dec 07 21:07:26 2018 -0500
@@ -1180,7 +1180,7 @@
         String name = entry.name;
         boolean isDir = entry.isDir;
 
-        if (name.equals("") || name.equals(".") || name.equals(zname)) {
+        if (name.isEmpty() || name.equals(".") || name.equals(zname)) {
             return;
         } else if ((name.equals(MANIFEST_DIR) || name.equals(MANIFEST_NAME))
                    && !Mflag) {
@@ -1886,7 +1886,7 @@
                 .map(ModuleInfoEntry::name)
                 .map(Main::versionFromEntryName)
                 .collect(joining(" "));
-        if (!releases.equals(""))
+        if (!releases.isEmpty())
             output("releases: " + releases + "\n");
 
         // Describe the operative descriptor for the specified --release, if any
@@ -1955,7 +1955,7 @@
 
         sb.append(md.toNameAndVersion());
 
-        if (!uriString.equals(""))
+        if (!uriString.isEmpty())
             sb.append(" ").append(uriString);
         if (md.isOpen())
             sb.append(" open");
--- a/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ClassDocImpl.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ClassDocImpl.java	Fri Dec 07 21:07:26 2018 -0500
@@ -420,7 +420,7 @@
         } else {
             String n = "";
             for ( ; c != null; c = c.owner.enclClass()) {
-                n = c.name + (n.equals("") ? "" : ".") + n;
+                n = c.name + (n.isEmpty() ? "" : ".") + n;
             }
             return n;
         }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SearchIndexItem.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SearchIndexItem.java	Fri Dec 07 21:07:26 2018 -0500
@@ -114,18 +114,18 @@
                 item.append("\"m\":\"").append(containingModule).append("\",");
             }
             item.append("\"l\":\"").append(label).append("\"");
-            if (!url.equals("")) {
+            if (!url.isEmpty()) {
                 item.append(",\"url\":\"").append(url).append("\"");
             }
             item.append("}");
             break;
         case TYPES:
             item.append("{");
-            if (!containingPackage.equals("")) {
+            if (!containingPackage.isEmpty()) {
                 item.append("\"p\":\"").append(containingPackage).append("\",");
             }
             item.append("\"l\":\"").append(label).append("\"");
-            if (!url.equals("")) {
+            if (!url.isEmpty()) {
                 item.append(",\"url\":\"").append(url).append("\"");
             }
             item.append("}");
@@ -135,7 +135,7 @@
                     .append("\"p\":\"").append(containingPackage).append("\",")
                     .append("\"c\":\"").append(containingClass).append("\",")
                     .append("\"l\":\"").append(label).append("\"");
-            if (!url.equals("")) {
+            if (!url.isEmpty()) {
                 item.append(",\"url\":\"").append(url).append("\"");
             }
             item.append("}");
@@ -144,7 +144,7 @@
             item.append("{")
                     .append("\"l\":\"").append(label).append("\",")
                     .append("\"h\":\"").append(holder).append("\",");
-            if (!description.equals("")) {
+            if (!description.isEmpty()) {
                 item.append("\"d\":\"").append(description).append("\",");
             }
             item.append("\"u\":\"").append(url).append("\"")
--- a/src/jdk.jcmd/share/classes/sun/tools/jmap/JMap.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.jcmd/share/classes/sun/tools/jmap/JMap.java	Fri Dec 07 21:07:26 2018 -0500
@@ -149,7 +149,7 @@
         throws AttachNotSupportedException, IOException,
                UnsupportedEncodingException {
         String liveopt = "-all";
-        if (options.equals("") || options.equals("all")) {
+        if (options.isEmpty() || options.equals("all")) {
             //  pass
         }
         else if (options.equals("live")) {
--- a/src/jdk.jconsole/share/classes/sun/tools/jconsole/ConnectDialog.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.jconsole/share/classes/sun/tools/jconsole/ConnectDialog.java	Fri Dec 07 21:07:26 2018 -0500
@@ -313,9 +313,9 @@
                 if (remoteRadioButton.isSelected()) {
                     String txt = remoteTF.getText().trim();
                     String userName = userNameTF.getText().trim();
-                    userName = userName.equals("") ? null : userName;
+                    userName = userName.isEmpty() ? null : userName;
                     String password = passwordTF.getText();
-                    password = password.equals("") ? null : password;
+                    password = password.isEmpty() ? null : password;
                     try {
                         if (txt.startsWith(JConsole.ROOT_URL)) {
                             String url = txt;
--- a/src/jdk.jconsole/share/classes/sun/tools/jconsole/ThreadTab.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.jconsole/share/classes/sun/tools/jconsole/ThreadTab.java	Fri Dec 07 21:07:26 2018 -0500
@@ -665,7 +665,7 @@
         }
 
         public void focusLost(FocusEvent e) {
-            if (promptRemoved && getText().equals("")) {
+            if (promptRemoved && getText().isEmpty()) {
                 setText(prompt);
                 setForeground(Color.gray);
                 promptRemoved = false;
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java	Fri Dec 07 21:07:26 2018 -0500
@@ -65,6 +65,8 @@
 
 public final class Utils {
 
+    private static final String INFINITY = "infinity";
+
     private static Boolean SAVE_GENERATED;
 
     public static final String EVENTS_PACKAGE_NAME = "jdk.jfr.events";
@@ -117,7 +119,6 @@
         if (dValue == null) {
             return "0";
         }
-
         long value = dValue.toNanos();
         TimespanUnit result = TimespanUnit.NANOSECONDS;
         for (TimespanUnit unit : TimespanUnit.values()) {
@@ -131,6 +132,13 @@
         return String.format("%d%s%s", value, separation, result.text);
     }
 
+    public static long parseTimespanWithInfinity(String s) {
+        if (INFINITY.equals(s)) {
+            return Long.MAX_VALUE;
+        }
+        return parseTimespan(s);
+    }
+
     public static long parseTimespan(String s) {
         if (s.endsWith("ns")) {
             return Long.parseLong(s.substring(0, s.length() - 2).trim());
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CutoffSetting.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CutoffSetting.java	Fri Dec 07 21:07:26 2018 -0500
@@ -28,11 +28,11 @@
 import java.util.Objects;
 import java.util.Set;
 
-import jdk.jfr.BooleanFlag;
 import jdk.jfr.Description;
 import jdk.jfr.Label;
 import jdk.jfr.MetadataDefinition;
 import jdk.jfr.Name;
+import jdk.jfr.Timespan;
 import jdk.jfr.internal.Control;
 import jdk.jfr.internal.PlatformEventType;
 import jdk.jfr.internal.Type;
@@ -42,7 +42,7 @@
 @Label("Cutoff")
 @Description("Limit running time of event")
 @Name(Type.SETTINGS_PREFIX + "Cutoff")
-@BooleanFlag
+@Timespan
 public final class CutoffSetting extends Control {
     private final static long typeId = Type.getTypeId(CutoffSetting.class);
 
@@ -59,7 +59,7 @@
         long max = 0;
         String text = "0 ns";
         for (String value : values) {
-            long l = parseValue(value);
+            long l =  Utils.parseTimespanWithInfinity(value);
             if (l > max) {
                 text = value;
                 max = l;
@@ -70,15 +70,11 @@
 
     @Override
     public void setValue(String value) {
-        long l = parseValue(value);
+        long l =  Utils.parseTimespanWithInfinity(value);
         this.value = value;
         eventType.setCutoff(l);
     }
 
-    private long parseValue(String value) {
-        return isInfinity(value) ? Long.MAX_VALUE : Utils.parseTimespan(value);
-    }
-
     @Override
     public String getValue() {
         return value;
@@ -88,16 +84,12 @@
         return CutoffSetting.typeId == typeId;
     }
 
-    private static boolean isInfinity(String s) {
-        return s.equals("infinity");
-    }
-
     public static long parseValueSafe(String value) {
         if (value == null) {
             return 0L;
         }
         try {
-            return isInfinity(value) ? Long.MAX_VALUE : Utils.parseTimespan(value);
+            return Utils.parseTimespanWithInfinity(value);
         } catch (NumberFormatException nfe) {
             return 0L;
         }
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/PeriodSetting.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/PeriodSetting.java	Fri Dec 07 21:07:26 2018 -0500
@@ -58,10 +58,11 @@
 
     @Override
     public String combine(Set<String> values) {
-        long min = Long.MAX_VALUE;
+
         boolean beginChunk = false;
         boolean endChunk = false;
-        String text = EVERY_CHUNK;
+        Long min = null;
+        String text = null;
         for (String value : values) {
             switch (value) {
             case EVERY_CHUNK:
@@ -75,14 +76,21 @@
                 endChunk = true;
                 break;
             default:
-                long l = Utils.parseTimespan(value);
-                if (l < min) {
+                long l = Utils.parseTimespanWithInfinity(value);
+                // Always accept first specified value
+                if (min == null) {
                     text = value;
                     min = l;
+                } else {
+                    if (l < min) {
+                        text = value;
+                        min = l;
+                    }
                 }
             }
         }
-        if (min != Long.MAX_VALUE) {
+        // A specified interval trumps *_CHUNK
+        if (min != null) {
             return text;
         }
         if (beginChunk && !endChunk) {
@@ -91,7 +99,7 @@
         if (!beginChunk && endChunk) {
             return END_CHUNK;
         }
-        return text;
+        return EVERY_CHUNK; // also default
     }
 
     @Override
@@ -107,7 +115,12 @@
             eventType.setPeriod(0, false, true);
             break;
         default:
-            eventType.setPeriod(Utils.parseTimespan(value) / 1_000_000, false, false);
+            long nanos = Utils.parseTimespanWithInfinity(value);
+            if (nanos != Long.MAX_VALUE) {
+                eventType.setPeriod(nanos / 1_000_000, false, false);
+            } else {
+                eventType.setPeriod(Long.MAX_VALUE, false, false);
+            }
         }
         this.value = value;
     }
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThresholdSetting.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThresholdSetting.java	Fri Dec 07 21:07:26 2018 -0500
@@ -54,21 +54,27 @@
 
     @Override
     public String combine(Set<String> values) {
-        long min = Long.MAX_VALUE;
-        String text = "0 ns";
+        Long min = null;
+        String text = null;
         for (String value : values) {
-            long l = Utils.parseTimespan(value);
-            if (l < min) {
+            long l = Utils.parseTimespanWithInfinity(value);
+            // always accept first value
+            if (min == null) {
+                min = l;
                 text = value;
-                min = l;
+            } else {
+                if (l < min) {
+                    text = value;
+                    min = l;
+                }
             }
         }
-        return text;
+        return text == null ? "0 ns" : text;
     }
 
     @Override
     public void setValue(String value) {
-        long l = Utils.parseTimespan(value);
+        long l = Utils.parseTimespanWithInfinity(value);
         this.value = value;
         eventType.setThreshold(l);
     }
--- a/src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java	Fri Dec 07 21:07:26 2018 -0500
@@ -265,7 +265,7 @@
     // return empty property set
     private static Properties parseString(String args) {
         Properties argProps = new Properties();
-        if (args != null && !args.trim().equals("")) {
+        if (args != null && !args.trim().isEmpty()) {
             for (String option : args.split(",")) {
                 String s[] = option.split("=", 2);
                 String name = s[0].trim();
--- a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsContext.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsContext.java	Fri Dec 07 21:07:26 2018 -0500
@@ -537,8 +537,8 @@
         int prefixLast = prefixC.size() - 1;
 
         // Let toolkit do the work at namespace boundaries.
-        if (nameC.isEmpty() || nameC.get(0).equals("") ||
-                prefixC.isEmpty() || prefixC.get(prefixLast).equals("")) {
+        if (nameC.isEmpty() || nameC.get(0).isEmpty() ||
+                prefixC.isEmpty() || prefixC.get(prefixLast).isEmpty()) {
             return super.composeName(nameC, prefixC);
         }
 
@@ -687,7 +687,7 @@
     private static CT fromAttrId(String attrId)
             throws InvalidAttributeIdentifierException {
 
-        if (attrId.equals("")) {
+        if (attrId.isEmpty()) {
             throw new InvalidAttributeIdentifierException(
                     "Attribute ID cannot be empty");
         }
--- a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsName.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsName.java	Fri Dec 07 21:07:26 2018 -0500
@@ -368,7 +368,7 @@
 
     boolean hasRootLabel() {
         return (!isEmpty() &&
-                get(0).equals(""));
+                get(0).isEmpty());
     }
 
     /*
@@ -442,7 +442,7 @@
         // label of the name.  Those two are special cases in that for
         // all other domain names, the number of labels is one greater
         // than the number of dot separators.
-        if (!name.equals("") && !name.equals(".")) {
+        if (!name.isEmpty() && !name.equals(".")) {
             add(0, label.toString());
         }
 
--- a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsUrl.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsUrl.java	Fri Dec 07 21:07:26 2018 -0500
@@ -89,7 +89,7 @@
         domain = path.startsWith("/")
             ? path.substring(1)
             : path;
-        domain = domain.equals("")
+        domain = domain.isEmpty()
             ? "."
             : UrlUtil.decode(domain);
 
--- a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/ResourceRecord.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/ResourceRecord.java	Fri Dec 07 21:07:26 2018 -0500
@@ -200,7 +200,7 @@
     }
 
     private static int nameToValue(String name, String[] names) {
-        if (name.equals("")) {
+        if (name.isEmpty()) {
             return -1;                          // invalid name
         } else if (name.equals("*")) {
             return QTYPE_STAR;                  // QTYPE_STAR == QCLASS_STAR
--- a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/ZoneNode.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/ZoneNode.java	Fri Dec 07 21:07:26 2018 -0500
@@ -124,7 +124,7 @@
      * name and its resource records.  Returns the zone's new contents.
      */
     NameNode populate(DnsName zone, ResourceRecords rrs) {
-        // assert zone.get(0).equals("");               // zone has root label
+        // assert zone.get(0).isEmpty();               // zone has root label
         // assert (zone.size() == (depth() + 1));       // +1 due to root label
 
         NameNode newContents = new NameNode(null);
--- a/src/jdk.rmic/share/classes/sun/tools/java/ClassPath.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.rmic/share/classes/sun/tools/java/ClassPath.java	Fri Dec 07 21:07:26 2018 -0500
@@ -230,7 +230,7 @@
             int i = name.lastIndexOf(File.separatorChar);
             subdir = name.substring(0, i + 1);
             basename = name.substring(i + 1);
-        } else if (!subdir.equals("")
+        } else if (!subdir.isEmpty()
                    && !subdir.endsWith(fileSeparatorChar)) {
             // zip files are picky about "foo" vs. "foo/".
             // also, the getFiles caches are keyed with a trailing /
--- a/src/jdk.rmic/share/classes/sun/tools/java/Package.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/src/jdk.rmic/share/classes/sun/tools/java/Package.java	Fri Dec 07 21:07:26 2018 -0500
@@ -115,7 +115,7 @@
     }
 
     private String makeName(String fileName) {
-        return pkg.equals("") ? fileName : pkg + File.separator + fileName;
+        return pkg.isEmpty() ? fileName : pkg + File.separator + fileName;
     }
 
     /**
@@ -153,7 +153,7 @@
     }
 
     public String toString() {
-        if (pkg.equals("")) {
+        if (pkg.isEmpty()) {
             return "unnamed package";
         }
         return "package " + pkg;
--- a/test/hotspot/jtreg/serviceability/tmtools/jstack/WaitNotifyThreadTest.java	Fri Dec 07 19:07:08 2018 -0500
+++ b/test/hotspot/jtreg/serviceability/tmtools/jstack/WaitNotifyThreadTest.java	Fri Dec 07 21:07:26 2018 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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
@@ -41,9 +41,9 @@
     private Object monitor = new Object();
     private final String OBJECT = "a java.lang.Object";
     private final String OBJECT_WAIT = "java.lang.Object.wait";
+    private final String RUN_METHOD = "WaitNotifyThreadTest$WaitThread.run";
 
     interface Action {
-
         void doAction(Thread thread);
     }
 
@@ -51,10 +51,12 @@
 
         @Override
         public void doAction(Thread thread) {
-            //Notify the waiting thread, so it stops waiting and sleeps
+            // Notify the waiting thread, so it stops waiting and sleeps
             synchronized (monitor) {
                 monitor.notifyAll();
             }
+            // Wait until MyWaitingThread exits the monitor and sleeps
+            while (thread.getState() != Thread.State.TIMED_WAITING) {}
         }
     }
 
@@ -64,6 +66,8 @@
         public void doAction(Thread thread) {
             // Interrupt the thread
             thread.interrupt();
+            // Wait until MyWaitingThread exits the monitor and sleeps
+            while (thread.getState() != Thread.State.TIMED_WAITING) {}
         }
     }
 
@@ -99,10 +103,12 @@
 
         final String WAITING_THREAD_NAME = "MyWaitingThread";
 
-        // Start athread that just waits
+        // Start a thread that just waits
         WaitThread waitThread = new WaitThread();
         waitThread.setName(WAITING_THREAD_NAME);
         waitThread.start();
+        // Wait until MyWaitingThread enters the monitor
+        while (waitThread.getState() != Thread.State.WAITING) {}
 
         // Collect output from the jstack tool
         JstackTool jstackTool = new JstackTool(ProcessHandle.current().pid());
@@ -122,7 +128,6 @@
         JStack jstack2 = new DefaultFormat().parse(results.getStdoutString());
         ThreadStack ti2 = jstack2.getThreadStack(WAITING_THREAD_NAME);
         analyzeThreadStackNoWaiting(ti2);
-
     }
 
     private void analyzeThreadStackWaiting(ThreadStack ti1) {
@@ -134,45 +139,39 @@
             if (mi.getName().startsWith(OBJECT_WAIT) && mi.getCompilationUnit() == null /*native method*/) {
                 if (mi.getLocks().size() == 1) {
                     MonitorInfo monInfo = mi.getLocks().getFirst();
-                    if (monInfo.getType().equals("waiting on") && compareMonitorClass(monInfo)) {
-                        monitorAddress = monInfo.getMonitorAddress();
-                    } else {
-                        System.err.println("Error: incorrect monitor info: " + monInfo.getType() + ", " + monInfo.getMonitorClass());
-                        throw new RuntimeException("Incorrect lock record in "
-                                + OBJECT_WAIT + " method");
-                    }
-
+                    monitorAddress = monInfo.getMonitorAddress();
+                    assertMonitorInfo("waiting on", monInfo, monitorAddress, OBJECT_WAIT);
                 } else {
-                    throw new RuntimeException(OBJECT_WAIT
-                            + " method has to contain one lock record bu it contains " + mi.getLocks().size());
+                    throw new RuntimeException(OBJECT_WAIT + " method has to contain one lock record but it contains "
+                                               + mi.getLocks().size());
                 }
             }
 
-            if (mi.getName().startsWith("WaitThread.run")) {
+            if (mi.getName().startsWith(RUN_METHOD)) {
                 if (monitorAddress == null) {
                     throw new RuntimeException("Cannot found monitor info associated with " + OBJECT_WAIT + " method");
                 }
-
-                int numLocks = mi.getLocks().size();
-                for (int i = 0; i < numLocks - 1; ++i) {
-                    assertMonitorInfo("waiting to re-lock in wait()", mi.getLocks().get(i), monitorAddress);
+                if (mi.getLocks().size() == 1) {
+                    assertMonitorInfo("locked", mi.getLocks().getLast(), monitorAddress, RUN_METHOD);
                 }
-                assertMonitorInfo("locked", mi.getLocks().getLast(), monitorAddress);
+                else {
+                    throw new RuntimeException(RUN_METHOD + " method has to contain one lock record but it contains "
+                                               + mi.getLocks().size());
+                }
             }
         }
-
     }
 
-    private void assertMonitorInfo(String expectedMessage, MonitorInfo monInfo, String monitorAddress) {
+    private void assertMonitorInfo(String expectedMessage, MonitorInfo monInfo, String monitorAddress, String method) {
         if (monInfo.getType().equals(expectedMessage)
                 && compareMonitorClass(monInfo)
                 && monInfo.getMonitorAddress().equals(
                         monitorAddress)) {
-            System.out.println("Correct monitor info found");
+            System.out.println("Correct monitor info found in " + method + " method");
         } else {
             System.err.println("Error: incorrect monitor info: " + monInfo.getType() + ", " + monInfo.getMonitorClass() + ", " + monInfo.getMonitorAddress());
             System.err.println("Expected: " + expectedMessage + ", a java.lang.Object, " + monitorAddress);
-            throw new RuntimeException("Incorrect lock record in 'run' method");
+            throw new RuntimeException("Incorrect lock record in " + method + " method");
         }
     }