changeset 10901:0d1533092ef8

Merge
author andrew
date Tue, 19 Jan 2021 20:49:42 +0000
parents aa3d863d3ab5 (diff) 54f222098a52 (current diff)
children b316aa340b90
files
diffstat 29 files changed, 378 insertions(+), 155 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Tue Jan 19 19:55:37 2021 +0000
+++ b/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Tue Jan 19 20:49:42 2021 +0000
@@ -908,9 +908,7 @@
     sub(current_header, current_header, R1_SP);
 
     assert(os::vm_page_size() > 0xfff, "page size too small - change the constant");
-    load_const_optimized(tmp,
-                         (address) (~(os::vm_page_size()-1) |
-                                    markOopDesc::lock_mask_in_place));
+    load_const_optimized(tmp, ~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place);
 
     and_(R0/*==0?*/, current_header, tmp);
     // If condition is true we are done and hence we can store 0 in the displaced
--- a/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Tue Jan 19 19:55:37 2021 +0000
+++ b/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Tue Jan 19 20:49:42 2021 +0000
@@ -2046,8 +2046,7 @@
   // Check if the owner is self by comparing the value in the markOop of object
   // (current_header) with the stack pointer.
   sub(current_header, current_header, R1_SP);
-  load_const_optimized(temp, (address) (~(os::vm_page_size()-1) |
-                                        markOopDesc::lock_mask_in_place));
+  load_const_optimized(temp, ~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place);
 
   and_(R0/*==0?*/, current_header, temp);
   // If condition is true we are cont and hence we can store 0 as the
--- a/src/os/linux/vm/osContainer_linux.cpp	Tue Jan 19 19:55:37 2021 +0000
+++ b/src/os/linux/vm/osContainer_linux.cpp	Tue Jan 19 20:49:42 2021 +0000
@@ -115,7 +115,25 @@
     }
 };
 
-CgroupSubsystem* memory = NULL;
+class CgroupMemorySubsystem: CgroupSubsystem {
+ friend class OSContainer;
+
+ private:
+    /* Some container runtimes set limits via cgroup
+     * hierarchy. If set to true consider also memory.stat
+     * file if everything else seems unlimited */
+    bool _uses_mem_hierarchy;
+
+ public:
+    CgroupMemorySubsystem(char *root, char *mountpoint) : CgroupSubsystem::CgroupSubsystem(root, mountpoint) {
+      _uses_mem_hierarchy = false;
+    }
+
+    bool is_hierarchical() { return _uses_mem_hierarchy; }
+    void set_hierarchical(bool value) { _uses_mem_hierarchy = value; }
+};
+
+CgroupMemorySubsystem* memory = NULL;
 CgroupSubsystem* cpuset = NULL;
 CgroupSubsystem* cpu = NULL;
 CgroupSubsystem* cpuacct = NULL;
@@ -124,24 +142,27 @@
 
 PRAGMA_DIAG_PUSH
 PRAGMA_FORMAT_NONLITERAL_IGNORED
-template <typename T> int subsystem_file_contents(CgroupSubsystem* c,
+template <typename T> int subsystem_file_line_contents(CgroupSubsystem* c,
                                               const char *filename,
+                                              const char *matchline,
                                               const char *scan_fmt,
                                               T returnval) {
   FILE *fp = NULL;
   char *p;
   char file[MAXPATHLEN+1];
   char buf[MAXPATHLEN+1];
+  char discard[MAXPATHLEN+1];
+  bool found_match = false;
 
   if (c == NULL) {
     if (PrintContainerInfo) {
-      tty->print_cr("subsystem_file_contents: CgroupSubsytem* is NULL");
+      tty->print_cr("subsystem_file_line_contents: CgroupSubsytem* is NULL");
     }
     return OSCONTAINER_ERROR;
   }
   if (c->subsystem_path() == NULL) {
     if (PrintContainerInfo) {
-      tty->print_cr("subsystem_file_contents: subsystem path is NULL");
+      tty->print_cr("subsystem_file_line_contents: subsystem path is NULL");
     }
     return OSCONTAINER_ERROR;
   }
@@ -161,19 +182,33 @@
   }
   fp = fopen(file, "r");
   if (fp != NULL) {
-    p = fgets(buf, MAXPATHLEN, fp);
-    if (p != NULL) {
-      int matched = sscanf(p, scan_fmt, returnval);
-      if (matched == 1) {
+    int err = 0;
+    while ((p = fgets(buf, MAXPATHLEN, fp)) != NULL) {
+      found_match = false;
+      if (matchline == NULL) {
+        // single-line file case
+        int matched = sscanf(p, scan_fmt, returnval);
+        found_match = (matched == 1);
+      } else {
+        // multi-line file case
+        if (strstr(p, matchline) != NULL) {
+          // discard matchline string prefix
+          int matched = sscanf(p, scan_fmt, discard, returnval);
+          found_match = (matched == 2);
+        } else {
+          continue; // substring not found
+        }
+      }
+      if (found_match) {
         fclose(fp);
         return 0;
       } else {
+        err = 1;
         if (PrintContainerInfo) {
           tty->print_cr("Type %s not found in file %s", scan_fmt, file);
         }
       }
-    } else {
-      if (PrintContainerInfo) {
+      if (err == 0 && PrintContainerInfo) {
         tty->print_cr("Empty file %s", file);
       }
     }
@@ -193,10 +228,11 @@
   return_type variable;                                                   \
 {                                                                         \
   int err;                                                                \
-  err = subsystem_file_contents(subsystem,                                \
-                                filename,                                 \
-                                scan_fmt,                                 \
-                                &variable);                               \
+  err = subsystem_file_line_contents(subsystem,                           \
+                                     filename,                            \
+                                     NULL,                                \
+                                     scan_fmt,                            \
+                                     &variable);                          \
   if (err != 0)                                                           \
     return (return_type) OSCONTAINER_ERROR;                               \
                                                                           \
@@ -209,10 +245,11 @@
   char variable[bufsize];                                                 \
 {                                                                         \
   int err;                                                                \
-  err = subsystem_file_contents(subsystem,                                \
-                                filename,                                 \
-                                scan_fmt,                                 \
-                                variable);                                \
+  err = subsystem_file_line_contents(subsystem,                           \
+                                     filename,                            \
+                                     NULL,                                \
+                                     scan_fmt,                            \
+                                     variable);                           \
   if (err != 0)                                                           \
     return (return_type) NULL;                                            \
                                                                           \
@@ -220,6 +257,24 @@
     tty->print_cr(logstring, variable);                                   \
 }
 
+#define GET_CONTAINER_INFO_LINE(return_type, subsystem, filename,         \
+                           matchline, logstring, scan_fmt, variable)      \
+  return_type variable;                                                   \
+{                                                                         \
+  int err;                                                                \
+  err = subsystem_file_line_contents(subsystem,                           \
+                                filename,                                 \
+                                matchline,                                \
+                                scan_fmt,                                 \
+                                &variable);                               \
+  if (err != 0)                                                           \
+    return (return_type) OSCONTAINER_ERROR;                               \
+                                                                          \
+  if (PrintContainerInfo)                                                 \
+    tty->print_cr(logstring, variable);                                   \
+}
+
+
 /* init
  *
  * Initialize the container support and determine if
@@ -281,7 +336,7 @@
     }
     while ((token = strsep(&cptr, ",")) != NULL) {
       if (strcmp(token, "memory") == 0) {
-        memory = new CgroupSubsystem(tmproot, tmpmount);
+        memory = new CgroupMemorySubsystem(tmproot, tmpmount);
       } else if (strcmp(token, "cpuset") == 0) {
         cpuset = new CgroupSubsystem(tmproot, tmpmount);
       } else if (strcmp(token, "cpu") == 0) {
@@ -368,6 +423,10 @@
     while ((token = strsep(&controllers, ",")) != NULL) {
       if (strcmp(token, "memory") == 0) {
         memory->set_subsystem_path(base);
+        jlong hierarchy = uses_mem_hierarchy();
+        if (hierarchy > 0) {
+          memory->set_hierarchical(true);
+        }
       } else if (strcmp(token, "cpuset") == 0) {
         cpuset->set_subsystem_path(base);
       } else if (strcmp(token, "cpu") == 0) {
@@ -384,6 +443,9 @@
   // command line arguments have been processed.
   if ((mem_limit = memory_limit_in_bytes()) > 0) {
     os::Linux::set_physical_memory(mem_limit);
+    if (PrintContainerInfo) {
+      tty->print_cr("Memory Limit is: " JLONG_FORMAT, mem_limit);
+    }
   }
 
   _is_containerized = true;
@@ -398,6 +460,21 @@
   }
 }
 
+/* uses_mem_hierarchy
+ *
+ * Return whether or not hierarchical cgroup accounting is being
+ * done.
+ *
+ * return:
+ *    A number > 0 if true, or
+ *    OSCONTAINER_ERROR for not supported
+ */
+jlong OSContainer::uses_mem_hierarchy() {
+  GET_CONTAINER_INFO(jlong, memory, "/memory.use_hierarchy",
+                    "Use Hierarchy is: " JLONG_FORMAT, JLONG_FORMAT, use_hierarchy);
+  return use_hierarchy;
+}
+
 
 /* memory_limit_in_bytes
  *
@@ -414,7 +491,20 @@
 
   if (memlimit >= _unlimited_memory) {
     if (PrintContainerInfo) {
-      tty->print_cr("Memory Limit is: Unlimited");
+      tty->print_cr("Non-Hierarchical Memory Limit is: Unlimited");
+    }
+    if (memory->is_hierarchical()) {
+      const char* matchline = "hierarchical_memory_limit";
+      char* format = "%s " JULONG_FORMAT;
+      GET_CONTAINER_INFO_LINE(julong, memory, "/memory.stat", matchline,
+                             "Hierarchical Memory Limit is: " JULONG_FORMAT, format, hier_memlimit)
+      if (hier_memlimit >= _unlimited_memory) {
+        if (PrintContainerInfo) {
+          tty->print_cr("Hierarchical Memory Limit is: Unlimited");
+        }
+      } else {
+        return (jlong)hier_memlimit;
+      }
     }
     return (jlong)-1;
   }
@@ -428,7 +518,20 @@
                      "Memory and Swap Limit is: " JULONG_FORMAT, JULONG_FORMAT, memswlimit);
   if (memswlimit >= _unlimited_memory) {
     if (PrintContainerInfo) {
-      tty->print_cr("Memory and Swap Limit is: Unlimited");
+      tty->print_cr("Non-Hierarchical Memory and Swap Limit is: Unlimited");
+    }
+    if (memory->is_hierarchical()) {
+      const char* matchline = "hierarchical_memsw_limit";
+      char* format = "%s " JULONG_FORMAT;
+      GET_CONTAINER_INFO_LINE(julong, memory, "/memory.stat", matchline,
+                             "Hierarchical Memory and Swap Limit is : " JULONG_FORMAT, format, hier_memlimit)
+      if (hier_memlimit >= _unlimited_memory) {
+        if (PrintContainerInfo) {
+          tty->print_cr("Hierarchical Memory and Swap Limit is: Unlimited");
+        }
+      } else {
+        return (jlong)hier_memlimit;
+      }
     }
     return (jlong)-1;
   } else {
--- a/src/os/linux/vm/osContainer_linux.hpp	Tue Jan 19 19:55:37 2021 +0000
+++ b/src/os/linux/vm/osContainer_linux.hpp	Tue Jan 19 20:49:42 2021 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -46,6 +46,7 @@
   static inline bool is_containerized();
   static const char * container_type();
 
+  static jlong uses_mem_hierarchy();
   static jlong memory_limit_in_bytes();
   static jlong memory_and_swap_limit_in_bytes();
   static jlong memory_soft_limit_in_bytes();
--- a/src/os/linux/vm/os_linux.cpp	Tue Jan 19 19:55:37 2021 +0000
+++ b/src/os/linux/vm/os_linux.cpp	Tue Jan 19 20:49:42 2021 +0000
@@ -5801,7 +5801,6 @@
 PRAGMA_DIAG_PUSH
 PRAGMA_FORMAT_NONLITERAL_IGNORED
 static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
-  static bool proc_task_unchecked = true;
   pid_t  tid = thread->osthread()->thread_id();
   char *s;
   char stat[2048];
@@ -5814,24 +5813,7 @@
   long ldummy;
   FILE *fp;
 
-  snprintf(proc_name, 64, "/proc/%d/stat", tid);
-
-  // The /proc/<tid>/stat aggregates per-process usage on
-  // new Linux kernels 2.6+ where NPTL is supported.
-  // The /proc/self/task/<tid>/stat still has the per-thread usage.
-  // See bug 6328462.
-  // There possibly can be cases where there is no directory
-  // /proc/self/task, so we check its availability.
-  if (proc_task_unchecked && os::Linux::is_NPTL()) {
-    // This is executed only once
-    proc_task_unchecked = false;
-    fp = fopen("/proc/self/task", "r");
-    if (fp != NULL) {
-      snprintf(proc_name, 64, "/proc/self/task/%d/stat", tid);
-      fclose(fp);
-    }
-  }
-
+  snprintf(proc_name, 64, "/proc/self/task/%d/stat", tid);
   fp = fopen(proc_name, "r");
   if ( fp == NULL ) return -1;
   statlen = fread(stat, 1, 2047, fp);
--- a/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp	Tue Jan 19 19:55:37 2021 +0000
+++ b/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp	Tue Jan 19 20:49:42 2021 +0000
@@ -264,7 +264,7 @@
     while (n <= next_boundary) {
       q = n;
       oop obj = oop(q);
-      if (obj->klass_or_null() == NULL) return q;
+      if (obj->klass_or_null_acquire() == NULL) return q;
       n += block_size(q);
     }
     assert(q <= next_boundary && n > next_boundary, "Consequence of loop");
--- a/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp	Tue Jan 19 19:55:37 2021 +0000
+++ b/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp	Tue Jan 19 20:49:42 2021 +0000
@@ -166,7 +166,7 @@
   while (n <= addr) {
     q = n;
     oop obj = oop(q);
-    if (obj->klass_or_null() == NULL) return q;
+    if (obj->klass_or_null_acquire() == NULL) return q;
     n += block_size(q);
   }
   assert(q <= n, "wrong order for q and addr");
@@ -177,7 +177,7 @@
 inline HeapWord*
 G1BlockOffsetArray::forward_to_block_containing_addr(HeapWord* q,
                                                      const void* addr) {
-  if (oop(q)->klass_or_null() == NULL) return q;
+  if (oop(q)->klass_or_null_acquire() == NULL) return q;
   HeapWord* n = q + block_size(q);
   // In the normal case, where the query "addr" is a card boundary, and the
   // offset table chunks are the same size as cards, the block starting at
--- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Tue Jan 19 19:55:37 2021 +0000
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Tue Jan 19 20:49:42 2021 +0000
@@ -575,9 +575,10 @@
                                         card_ptr);
 
   // If unable to process the card then we encountered an unparsable
-  // part of the heap (e.g. a partially allocated object).  Redirty
-  // and re-enqueue: if we put off the card until a GC pause, then the
-  // allocation will have completed.
+  // part of the heap (e.g. a partially allocated object) while
+  // processing a stale card.  Despite the card being stale, redirty
+  // and re-enqueue, because we've already cleaned the card.  Without
+  // this we could incorrectly discard a non-stale card.
   if (!card_processed) {
     assert(!_g1->is_gc_active(), "Unparsable heap during GC");
     // The card might have gotten re-dirtied and re-enqueued while we
--- a/src/share/vm/gc_implementation/g1/heapRegion.cpp	Tue Jan 19 19:55:37 2021 +0000
+++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp	Tue Jan 19 20:49:42 2021 +0000
@@ -407,6 +407,49 @@
   return NULL;
 }
 
+// Humongous objects are allocated directly in the old-gen.  Need
+// special handling for concurrent processing encountering an
+// in-progress allocation.
+static bool do_oops_on_card_in_humongous(MemRegion mr,
+                                         FilterOutOfRegionClosure* cl,
+                                         HeapRegion* hr,
+                                         G1CollectedHeap* g1h) {
+  assert(hr->isHumongous(), "precondition");
+  HeapRegion* sr = hr->humongous_start_region();
+  oop obj = oop(sr->bottom());
+
+  // If concurrent and klass_or_null is NULL, then space has been
+  // allocated but the object has not yet been published by setting
+  // the klass.  That can only happen if the card is stale.  However,
+  // we've already set the card clean, so we must return failure,
+  // since the allocating thread could have performed a write to the
+  // card that might be missed otherwise.
+  if (!g1h->is_gc_active() && (obj->klass_or_null_acquire() == NULL)) {
+    return false;
+  }
+
+  // Only filler objects follow a humongous object in the containing
+  // regions, and we can ignore those.  So only process the one
+  // humongous object.
+  if (!g1h->is_obj_dead(obj, sr)) {
+    if (obj->is_objArray() || (sr->bottom() < mr.start())) {
+      // objArrays are always marked precisely, so limit processing
+      // with mr.  Non-objArrays might be precisely marked, and since
+      // it's humongous it's worthwhile avoiding full processing.
+      // However, the card could be stale and only cover filler
+      // objects.  That should be rare, so not worth checking for;
+      // instead let it fall out from the bounded iteration.
+      obj->oop_iterate(cl, mr);
+    } else {
+      // If obj is not an objArray and mr contains the start of the
+      // obj, then this could be an imprecise mark, and we need to
+      // process the entire object.
+      obj->oop_iterate(cl);
+    }
+  }
+  return true;
+}
+
 bool HeapRegion::oops_on_card_seq_iterate_careful(MemRegion mr,
                                                   FilterOutOfRegionClosure* cl,
                                                   jbyte* card_ptr) {
@@ -424,7 +467,6 @@
   if (mr.is_empty()) {
     return true;
   }
-  // Otherwise, find the obj that extends onto mr.start().
 
   // The intersection of the incoming mr (for the card) and the
   // allocated part of the region is non-empty. This implies that
@@ -442,54 +484,52 @@
   // We must complete this write before we do any of the reads below.
   OrderAccess::storeload();
 
+  // Special handling for humongous regions.
+  if (isHumongous()) {
+    return do_oops_on_card_in_humongous(mr, cl, this, g1h);
+  }
+
+  // During GC we limit mr by scan_top. So we never get here with an
+  // mr covering objects allocated during GC.  Non-humongous objects
+  // are only allocated in the old-gen during GC.  So the parts of the
+  // heap that may be examined here are always parsable; there's no
+  // need to use klass_or_null here to detect in-progress allocations.
+
   // Cache the boundaries of the memory region in some const locals
   HeapWord* const start = mr.start();
   HeapWord* const end = mr.end();
 
-  // Update BOT as needed while finding start of (potential) object.
+  // Find the obj that extends onto mr.start().
+  // Update BOT as needed while finding start of (possibly dead)
+  // object containing the start of the region.
   HeapWord* cur = block_start(start);
-  assert(cur <= start, "Postcondition");
-
-  oop obj;
 
-  HeapWord* next = cur;
-  do {
-    cur = next;
-    obj = oop(cur);
-    if (obj->klass_or_null() == NULL) {
-      // Ran into an unparseable point.
-      assert(!g1h->is_gc_active(),
-             err_msg("Unparsable heap during GC at " PTR_FORMAT, p2i(cur)));
-      return false;
-    }
-    // Otherwise...
-    next = cur + block_size(cur);
-  } while (next <= start);
-
-  // If we finish the above loop...We have a parseable object that
-  // begins on or before the start of the memory region, and ends
-  // inside or spans the entire region.
-  assert(cur <= start, "Loop postcondition");
-  assert(obj->klass_or_null() != NULL, "Loop postcondition");
+#ifdef ASSERT
+  {
+    assert(cur <= start,
+           err_msg("cur: " PTR_FORMAT ", start: " PTR_FORMAT, p2i(cur), p2i(start)));
+    HeapWord* next = cur + block_size(cur);
+    assert(start < next,
+           err_msg("start: " PTR_FORMAT ", next: " PTR_FORMAT, p2i(start), p2i(next)));
+  }
+#endif
 
   do {
-    obj = oop(cur);
-    assert((cur + block_size(cur)) > (HeapWord*)obj, "Loop invariant");
-    if (obj->klass_or_null() == NULL) {
-      // Ran into an unparseable point.
-      assert(!g1h->is_gc_active(),
-             err_msg("Unparsable heap during GC at " PTR_FORMAT, p2i(cur)));
-      return false;
-    }
+    oop obj = oop(cur);
+    assert(obj->is_oop(true), err_msg("Not an oop at " PTR_FORMAT, p2i(cur)));
+    assert(obj->klass_or_null() != NULL,
+           err_msg("Unparsable heap at " PTR_FORMAT, p2i(cur)));
 
-    // Advance the current pointer. "obj" still points to the object to iterate.
-    cur = cur + block_size(cur);
-
-    if (!g1h->is_obj_dead(obj)) {
-      // Non-objArrays are sometimes marked imprecise at the object start. We
-      // always need to iterate over them in full.
-      // We only iterate over object arrays in full if they are completely contained
-      // in the memory region.
+    if (g1h->is_obj_dead(obj, this)) {
+      // Carefully step over dead object.
+      cur += block_size(cur);
+    } else {
+      // Step over live object, and process its references.
+      cur += obj->size();
+      // Non-objArrays are usually marked imprecise at the object
+      // start, in which case we need to iterate over them in full.
+      // objArrays are precisely marked, but can still be iterated
+      // over in full if completely covered.
       if (!obj->is_objArray() || (((HeapWord*)obj) >= start && cur <= end)) {
         obj->oop_iterate(cl);
       } else {
--- a/src/share/vm/gc_implementation/g1/heapRegion.hpp	Tue Jan 19 19:55:37 2021 +0000
+++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp	Tue Jan 19 20:49:42 2021 +0000
@@ -723,7 +723,7 @@
   // mr: the memory region covered by the card.
   // card_ptr: if we decide that the card is not young and we iterate
   // over it, we'll clean the card before we start the iteration.
-  // Returns true if card was successfully processed, false if an
+  // Returns true if the card was successfully processed, false if an
   // unparsable part of the heap was encountered, which should only
   // happen when invoked concurrently with the mutator.
   bool oops_on_card_seq_iterate_careful(MemRegion mr,
--- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Tue Jan 19 19:55:37 2021 +0000
+++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Tue Jan 19 20:49:42 2021 +0000
@@ -1544,22 +1544,25 @@
      return false;
   }
   assert(prefix != NULL && prefix != BUSY, "Error");
-  size_t i = 1;
   oop cur = prefix;
-  while (i < objsFromOverflow && cur->klass_or_null() != NULL) {
-    i++; cur = cur->list_ptr_from_klass();
+  for (size_t i = 1; i < objsFromOverflow; ++i) {
+    oop next = cur->list_ptr_from_klass();
+    if (next == NULL) break;
+    cur = next;
   }
+  assert(cur != NULL, "Loop postcondition");
 
   // Reattach remaining (suffix) to overflow list
-  if (cur->klass_or_null() == NULL) {
+  oop suffix = cur->list_ptr_from_klass();
+  if (suffix == NULL) {
     // Write back the NULL in lieu of the BUSY we wrote
     // above and it is still the same value.
     if (_overflow_list == BUSY) {
       (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
     }
   } else {
-    assert(cur->klass_or_null() != (Klass*)(address)BUSY, "Error");
-    oop suffix = cur->list_ptr_from_klass();       // suffix will be put back on global list
+    assert(suffix != BUSY, "Error");
+    // suffix will be put back on global list
     cur->set_klass_to_list_ptr(NULL);     // break off suffix
     // It's possible that the list is still in the empty(busy) state
     // we left it in a short while ago; in that case we may be
@@ -1579,8 +1582,10 @@
       // Too bad, someone else got in in between; we'll need to do a splice.
       // Find the last item of suffix list
       oop last = suffix;
-      while (last->klass_or_null() != NULL) {
-        last = last->list_ptr_from_klass();
+      while (true) {
+        oop next = last->list_ptr_from_klass();
+        if (next == NULL) break;
+        last = next;
       }
       // Atomically prepend suffix to current overflow list
       observed_overflow_list = _overflow_list;
--- a/src/share/vm/jfr/recorder/storage/jfrStorage.cpp	Tue Jan 19 19:55:37 2021 +0000
+++ b/src/share/vm/jfr/recorder/storage/jfrStorage.cpp	Tue Jan 19 20:49:42 2021 +0000
@@ -483,7 +483,7 @@
 
 BufferPtr JfrStorage::flush_regular(BufferPtr cur, const u1* const cur_pos, size_t used, size_t req, bool native, Thread* t) {
   debug_only(assert_flush_regular_precondition(cur, cur_pos, used, req, t);)
-  // A flush is needed before memcpy since a non-large buffer is thread stable
+  // A flush is needed before memmove since a non-large buffer is thread stable
   // (thread local). The flush will not modify memory in addresses above pos()
   // which is where the "used / uncommitted" data resides. It is therefore both
   // possible and valid to migrate data after the flush. This is however only
@@ -495,7 +495,8 @@
   if (cur->free_size() >= req) {
     // simplest case, no switching of buffers
     if (used > 0) {
-      memcpy(cur->pos(), (void*)cur_pos, used);
+      // source and destination may overlap so memmove must be used instead of memcpy
+      memmove(cur->pos(), (void*)cur_pos, used);
     }
     assert(native ? t->jfr_thread_local()->native_buffer() == cur : t->jfr_thread_local()->java_buffer() == cur, "invariant");
     return cur;
--- a/src/share/vm/oops/markOop.hpp	Tue Jan 19 19:55:37 2021 +0000
+++ b/src/share/vm/oops/markOop.hpp	Tue Jan 19 20:49:42 2021 +0000
@@ -138,23 +138,15 @@
          epoch_mask_in_place      = epoch_mask << epoch_shift,
          cms_mask                 = right_n_bits(cms_bits),
          cms_mask_in_place        = cms_mask << cms_shift
-#ifndef _WIN64
-         ,hash_mask               = right_n_bits(hash_bits),
-         hash_mask_in_place       = (address_word)hash_mask << hash_shift
-#endif
   };
 
+  const static uintptr_t hash_mask = right_n_bits(hash_bits);
+  const static uintptr_t hash_mask_in_place = hash_mask << hash_shift;
+
   // Alignment of JavaThread pointers encoded in object header required by biased locking
   enum { biased_lock_alignment    = 2 << (epoch_shift + epoch_bits)
   };
 
-#ifdef _WIN64
-    // These values are too big for Win64
-    const static uintptr_t hash_mask = right_n_bits(hash_bits);
-    const static uintptr_t hash_mask_in_place  =
-                            (address_word)hash_mask << hash_shift;
-#endif
-
   enum { locked_value             = 0,
          unlocked_value           = 1,
          monitor_value            = 2,
--- a/src/share/vm/opto/node.cpp	Tue Jan 19 19:55:37 2021 +0000
+++ b/src/share/vm/opto/node.cpp	Tue Jan 19 20:49:42 2021 +0000
@@ -1153,8 +1153,8 @@
   if( this->is_Store() ) {
     // Condition for back-to-back stores folding.
     return n->Opcode() == op && n->in(MemNode::Memory) == this;
-  } else if (this->is_Load()) {
-    // Condition for removing an unused LoadNode from the MemBarAcquire precedence input
+  } else if (this->is_Load() || this->is_DecodeN()) {
+    // Condition for removing an unused LoadNode or DecodeNNode from the MemBarAcquire precedence input
     return n->Opcode() == Op_MemBarAcquire;
   } else if( op == Op_AddL ) {
     // Condition for convL2I(addL(x,y)) ==> addI(convL2I(x),convL2I(y))
--- a/test/Makefile	Tue Jan 19 19:55:37 2021 +0000
+++ b/test/Makefile	Tue Jan 19 20:49:42 2021 +0000
@@ -250,6 +250,21 @@
   endif
 endif
 
+# Problematic tests to be excluded
+PROBLEM_LISTS=$(call MixedDirs,$(wildcard ProblemList.txt closed/ProblemList.txt))
+
+# Create exclude list for this platform and arch
+ifdef NO_EXCLUDES
+  JTREG_EXCLUSIONS =
+else
+  JTREG_EXCLUSIONS = $(PROBLEM_LISTS:%=-exclude:%)
+endif
+
+# convert list of directories to dos paths
+define MixedDirs
+$(foreach i,$1,$(shell $(GETMIXEDPATH) "${i}"))
+endef
+
 # When called from JPRT the TESTDIRS variable is set to the jtreg tests to run
 ifdef TESTDIRS
   TEST_SELECTION = $(TESTDIRS)
@@ -278,14 +293,6 @@
 # Set other vm and test options
 JTREG_TEST_OPTIONS = $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_OPTIONS:%=-vmoption:%) $(JAVA_VM_ARGS:%=-vmoption:%)
 
-# Option to tell jtreg to not run tests marked with "ignore"
-ifeq ($(PLATFORM), windows)
-  JTREG_KEY_OPTION = -k:!ignore
-else
-  JTREG_KEY_OPTION = -k:\!ignore
-endif
-JTREG_BASIC_OPTIONS += $(JTREG_KEY_OPTION)
- 
 # Make sure jtreg exists
 $(JTREG): $(JT_HOME)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/ProblemList.txt	Tue Jan 19 20:49:42 2021 +0000
@@ -0,0 +1,66 @@
+#
+# Copyright (c) 2016, 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.
+#
+
+#############################################################################
+#
+# List of quarantined tests -- tests that should not be run by default, because
+# they may fail due to known reason. The reason (CR#) must be mandatory specified.
+#
+# List items are testnames followed by labels, all MUST BE commented
+#   as to why they are here and use a label:
+#     generic-all   Problems on all platforms
+#     generic-ARCH  Where ARCH is one of: sparc, sparcv9, x64, i586, etc.
+#     OSNAME-all    Where OSNAME is one of: solaris, linux, windows, macosx, aix
+#     OSNAME-ARCH   Specific on to one OSNAME and ARCH, e.g. solaris-amd64
+#     OSNAME-REV    Specific on to one OSNAME and REV, e.g. solaris-5.8
+#
+# More than one label is allowed but must be on the same line.
+#
+#############################################################################
+
+# :hotspot_runtime
+
+runtime/SharedArchiveFile/SharedBaseAddress.java 8044600 solaris-sparc
+runtime/6929067/Test6929067.sh 8028740 generic-all
+runtime/CDSCompressedKPtrs/XShareAuto.java 8026154 generic-all
+runtime/XCheckJniJsig/XCheckJSig.java 8023735 generic-all
+runtime/6626217/Test6626217.sh 8028733 generic-all
+runtime/jsig/Test8017498.sh 8028806 generic-all
+runtime/LoadClass/LoadClassNegative.java 8028095 generic-all
+runtime/NMT/MallocStressTest.java 8166548 generic-all
+runtime/InitialThreadOverflow/testme.sh 8029139 generic-all
+runtime/memory/ReadFromNoaccessArea.java 8028398 generic-all
+
+# :hotspot_compiler
+
+compiler/rtm/locking/TestRTMAbortRatio.java 8183263 generic-x64
+compiler/rtm/locking/TestRTMAbortThreshold.java 8183263 generic-x64
+compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java 8183263 generic-x64
+compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java 8183263 generic-x64
+compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java 8183263 generic-x64
+compiler/rtm/locking/TestRTMLockingCalculationDelay.java 8183263 generic-x64
+compiler/rtm/locking/TestRTMLockingThreshold.java 8183263 generic-x64
+compiler/rtm/locking/TestRTMSpinLoopCount.java 8183263 generic-x64
+compiler/rtm/locking/TestUseRTMDeopt.java 8183263 generic-x64
+compiler/rtm/locking/TestUseRTMXendForLockBusy.java 8183263 generic-x64
+compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java 8183263 generic-x64
--- a/test/runtime/6626217/Test6626217.sh	Tue Jan 19 19:55:37 2021 +0000
+++ b/test/runtime/6626217/Test6626217.sh	Tue Jan 19 20:49:42 2021 +0000
@@ -22,7 +22,6 @@
 # 
 
 
-# @ignore 8028733
 # @test @(#)Test6626217.sh
 # @bug 6626217
 # @summary Loader-constraint table allows arrays instead of only the base-classes
--- a/test/runtime/6929067/Test6929067.sh	Tue Jan 19 19:55:37 2021 +0000
+++ b/test/runtime/6929067/Test6929067.sh	Tue Jan 19 20:49:42 2021 +0000
@@ -1,7 +1,6 @@
 #!/bin/sh
 
 ##
-## @ignore 8028740
 ## @test Test6929067.sh
 ## @bug 6929067
 ## @bug 8021296
--- a/test/runtime/CDSCompressedKPtrs/XShareAuto.java	Tue Jan 19 19:55:37 2021 +0000
+++ b/test/runtime/CDSCompressedKPtrs/XShareAuto.java	Tue Jan 19 20:49:42 2021 +0000
@@ -22,7 +22,6 @@
  */
 
 /*
- * @ignore 8026154
  * @test
  * @bug 8005933
  * @summary Test that -Xshare:auto uses CDS when explicitly specified with -server.
--- a/test/runtime/InitialThreadOverflow/testme.sh	Tue Jan 19 19:55:37 2021 +0000
+++ b/test/runtime/InitialThreadOverflow/testme.sh	Tue Jan 19 20:49:42 2021 +0000
@@ -21,7 +21,6 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 
-# @ignore 8029139
 # @test testme.sh
 # @bug 8009062
 # @summary Poor performance of JNI AttachCurrentThread after fix for 7017193
--- a/test/runtime/LoadClass/LoadClassNegative.java	Tue Jan 19 19:55:37 2021 +0000
+++ b/test/runtime/LoadClass/LoadClassNegative.java	Tue Jan 19 20:49:42 2021 +0000
@@ -22,7 +22,6 @@
  */
 
 /*
- * @ignore 8028095
  * @test
  * @key regression
  * @bug 8020675
--- a/test/runtime/NMT/MallocStressTest.java	Tue Jan 19 19:55:37 2021 +0000
+++ b/test/runtime/NMT/MallocStressTest.java	Tue Jan 19 20:49:42 2021 +0000
@@ -27,7 +27,6 @@
  * @key nmt jcmd stress
  * @library /testlibrary /testlibrary/whitebox
  * @build MallocStressTest
- * @ignore - This test is disabled since it will stress NMT and timeout during normal testing
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocStressTest
  */
--- a/test/runtime/SharedArchiveFile/SharedBaseAddress.java	Tue Jan 19 19:55:37 2021 +0000
+++ b/test/runtime/SharedArchiveFile/SharedBaseAddress.java	Tue Jan 19 20:49:42 2021 +0000
@@ -41,8 +41,6 @@
     };
 
     public static void main(String[] args) throws Exception {
-        // Known issue on Solaris-Sparc
-        // @ignore JDK-8044600
         if (Platform.isSolaris() && Platform.isSparc())
             return;
 
--- a/test/runtime/XCheckJniJsig/XCheckJSig.java	Tue Jan 19 19:55:37 2021 +0000
+++ b/test/runtime/XCheckJniJsig/XCheckJSig.java	Tue Jan 19 20:49:42 2021 +0000
@@ -22,7 +22,6 @@
  */
 
 /*
- * @ignore 8023735
  * @test
  * @bug 7051189 8023393
  * @summary Need to suppress info message if -Xcheck:jni is used with libjsig.so
--- a/test/runtime/containers/docker/TestMemoryAwareness.java	Tue Jan 19 19:55:37 2021 +0000
+++ b/test/runtime/containers/docker/TestMemoryAwareness.java	Tue Jan 19 20:49:42 2021 +0000
@@ -34,6 +34,7 @@
 import com.oracle.java.testlibrary.Common;
 import com.oracle.java.testlibrary.DockerRunOptions;
 import com.oracle.java.testlibrary.DockerTestUtils;
+import com.oracle.java.testlibrary.OutputAnalyzer;
 
 
 public class TestMemoryAwareness {
@@ -128,14 +129,26 @@
                 "--memory-swap", swapAllocation
             );
 
-        DockerTestUtils.dockerRunJava(opts)
-            .shouldHaveExitValue(0)
-            .shouldContain("Checking OperatingSystemMXBean")
-            .shouldContain("OperatingSystemMXBean.getTotalPhysicalMemorySize: " + expectedMemory)
-            .shouldMatch("OperatingSystemMXBean\\.getFreePhysicalMemorySize: [1-9][0-9]+")
-            .shouldContain("OperatingSystemMXBean.getTotalSwapSpaceSize: " + expectedSwap)
-            .shouldMatch("OperatingSystemMXBean\\.getFreeSwapSpaceSize: [1-9][0-9]+")
-            ;
+        OutputAnalyzer out = DockerTestUtils.dockerRunJava(opts);
+            out.shouldHaveExitValue(0)
+               .shouldContain("Checking OperatingSystemMXBean")
+               .shouldContain("OperatingSystemMXBean.getTotalPhysicalMemorySize: " + expectedMemory)
+               .shouldMatch("OperatingSystemMXBean\\.getFreePhysicalMemorySize: [1-9][0-9]+");
+        // in case of warnings like : "Your kernel does not support swap limit capabilities
+        // or the cgroup is not mounted. Memory limited without swap."
+        // the getTotalSwapSpaceSize and getFreeSwapSpaceSize return the system
+        // values as the container setup isn't supported in that case.
+        try {
+            out.shouldContain("OperatingSystemMXBean.getTotalSwapSpaceSize: " + expectedSwap);
+        } catch(RuntimeException ex) {
+            out.shouldMatch("OperatingSystemMXBean.getTotalSwapSpaceSize: [0-9]+");
+        }
+
+        try {
+            out.shouldMatch("OperatingSystemMXBean\\.getFreeSwapSpaceSize: [1-9][0-9]+");
+        } catch(RuntimeException ex) {
+            out.shouldMatch("OperatingSystemMXBean\\.getFreeSwapSpaceSize: 0");
+        }
     }
 
 }
--- a/test/runtime/jsig/Test8017498.sh	Tue Jan 19 19:55:37 2021 +0000
+++ b/test/runtime/jsig/Test8017498.sh	Tue Jan 19 20:49:42 2021 +0000
@@ -24,7 +24,6 @@
 #
 
 ##
-## @ignore 8028806
 ## @test Test8017498.sh
 ## @bug 8017498
 ## @bug 8020791
--- a/test/runtime/memory/ReadFromNoaccessArea.java	Tue Jan 19 19:55:37 2021 +0000
+++ b/test/runtime/memory/ReadFromNoaccessArea.java	Tue Jan 19 20:49:42 2021 +0000
@@ -22,7 +22,6 @@
  */
 
 /*
- * @ignore 8028398
  * @test
  * @summary Test that touching noaccess area in class ReservedHeapSpace results in SIGSEGV/ACCESS_VIOLATION
  * @library /testlibrary /testlibrary/whitebox
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary/com/oracle/java/testlibrary/Container.java	Tue Jan 19 20:49:42 2021 +0000
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019, Red Hat Inc.
+ * 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.
+ */
+package com.oracle.java.testlibrary;
+
+public class Container {
+    // Use this property to specify docker location on your system.
+    // E.g.: "/usr/local/bin/docker". We define this constant here so
+    // that it can be used in VMProps as well which checks docker support
+    // via this command
+    public static final String ENGINE_COMMAND =
+        System.getProperty("jdk.test.container.command", "docker");
+}
--- a/test/testlibrary/com/oracle/java/testlibrary/DockerTestUtils.java	Tue Jan 19 19:55:37 2021 +0000
+++ b/test/testlibrary/com/oracle/java/testlibrary/DockerTestUtils.java	Tue Jan 19 20:49:42 2021 +0000
@@ -38,7 +38,7 @@
 import java.util.List;
 
 import com.oracle.java.testlibrary.Utils;
-import com.oracle.java.testlibrary.Platform;
+import com.oracle.java.testlibrary.Container;
 import com.oracle.java.testlibrary.OutputAnalyzer;
 import com.oracle.java.testlibrary.ProcessTools;
 
@@ -47,11 +47,6 @@
     private static boolean isDockerEngineAvailable = false;
     private static boolean wasDockerEngineChecked = false;
 
-    // Use this property to specify docker location on your system.
-    // E.g.: "/usr/local/bin/docker".
-    private static final String DOCKER_COMMAND =
-        System.getProperty("jdk.test.docker.command", "docker");
-
     // Set this property to true to retain image after test. By default
     // images are removed after test execution completes.
     // Retaining the image can be useful for diagnostics and image inspection.
@@ -111,7 +106,7 @@
      */
     private static boolean isDockerEngineAvailableCheck() throws Exception {
         try {
-            execute(DOCKER_COMMAND, "ps")
+            execute(Container.ENGINE_COMMAND, "ps")
                 .shouldHaveExitValue(0)
                 .shouldContain("CONTAINER")
                 .shouldContain("IMAGE");
@@ -172,9 +167,8 @@
                            DockerfileConfig.getBaseImageVersion());
 
         // Build the docker
-        execute(DOCKER_COMMAND, "build", "--no-cache", "--tag", imageName, buildDir.toString())
-            .shouldHaveExitValue(0)
-            .shouldContain("Successfully built");
+        execute(Container.ENGINE_COMMAND, "build", "--no-cache", "--tag", imageName, buildDir.toString())
+            .shouldHaveExitValue(0);
     }
 
 
@@ -189,7 +183,7 @@
     public static OutputAnalyzer dockerRunJava(DockerRunOptions opts) throws Exception {
         ArrayList<String> cmd = new ArrayList<>();
 
-        cmd.add(DOCKER_COMMAND);
+        cmd.add(Container.ENGINE_COMMAND);
         cmd.add("run");
         if (opts.tty)
             cmd.add("--tty=true");
@@ -218,7 +212,7 @@
      * @throws Exception
      */
     public static void removeDockerImage(String imageNameAndTag) throws Exception {
-            execute(DOCKER_COMMAND, "rmi", "--force", imageNameAndTag);
+            execute(Container.ENGINE_COMMAND, "rmi", "--force", imageNameAndTag);
     }