changeset 10803:c8c10298f00a

Merge jdk8u272-ga
author Andrew John Hughes <gnu_andrew@member.fsf.org>
date Tue, 27 Oct 2020 06:33:36 +0000
parents 9bdb9da0295a (current diff) 73f624a2488d (diff)
children d06ea5129bd8
files .hgtags THIRD_PARTY_README make/aix/makefiles/vm.make make/bsd/makefiles/buildtree.make make/bsd/makefiles/vm.make make/linux/makefiles/buildtree.make make/linux/makefiles/mapfile-vers-debug make/linux/makefiles/vm.make make/solaris/makefiles/vm.make src/share/vm/classfile/classFileParser.cpp src/share/vm/classfile/symbolTable.cpp src/share/vm/classfile/systemDictionary.cpp src/share/vm/classfile/verifier.cpp src/share/vm/compiler/disassembler.cpp src/share/vm/gc_implementation/g1/concurrentMark.cpp src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp src/share/vm/gc_implementation/g1/g1StringDedupTable.cpp src/share/vm/memory/metaspaceShared.cpp src/share/vm/oops/constantPool.cpp src/share/vm/oops/constantPool.hpp src/share/vm/opto/compile.cpp src/share/vm/opto/compile.hpp src/share/vm/opto/loopTransform.cpp src/share/vm/opto/loopnode.hpp src/share/vm/opto/type.cpp src/share/vm/opto/type.hpp src/share/vm/prims/jniCheck.cpp src/share/vm/prims/jvm.cpp src/share/vm/prims/jvm.h src/share/vm/prims/nativeLookup.cpp src/share/vm/runtime/globals.hpp src/share/vm/runtime/reflection.cpp src/share/vm/runtime/thread.cpp src/share/vm/utilities/globalDefinitions.hpp src/share/vm/utilities/taskqueue.hpp test/runtime/8233197/T.java test/runtime/8233197/Test8233197.sh test/runtime/8233197/libJvmtiAgent.c test/runtime/ClassFile/BadHelloWorld.jcod test/runtime/ClassFile/FormatCheckingTest.java
diffstat 68 files changed, 1323 insertions(+), 1159 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Oct 27 03:35:20 2020 +0000
+++ b/.hgtags	Tue Oct 27 06:33:36 2020 +0000
@@ -1409,3 +1409,11 @@
 414c1dcfc3f3620b73cc7faf23f9a3ffde83b240 jdk8u272-b02
 e649f213636810823e761473ac871ce55a5235f7 jdk8u272-b03
 9cc00eb32cbd7a2081ebf67a778ab2137fafc3d1 icedtea-3.17.0pre02
+cbabffce5685f9a18bfd05bd1fb18c4c73be98cf jdk8u272-b04
+1b2d99958c293b7ab324c5786664f82c8e9c4e50 jdk8u272-b05
+4b0aa85a95653f44cc45f2ec0571153017ebbf03 jdk8u272-b06
+4689eaf1a5c9c5e284d466631420761f4bd4ecae jdk8u272-b07
+a0eb08e2db5a40956a9c2d6b7dea76a894559033 jdk8u272-b08
+176a7e5cc0609cface769e5e8a31b00700d223ba jdk8u272-b09
+6b836efa38fef1b50ba798b6e344ab44ee995812 jdk8u272-b10
+6b836efa38fef1b50ba798b6e344ab44ee995812 jdk8u272-ga
--- a/THIRD_PARTY_README	Tue Oct 27 03:35:20 2020 +0000
+++ b/THIRD_PARTY_README	Tue Oct 27 06:33:36 2020 +0000
@@ -2240,7 +2240,7 @@
 
 -------------------------------------------------------------------------------
 
-%% This notice is provided with respect to PC/SC Lite v1.8.24,
+%% This notice is provided with respect to PC/SC Lite v1.8.26,
 which may be included with JRE 8, JDK 8, and OpenJDK 8 on Linux and Solaris.
 
 --- begin of LICENSE ---
@@ -3241,3 +3241,42 @@
 --- end of LICENSE ---
 
 -------------------------------------------------------------------------------
+
+%% This notice is provided with respect to OASIS PKCS #11 Cryptographic Token
+Interface v2.40,  which may be included with JRE 8, JDK 8, and OpenJDK 8.
+
+--- begin of LICENSE ---
+
+Copyright (c) OASIS Open 2016. All Rights Reserved.
+
+All capitalized terms in the following text have the meanings assigned to them
+in the OASIS Intellectual Property Rights Policy (the "OASIS IPR Policy"). The
+full Policy may be found at the OASIS website:
+[http://www.oasis-open.org/policies-guidelines/ipr]
+
+This document and translations of it may be copied and furnished to others, and
+derivative works that comment on or otherwise explain it or assist in its
+implementation may be prepared, copied, published, and distributed, in whole or
+in part, without restriction of any kind, provided that the above copyright
+notice and this section are included on all such copies and derivative works.
+However, this document itself may not be modified in any way, including by
+removing the copyright notice or references to OASIS, except as needed for the
+purpose of developing any document or deliverable produced by an OASIS
+Technical Committee (in which case the rules applicable to copyrights, as set
+forth in the OASIS IPR Policy, must be followed) or as required to translate it
+into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by
+OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS"
+basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT
+INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR
+FITNESS FOR A PARTICULAR PURPOSE. OASIS AND ITS MEMBERS WILL NOT BE LIABLE FOR
+ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE
+OF THIS DOCUMENT OR ANY PART THEREOF.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
--- a/make/excludeSrc.make	Tue Oct 27 03:35:20 2020 +0000
+++ b/make/excludeSrc.make	Tue Oct 27 06:33:36 2020 +0000
@@ -95,6 +95,7 @@
       gc_shared_keep :=							\
 	adaptiveSizePolicy.cpp						\
 	ageTable.cpp							\
+	ageTableTracer.cpp						\
 	collectorCounters.cpp						\
 	cSpaceCounters.cpp						\
 	gcId.cpp							\
--- a/make/linux/makefiles/mapfile-vers-debug	Tue Oct 27 03:35:20 2020 +0000
+++ b/make/linux/makefiles/mapfile-vers-debug	Tue Oct 27 06:33:36 2020 +0000
@@ -190,6 +190,7 @@
                 JVM_IsSilentCompiler;
                 JVM_IsSupportedJNIVersion;
                 JVM_IsThreadAlive;
+                JVM_IsUseContainerSupport;
                 JVM_IsVMGeneratedMethodIx;
                 JVM_LatestUserDefinedLoader;
                 JVM_Listen;
--- a/make/linux/makefiles/mapfile-vers-product	Tue Oct 27 03:35:20 2020 +0000
+++ b/make/linux/makefiles/mapfile-vers-product	Tue Oct 27 06:33:36 2020 +0000
@@ -185,6 +185,7 @@
                 JVM_IsInterface;
                 JVM_IsInterrupted;
                 JVM_IsNaN;
+                JVM_IsUseContainerSupport;
                 JVM_IsPrimitiveClass;
                 JVM_IsSameClassPackage;
                 JVM_IsSilentCompiler;
--- a/src/share/vm/classfile/altHashing.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/classfile/altHashing.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, 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
@@ -22,12 +22,29 @@
  *
  */
 
+/*
+ * halfsiphash code adapted from reference implementation
+ * (https://github.com/veorq/SipHash/blob/master/halfsiphash.c)
+ * which is distributed with the following copyright:
+ *
+ * SipHash reference C implementation
+ *
+ * Copyright (c) 2016 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
 #include "precompiled.hpp"
 #include "classfile/altHashing.hpp"
-#include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "oops/markOop.hpp"
-#include "runtime/thread.hpp"
+#include "runtime/os.hpp"
 
 // Get the hash code of the classes mirror if it exists, otherwise just
 // return a random number, which is one of the possible hash code used for
@@ -39,266 +56,292 @@
 }
 
 // Seed value used for each alternative hash calculated.
-juint AltHashing::compute_seed() {
-  jlong nanos = os::javaTimeNanos();
-  jlong now = os::javaTimeMillis();
-  int SEED_MATERIAL[8] = {
-            (int) object_hash(SystemDictionary::String_klass()),
-            (int) object_hash(SystemDictionary::System_klass()),
-            (int) os::random(),  // current thread isn't a java thread
-            (int) (((julong)nanos) >> 32),
-            (int) nanos,
-            (int) (((julong)now) >> 32),
-            (int) now,
-            (int) (os::javaTimeNanos() >> 2)
+uint64_t AltHashing::compute_seed() {
+  uint64_t nanos = os::javaTimeNanos();
+  uint64_t now = os::javaTimeMillis();
+  uint32_t SEED_MATERIAL[8] = {
+            (uint32_t) object_hash(SystemDictionary::String_klass()),
+            (uint32_t) object_hash(SystemDictionary::System_klass()),
+            (uint32_t) os::random(),  // current thread isn't a java thread
+            (uint32_t) (((uint64_t)nanos) >> 32),
+            (uint32_t) nanos,
+            (uint32_t) (((uint64_t)now) >> 32),
+            (uint32_t) now,
+            (uint32_t) (os::javaTimeNanos() >> 2)
   };
 
-  return murmur3_32(SEED_MATERIAL, 8);
+  return halfsiphash_64(SEED_MATERIAL, 8);
+}
+
+// utility function copied from java/lang/Integer
+static uint32_t Integer_rotateLeft(uint32_t i, int distance) {
+  return (i << distance) | (i >> (32 - distance));
+}
+
+static void halfsiphash_rounds(uint32_t v[4], int rounds) {
+  while (rounds-- > 0) {
+    v[0] += v[1];
+    v[1] = Integer_rotateLeft(v[1], 5);
+    v[1] ^= v[0];
+    v[0] = Integer_rotateLeft(v[0], 16);
+    v[2] += v[3];
+    v[3] = Integer_rotateLeft(v[3], 8);
+    v[3] ^= v[2];
+    v[0] += v[3];
+    v[3] = Integer_rotateLeft(v[3], 7);
+    v[3] ^= v[0];
+    v[2] += v[1];
+    v[1] = Integer_rotateLeft(v[1], 13);
+    v[1] ^= v[2];
+    v[2] = Integer_rotateLeft(v[2], 16);
+  }
+ }
+
+static void halfsiphash_adddata(uint32_t v[4], uint32_t newdata, int rounds) {
+  v[3] ^= newdata;
+  halfsiphash_rounds(v, rounds);
+  v[0] ^= newdata;
 }
 
+static void halfsiphash_init32(uint32_t v[4], uint64_t seed) {
+  v[0] = seed & 0xffffffff;
+  v[1] = seed >> 32;
+  v[2] = 0x6c796765 ^ v[0];
+  v[3] = 0x74656462 ^ v[1];
+}
 
-// Murmur3 hashing for Symbol
-juint AltHashing::murmur3_32(juint seed, const jbyte* data, int len) {
-  juint h1 = seed;
+static void halfsiphash_init64(uint32_t v[4], uint64_t seed) {
+  halfsiphash_init32(v, seed);
+  v[1] ^= 0xee;
+}
+
+uint32_t halfsiphash_finish32(uint32_t v[4], int rounds) {
+  v[2] ^= 0xff;
+  halfsiphash_rounds(v, rounds);
+  return (v[1] ^ v[3]);
+}
+
+static uint64_t halfsiphash_finish64(uint32_t v[4], int rounds) {
+  uint64_t rv;
+  v[2] ^= 0xee;
+  halfsiphash_rounds(v, rounds);
+  rv = v[1] ^ v[3];
+  v[1] ^= 0xdd;
+  halfsiphash_rounds(v, rounds);
+  rv |= (uint64_t)(v[1] ^ v[3]) << 32;
+  return rv;
+}
+
+// HalfSipHash-2-4 (32-bit output) for Symbols
+uint32_t AltHashing::halfsiphash_32(uint64_t seed, const uint8_t* data, int len) {
+  uint32_t v[4];
+  uint32_t newdata;
+  int off = 0;
   int count = len;
-  int offset = 0;
 
+  halfsiphash_init32(v, seed);
   // body
   while (count >= 4) {
-    juint k1 = (data[offset] & 0x0FF)
-        | (data[offset + 1] & 0x0FF) << 8
-        | (data[offset + 2] & 0x0FF) << 16
-        | data[offset + 3] << 24;
+    // Avoid sign extension with 0x0ff
+    newdata = (data[off] & 0x0FF)
+        | (data[off + 1] & 0x0FF) << 8
+        | (data[off + 2] & 0x0FF) << 16
+        | data[off + 3] << 24;
 
     count -= 4;
-    offset += 4;
+    off += 4;
 
-    k1 *= 0xcc9e2d51;
-    k1 = Integer_rotateLeft(k1, 15);
-    k1 *= 0x1b873593;
-
-    h1 ^= k1;
-    h1 = Integer_rotateLeft(h1, 13);
-    h1 = h1 * 5 + 0xe6546b64;
+    halfsiphash_adddata(v, newdata, 2);
   }
 
   // tail
+  newdata = ((uint32_t)len) << 24; // (Byte.SIZE / Byte.SIZE);
 
   if (count > 0) {
-    juint k1 = 0;
-
     switch (count) {
       case 3:
-        k1 ^= (data[offset + 2] & 0xff) << 16;
+        newdata |= (data[off + 2] & 0x0ff) << 16;
       // fall through
       case 2:
-        k1 ^= (data[offset + 1] & 0xff) << 8;
+        newdata |= (data[off + 1] & 0x0ff) << 8;
       // fall through
       case 1:
-        k1 ^= (data[offset] & 0xff);
+        newdata |= (data[off] & 0x0ff);
       // fall through
-      default:
-        k1 *= 0xcc9e2d51;
-        k1 = Integer_rotateLeft(k1, 15);
-        k1 *= 0x1b873593;
-        h1 ^= k1;
     }
   }
 
-  // finalization
-  h1 ^= len;
+  halfsiphash_adddata(v, newdata, 2);
 
-  // finalization mix force all bits of a hash block to avalanche
-  h1 ^= h1 >> 16;
-  h1 *= 0x85ebca6b;
-  h1 ^= h1 >> 13;
-  h1 *= 0xc2b2ae35;
-  h1 ^= h1 >> 16;
-
-  return h1;
+  // finalization
+  return halfsiphash_finish32(v, 4);
 }
 
-// Murmur3 hashing for Strings
-juint AltHashing::murmur3_32(juint seed, const jchar* data, int len) {
-  juint h1 = seed;
-
+// HalfSipHash-2-4 (32-bit output) for Strings
+uint32_t AltHashing::halfsiphash_32(uint64_t seed, const uint16_t* data, int len) {
+  uint32_t v[4];
+  uint32_t newdata;
   int off = 0;
   int count = len;
 
+  halfsiphash_init32(v, seed);
+
   // body
   while (count >= 2) {
-    jchar d1 = data[off++] & 0xFFFF;
-    jchar d2 = data[off++];
-    juint k1 = (d1 | d2 << 16);
+    uint16_t d1 = data[off++] & 0x0FFFF;
+    uint16_t d2 = data[off++];
+    newdata = (d1 | d2 << 16);
 
     count -= 2;
 
-    k1 *= 0xcc9e2d51;
-    k1 = Integer_rotateLeft(k1, 15);
-    k1 *= 0x1b873593;
-
-    h1 ^= k1;
-    h1 = Integer_rotateLeft(h1, 13);
-    h1 = h1 * 5 + 0xe6546b64;
+    halfsiphash_adddata(v, newdata, 2);
   }
 
   // tail
-
+  newdata = ((uint32_t)len * 2) << 24; // (Character.SIZE / Byte.SIZE);
   if (count > 0) {
-    juint k1 = (juint)data[off];
-
-    k1 *= 0xcc9e2d51;
-    k1 = Integer_rotateLeft(k1, 15);
-    k1 *= 0x1b873593;
-    h1 ^= k1;
+    newdata |= (uint32_t)data[off];
   }
+  halfsiphash_adddata(v, newdata, 2);
 
   // finalization
-  h1 ^= len * 2; // (Character.SIZE / Byte.SIZE);
-
-  // finalization mix force all bits of a hash block to avalanche
-  h1 ^= h1 >> 16;
-  h1 *= 0x85ebca6b;
-  h1 ^= h1 >> 13;
-  h1 *= 0xc2b2ae35;
-  h1 ^= h1 >> 16;
-
-  return h1;
+  return halfsiphash_finish32(v, 4);
 }
 
-// Hash used for the seed.
-juint AltHashing::murmur3_32(juint seed, const int* data, int len) {
-  juint h1 = seed;
+// HalfSipHash-2-4 (64-bit output) for integers (used to create seed)
+uint64_t AltHashing::halfsiphash_64(uint64_t seed, const uint32_t* data, int len) {
+  uint32_t v[4];
 
   int off = 0;
   int end = len;
 
+  halfsiphash_init64(v, seed);
+
   // body
   while (off < end) {
-    juint k1 = (juint)data[off++];
-
-    k1 *= 0xcc9e2d51;
-    k1 = Integer_rotateLeft(k1, 15);
-    k1 *= 0x1b873593;
-
-    h1 ^= k1;
-    h1 = Integer_rotateLeft(h1, 13);
-    h1 = h1 * 5 + 0xe6546b64;
+    halfsiphash_adddata(v, (uint32_t)data[off++], 2);
   }
 
   // tail (always empty, as body is always 32-bit chunks)
 
   // finalization
-
-  h1 ^= len * 4; // (Integer.SIZE / Byte.SIZE);
-
-  // finalization mix force all bits of a hash block to avalanche
-  h1 ^= h1 >> 16;
-  h1 *= 0x85ebca6b;
-  h1 ^= h1 >> 13;
-  h1 *= 0xc2b2ae35;
-  h1 ^= h1 >> 16;
-
-  return h1;
+  halfsiphash_adddata(v, ((uint32_t)len * 4) << 24, 2); // (Integer.SIZE / Byte.SIZE);
+  return halfsiphash_finish64(v, 4);
 }
 
-juint AltHashing::murmur3_32(const int* data, int len) {
-  return murmur3_32(0, data, len);
+// HalfSipHash-2-4 (64-bit output) for integers (used to create seed)
+uint64_t AltHashing::halfsiphash_64(const uint32_t* data, int len) {
+  return halfsiphash_64((uint64_t)0, data, len);
 }
 
 #ifndef PRODUCT
-// Overloaded versions for internal test.
-juint AltHashing::murmur3_32(const jbyte* data, int len) {
-  return murmur3_32(0, data, len);
-}
+  void AltHashing::testHalfsiphash_32_ByteArray() {
+    const int factor = 4;
 
-juint AltHashing::murmur3_32(const jchar* data, int len) {
-  return murmur3_32(0, data, len);
-}
+    uint8_t vector[256];
+    uint8_t hashes[factor * 256];
+
+    for (int i = 0; i < 256; i++) {
+      vector[i] = (uint8_t) i;
+    }
 
-// Internal test for alternate hashing.  Translated from JDK version
-// test/sun/misc/Hashing.java
-static const jbyte ONE_BYTE[] = { (jbyte) 0x80};
-static const jbyte TWO_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81};
-static const jchar ONE_CHAR[] = { (jchar) 0x8180};
-static const jbyte THREE_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82};
-static const jbyte FOUR_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83};
-static const jchar TWO_CHAR[] = { (jchar) 0x8180, (jchar) 0x8382};
-static const jint ONE_INT[] = { (jint) 0x83828180};
-static const jbyte SIX_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85};
-static const jchar THREE_CHAR[] = { (jchar) 0x8180, (jchar) 0x8382, (jchar) 0x8584};
-static const jbyte EIGHT_BYTE[] = {
-  (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82,
-  (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85,
-  (jbyte) 0x86, (jbyte) 0x87};
-static const jchar FOUR_CHAR[] = {
-  (jchar) 0x8180, (jchar) 0x8382,
-  (jchar) 0x8584, (jchar) 0x8786};
+    // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255}
+    for (int i = 0; i < 256; i++) {
+      uint32_t hash = AltHashing::halfsiphash_32(256 - i, vector, i);
+      hashes[i * factor] = (uint8_t) hash;
+      hashes[i * factor + 1] = (uint8_t)(hash >> 8);
+      hashes[i * factor + 2] = (uint8_t)(hash >> 16);
+      hashes[i * factor + 3] = (uint8_t)(hash >> 24);
+    }
+
+    // hash to get const result.
+    uint32_t final_hash = AltHashing::halfsiphash_32(0, hashes, factor*256);
 
-static const jint TWO_INT[] = { (jint) 0x83828180, (jint) 0x87868584};
-
-static const juint MURMUR3_32_X86_CHECK_VALUE = 0xB0F57EE3;
+    // Value found using reference implementation for the hashes array.
+    //uint64_t k = 0;  // seed
+    //uint32_t reference;
+    //halfsiphash((const uint8_t*)hashes, factor*256, (const uint8_t *)&k, (uint8_t*)&reference, 4);
+    //printf("0x%x", reference);
 
-void AltHashing::testMurmur3_32_ByteArray() {
-  // printf("testMurmur3_32_ByteArray\n");
+    static const uint32_t HALFSIPHASH_32_BYTE_CHECK_VALUE = 0xd2be7fd8;
 
-  jbyte vector[256];
-  jbyte hashes[4 * 256];
-
-  for (int i = 0; i < 256; i++) {
-    vector[i] = (jbyte) i;
+    assert (HALFSIPHASH_32_BYTE_CHECK_VALUE == final_hash,
+      err_msg(
+          "Calculated hash result not as expected. Expected " UINT32_FORMAT " got " UINT32_FORMAT,
+          HALFSIPHASH_32_BYTE_CHECK_VALUE,
+          final_hash));
   }
 
-  // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255}
-  for (int i = 0; i < 256; i++) {
-    juint hash = murmur3_32(256 - i, vector, i);
-    hashes[i * 4] = (jbyte) hash;
-    hashes[i * 4 + 1] = (jbyte)(hash >> 8);
-    hashes[i * 4 + 2] = (jbyte)(hash >> 16);
-    hashes[i * 4 + 3] = (jbyte)(hash >> 24);
+  void AltHashing::testHalfsiphash_32_CharArray() {
+    const int factor = 2;
+
+    uint16_t vector[256];
+    uint16_t hashes[factor * 256];
+
+    for (int i = 0; i < 256; i++) {
+      vector[i] = (uint16_t) i;
+    }
+
+    // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255}
+    for (int i = 0; i < 256; i++) {
+      uint32_t hash = AltHashing::halfsiphash_32(256 - i, vector, i);
+      hashes[i * factor] = (uint16_t) hash;
+      hashes[i * factor + 1] = (uint16_t)(hash >> 16);
+    }
+
+    // hash to get const result.
+    uint32_t final_hash = AltHashing::halfsiphash_32(0, hashes, factor*256);
+
+    // Value found using reference implementation for the hashes array.
+    //uint64_t k = 0;  // seed
+    //uint32_t reference;
+    //halfsiphash((const uint8_t*)hashes, 2*factor*256, (const uint8_t *)&k, (uint8_t*)&reference, 4);
+    //printf("0x%x", reference);
+
+    static const uint32_t HALFSIPHASH_32_CHAR_CHECK_VALUE = 0x428bf8a5;
+
+    assert(HALFSIPHASH_32_CHAR_CHECK_VALUE == final_hash,
+      err_msg(
+          "Calculated hash result not as expected. Expected " UINT32_FORMAT " got " UINT32_FORMAT,
+          HALFSIPHASH_32_CHAR_CHECK_VALUE,
+          final_hash));
   }
 
-  // hash to get const result.
-  juint final_hash = murmur3_32(hashes, 4*256);
-
-  assert (MURMUR3_32_X86_CHECK_VALUE == final_hash,
-    err_msg(
-        "Calculated hash result not as expected. Expected %08X got %08X\n",
-        MURMUR3_32_X86_CHECK_VALUE,
-        final_hash));
-}
+  // Test against sample hashes published with the reference implementation:
+  // https://github.com/veorq/SipHash
+  void AltHashing::testHalfsiphash_64_FromReference() {
 
-void AltHashing::testEquivalentHashes() {
-  juint jbytes, jchars, ints;
-
-  // printf("testEquivalentHashes\n");
-
-  jbytes = murmur3_32(TWO_BYTE, 2);
-  jchars = murmur3_32(ONE_CHAR, 1);
-  assert (jbytes == jchars,
-    err_msg("Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars));
+    const uint64_t seed = 0x0706050403020100;
+    const uint64_t results[16] = {
+              0xc83cb8b9591f8d21, 0xa12ee55b178ae7d5,
+              0x8c85e4bc20e8feed, 0x99c7f5ae9f1fc77b,
+              0xb5f37b5fd2aa3673, 0xdba7ee6f0a2bf51b,
+              0xf1a63fae45107470, 0xb516001efb5f922d,
+              0x6c6211d8469d7028, 0xdc7642ec407ad686,
+              0x4caec8671cc8385b, 0x5ab1dc27adf3301e,
+              0x3e3ea94bc0a8eaa9, 0xe150f598795a4402,
+              0x1d5ff142f992a4a1, 0x60e426bf902876d6
+    };
+    uint32_t vector[16];
 
-  jbytes = murmur3_32(FOUR_BYTE, 4);
-  jchars = murmur3_32(TWO_CHAR, 2);
-  ints = murmur3_32(ONE_INT, 1);
-  assert ((jbytes == jchars) && (jbytes == ints),
-    err_msg("Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints));
-
-  jbytes = murmur3_32(SIX_BYTE, 6);
-  jchars = murmur3_32(THREE_CHAR, 3);
-  assert (jbytes == jchars,
-    err_msg("Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars));
+    for (int i = 0; i < 16; i++)
+      vector[i] = 0x03020100 + i * 0x04040404;
 
-  jbytes = murmur3_32(EIGHT_BYTE, 8);
-  jchars = murmur3_32(FOUR_CHAR, 4);
-  ints = murmur3_32(TWO_INT, 2);
-  assert ((jbytes == jchars) && (jbytes == ints),
-    err_msg("Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints));
-}
+    for (int i = 0; i < 16; i++) {
+      uint64_t hash = AltHashing::halfsiphash_64(seed, vector, i);
+      assert(results[i] == hash,
+        err_msg(
+            "Calculated hash result not as expected. Round %d: "
+            "Expected " UINT64_FORMAT_X " got " UINT64_FORMAT_X "\n",
+            i,
+            results[i],
+            hash));
+    }
+  }
 
-// Returns true if the alternate hashcode is correct
 void AltHashing::test_alt_hash() {
-  testMurmur3_32_ByteArray();
-  testEquivalentHashes();
+  testHalfsiphash_32_ByteArray();
+  testHalfsiphash_32_CharArray();
+  testHalfsiphash_64_FromReference();
 }
 #endif // PRODUCT
--- a/src/share/vm/classfile/altHashing.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/classfile/altHashing.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -26,37 +26,30 @@
 #define SHARE_VM_CLASSFILE_ALTHASHING_HPP
 
 #include "prims/jni.h"
-#include "classfile/symbolTable.hpp"
+#include "memory/allocation.hpp"
 
 /**
- * Hashing utilities.
- *
- * Implementation of Murmur3 hashing.
- * This code was translated from src/share/classes/sun/misc/Hashing.java
- * code in the JDK.
+ * Implementation of alternate more secure hashing.
  */
 
 class AltHashing : AllStatic {
 
-  // utility function copied from java/lang/Integer
-  static juint Integer_rotateLeft(juint i, int distance) {
-    return (i << distance) | (i >> (32-distance));
-  }
-  static juint murmur3_32(const int* data, int len);
-  static juint murmur3_32(juint seed, const int* data, int len);
+  // For the seed computation
+  static uint64_t halfsiphash_64(const uint32_t* data, int len);
+  static uint64_t halfsiphash_64(uint64_t seed, const uint32_t* data, int len);
+ #ifndef PRODUCT
+   // Hashing functions used for internal testing
+  static void testHalfsiphash_32_ByteArray();
+  static void testHalfsiphash_32_CharArray();
+  static void testHalfsiphash_64_FromReference();
+ #endif // PRODUCT
+ public:
+  static uint64_t compute_seed();
 
-#ifndef PRODUCT
-  // Hashing functions used for internal testing
-  static juint murmur3_32(const jbyte* data, int len);
-  static juint murmur3_32(const jchar* data, int len);
-  static void testMurmur3_32_ByteArray();
-  static void testEquivalentHashes();
-#endif // PRODUCT
-
- public:
-  static juint compute_seed();
-  static juint murmur3_32(juint seed, const jbyte* data, int len);
-  static juint murmur3_32(juint seed, const jchar* data, int len);
+  // For Symbols
+  static uint32_t halfsiphash_32(uint64_t seed, const uint8_t* data, int len);
+  // For Strings
+  static uint32_t halfsiphash_32(uint64_t seed, const uint16_t* data, int len);
   NOT_PRODUCT(static void test_alt_hash();)
 };
 #endif // SHARE_VM_CLASSFILE_ALTHASHING_HPP
--- a/src/share/vm/classfile/classFileParser.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/classfile/classFileParser.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -2691,8 +2691,83 @@
 // Inner classes can be static, private or protected (classic VM does this)
 #define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC)
 
+// Find index of the InnerClasses entry for the specified inner_class_info_index.
+// Return -1 if none is found.
+static int inner_classes_find_index(const Array<u2>* inner_classes, int inner, const ConstantPool* cp, int length) {
+  Symbol* cp_klass_name =  cp->klass_name_at(inner);
+  for (int idx = 0; idx < length; idx += InstanceKlass::inner_class_next_offset) {
+    int idx_inner = inner_classes->at(idx + InstanceKlass::inner_class_inner_class_info_offset);
+    if (cp->klass_name_at(idx_inner) == cp_klass_name) {
+      return idx;
+    }
+  }
+  return -1;
+}
+
+// Return the outer_class_info_index for the InnerClasses entry containing the
+// specified inner_class_info_index.  Return -1 if no InnerClasses entry is found.
+static int inner_classes_jump_to_outer(const Array<u2>* inner_classes, int inner, const ConstantPool* cp, int length) {
+  if (inner == 0) return -1;
+  int idx = inner_classes_find_index(inner_classes, inner, cp, length);
+  if (idx == -1) return -1;
+  int result = inner_classes->at(idx + InstanceKlass::inner_class_outer_class_info_offset);
+  return result;
+}
+
+// Return true if circularity is found, false if no circularity is found.
+// Use Floyd's cycle finding algorithm.
+static bool inner_classes_check_loop_through_outer(const Array<u2>* inner_classes, int idx, const ConstantPool* cp, int length) {
+  int slow = inner_classes->at(idx + InstanceKlass::inner_class_inner_class_info_offset);
+  int fast = inner_classes->at(idx + InstanceKlass::inner_class_outer_class_info_offset);
+  while (fast != -1 && fast != 0) {
+    if (slow != 0 && (cp->klass_name_at(slow) == cp->klass_name_at(fast))) {
+      return true;  // found a circularity
+    }
+    fast = inner_classes_jump_to_outer(inner_classes, fast, cp, length);
+    if (fast == -1) return false;
+    fast = inner_classes_jump_to_outer(inner_classes, fast, cp, length);
+    if (fast == -1) return false;
+    slow = inner_classes_jump_to_outer(inner_classes, slow, cp, length);
+    assert(slow != -1, "sanity check");
+  }
+  return false;
+}
+
+// Loop through each InnerClasses entry checking for circularities and duplications
+// with other entries.  If duplicate entries are found then throw CFE.  Otherwise,
+// return true if a circularity or entries with duplicate inner_class_info_indexes
+// are found.
+bool ClassFileParser::check_inner_classes_circularity(const ConstantPool* cp, int length, TRAPS) {
+  // Loop through each InnerClasses entry.
+  for (int idx = 0; idx < length; idx += InstanceKlass::inner_class_next_offset) {
+    // Return true if there are circular entries.
+    if (inner_classes_check_loop_through_outer(_inner_classes, idx, cp, length)) {
+      return true;
+    }
+    // Check if there are duplicate entries or entries with the same inner_class_info_index.
+    for (int y = idx + InstanceKlass::inner_class_next_offset; y < length;
+         y += InstanceKlass::inner_class_next_offset) {
+
+      // To maintain compatibility, throw an exception if duplicate inner classes
+      // entries are found.
+      guarantee_property((_inner_classes->at(idx) != _inner_classes->at(y) ||
+                          _inner_classes->at(idx+1) != _inner_classes->at(y+1) ||
+                          _inner_classes->at(idx+2) != _inner_classes->at(y+2) ||
+                          _inner_classes->at(idx+3) != _inner_classes->at(y+3)),
+                         "Duplicate entry in InnerClasses attribute in class file %s",
+                         CHECK_(true));
+      // Return true if there are two entries with the same inner_class_info_index.
+      if (_inner_classes->at(y) == _inner_classes->at(idx)) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 // Return number of classes in the inner classes attribute table
-u2 ClassFileParser::parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
+u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ConstantPool* cp,
+                                                            u1* inner_classes_attribute_start,
                                                             bool parsed_enclosingmethod_attribute,
                                                             u2 enclosing_method_class_index,
                                                             u2 enclosing_method_method_index,
@@ -2764,25 +2839,28 @@
   }
 
   // 4347400: make sure there's no duplicate entry in the classes array
+  // Also, check for circular entries.
+  bool has_circularity = false;
   if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
-    for(int i = 0; i < length * 4; i += 4) {
-      for(int j = i + 4; j < length * 4; j += 4) {
-        guarantee_property((inner_classes->at(i)   != inner_classes->at(j) ||
-                            inner_classes->at(i+1) != inner_classes->at(j+1) ||
-                            inner_classes->at(i+2) != inner_classes->at(j+2) ||
-                            inner_classes->at(i+3) != inner_classes->at(j+3)),
-                            "Duplicate entry in InnerClasses in class file %s",
-                            CHECK_0);
+    has_circularity = check_inner_classes_circularity(cp, length * 4, CHECK_0);
+    if (has_circularity) {
+      // If circularity check failed then ignore InnerClasses attribute.
+      MetadataFactory::free_array<u2>(_loader_data, _inner_classes);
+      index = 0;
+      if (parsed_enclosingmethod_attribute) {
+        inner_classes = MetadataFactory::new_array<u2>(_loader_data, 2, CHECK_0);
+        _inner_classes = inner_classes;
+      } else {
+        _inner_classes = Universe::the_empty_short_array();
       }
     }
   }
-
   // Set EnclosingMethod class and method indexes.
   if (parsed_enclosingmethod_attribute) {
     inner_classes->at_put(index++, enclosing_method_class_index);
     inner_classes->at_put(index++, enclosing_method_method_index);
   }
-  assert(index == size, "wrong size");
+  assert(index == size || has_circularity, "wrong size");
 
   // Restore buffer's current position.
   cfs->set_current(current_mark);
@@ -3051,6 +3129,7 @@
 
   if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) {
     u2 num_of_classes = parse_classfile_inner_classes_attribute(
+                            _cp,
                             inner_classes_attribute_start,
                             parsed_innerclasses_attribute,
                             enclosing_method_class_index,
@@ -3717,16 +3796,6 @@
   info->has_nonstatic_fields = has_nonstatic_fields;
 }
 
-static bool relax_format_check_for(ClassLoaderData* loader_data) {
-  bool trusted = (loader_data->is_the_null_class_loader_data() ||
-                  SystemDictionary::is_ext_class_loader(loader_data->class_loader()));
-  bool need_verify =
-    // verifyAll
-    (BytecodeVerificationLocal && BytecodeVerificationRemote) ||
-    // verifyRemote
-    (!BytecodeVerificationLocal && BytecodeVerificationRemote && !trusted);
-  return !need_verify;
-}
 
 instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
                                                     ClassLoaderData* loader_data,
@@ -3873,7 +3942,7 @@
 
   // Check if verification needs to be relaxed for this class file
   // Do not restrict it to jdk1.0 or jdk1.1 to maintain backward compatibility (4982376)
-  _relax_verify = relax_format_check_for(_loader_data);
+  _relax_verify = Verifier::relax_verify_for(class_loader());
 
   // Constant pool
   constantPoolHandle cp = parse_constant_pool(CHECK_(nullHandle));
--- a/src/share/vm/classfile/classFileParser.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/classfile/classFileParser.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -275,7 +275,12 @@
   u2 parse_generic_signature_attribute(TRAPS);
   void parse_classfile_sourcefile_attribute(TRAPS);
   void parse_classfile_source_debug_extension_attribute(int length, TRAPS);
-  u2   parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
+
+  // Check for circularity in InnerClasses attribute.
+  bool check_inner_classes_circularity(const ConstantPool* cp, int length, TRAPS);
+
+  u2   parse_classfile_inner_classes_attribute(const ConstantPool* cp,
+                                               u1* inner_classes_attribute_start,
                                                bool parsed_enclosingmethod_attribute,
                                                u2 enclosing_method_class_index,
                                                u2 enclosing_method_method_index,
--- a/src/share/vm/classfile/symbolTable.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/classfile/symbolTable.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, 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
@@ -224,7 +224,7 @@
 // Pick hashing algorithm.
 unsigned int SymbolTable::hash_symbol(const char* s, int len) {
   return use_alternate_hashcode() ?
-           AltHashing::murmur3_32(seed(), (const jbyte*)s, len) :
+           AltHashing::halfsiphash_32(seed(), (const uint8_t*)s, len) :
            java_lang_String::hash_code(s, len);
 }
 
@@ -650,7 +650,7 @@
 
 // Pick hashing algorithm
 unsigned int StringTable::hash_string(const jchar* s, int len) {
-  return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
+  return use_alternate_hashcode() ? AltHashing::halfsiphash_32(seed(), s, len) :
                                     java_lang_String::hash_code(s, len);
 }
 
--- a/src/share/vm/classfile/systemDictionary.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/classfile/systemDictionary.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, 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
@@ -1074,6 +1074,18 @@
   return k();
 }
 
+static bool is_prohibited_package_slow(Symbol* class_name) {
+  // Caller has ResourceMark
+  int length;
+  jchar* unicode = class_name->as_unicode(length);
+  return (length >= 5 &&
+          unicode[0] == 'j' &&
+          unicode[1] == 'a' &&
+          unicode[2] == 'v' &&
+          unicode[3] == 'a' &&
+          unicode[4] == '/');
+}
+
 // Add a klass to the system from a stream (called by jni_DefineClass and
 // JVM_DefineClass).
 // Note: class_name can be NULL. In that case we do not know the name of
@@ -1121,24 +1133,33 @@
   if (!HAS_PENDING_EXCEPTION &&
       !class_loader.is_null() &&
       parsed_name != NULL &&
-      parsed_name->utf8_length() >= (int)pkglen &&
-      !strncmp((const char*)parsed_name->bytes(), pkg, pkglen)) {
-    // It is illegal to define classes in the "java." package from
-    // JVM_DefineClass or jni_DefineClass unless you're the bootclassloader
+      parsed_name->utf8_length() >= (int)pkglen) {
     ResourceMark rm(THREAD);
-    char* name = parsed_name->as_C_string();
-    char* index = strrchr(name, '/');
-    assert(index != NULL, "must be");
-    *index = '\0'; // chop to just the package name
-    while ((index = strchr(name, '/')) != NULL) {
-      *index = '.'; // replace '/' with '.' in package name
+    bool prohibited;
+    const jbyte* base = parsed_name->base();
+    if ((base[0] | base[1] | base[2] | base[3] | base[4]) & 0x80) {
+      prohibited = is_prohibited_package_slow(parsed_name);
+    } else {
+      char* name = parsed_name->as_C_string();
+      prohibited = (strncmp(name, pkg, pkglen) == 0);
     }
-    const char* fmt = "Prohibited package name: %s";
-    size_t len = strlen(fmt) + strlen(name);
-    char* message = NEW_RESOURCE_ARRAY(char, len);
-    jio_snprintf(message, len, fmt, name);
-    Exceptions::_throw_msg(THREAD_AND_LOCATION,
-      vmSymbols::java_lang_SecurityException(), message);
+    if (prohibited) {
+      // It is illegal to define classes in the "java." package from
+      // JVM_DefineClass or jni_DefineClass unless you're the bootclassloader
+      char* name = parsed_name->as_C_string();
+      char* index = strrchr(name, '/');
+      assert(index != NULL, "must be");
+      *index = '\0'; // chop to just the package name
+      while ((index = strchr(name, '/')) != NULL) {
+        *index = '.'; // replace '/' with '.' in package name
+      }
+      const char* fmt = "Prohibited package name: %s";
+      size_t len = strlen(fmt) + strlen(name);
+      char* message = NEW_RESOURCE_ARRAY(char, len);
+      jio_snprintf(message, len, fmt, name);
+      Exceptions::_throw_msg(THREAD_AND_LOCATION,
+        vmSymbols::java_lang_SecurityException(), message);
+    }
   }
 
   if (!HAS_PENDING_EXCEPTION) {
--- a/src/share/vm/classfile/verifier.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/classfile/verifier.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -101,7 +101,7 @@
     BytecodeVerificationLocal : BytecodeVerificationRemote;
 }
 
-bool Verifier::relax_access_for(oop loader) {
+bool Verifier::relax_verify_for(oop loader) {
   bool trusted = java_lang_ClassLoader::is_trusted_loader(loader);
   bool need_verify =
     // verifyAll
--- a/src/share/vm/classfile/verifier.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/classfile/verifier.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2014, 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
@@ -57,8 +57,8 @@
   // -Xverify:all/none override this value
   static bool should_verify_for(oop class_loader, bool should_verify_class);
 
-  // Relax certain access checks to enable some broken 1.1 apps to run on 1.2.
-  static bool relax_access_for(oop class_loader);
+  // Relax certain verifier checks to enable some broken 1.1 apps to run on 1.2.
+  static bool relax_verify_for(oop class_loader);
 
  private:
   static bool is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class);
--- a/src/share/vm/compiler/disassembler.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/compiler/disassembler.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -247,19 +247,24 @@
   const char* options() { return _option_buf; }
 };
 
-decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) {
-  memset(this, 0, sizeof(*this)); // Beware, this zeroes bits of fields.
-  _output = output ? output : tty;
-  _code = code;
-  if (code != NULL && code->is_nmethod())
-    _nm = (nmethod*) code;
+decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) :
+  _nm((code != NULL && code->is_nmethod()) ? (nmethod*)code : NULL),
+  _code(code),
+  _strings(),
+  _output(output ? output : tty),
+  _start(NULL),
+  _end(NULL),
+  _print_raw(0),
+  // by default, output pc but not bytes:
+  _print_pc(true),
+  _print_bytes(false),
+  _cur_insn(NULL),
+  _total_ticks(0),
+  _bytes_per_line(Disassembler::pd_instruction_alignment())
+{
+  memset(_option_buf, 0, sizeof(_option_buf));
   _strings.copy(c);
 
-  // by default, output pc but not bytes:
-  _print_pc       = true;
-  _print_bytes    = false;
-  _bytes_per_line = Disassembler::pd_instruction_alignment();
-
   // parse the global option string:
   collect_options(Disassembler::pd_cpu_opts());
   collect_options(PrintAssemblyOptions);
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -3096,7 +3096,10 @@
   }
 
   void do_object_work(oop obj) {
-    guarantee(!_g1h->obj_in_cs(obj),
+    guarantee(G1CMObjArrayProcessor::is_array_slice(obj) || obj->is_oop(),
+              err_msg("Non-oop " PTR_FORMAT ", phase: %s, info: %d",
+                      p2i((void*) obj), phase_str(), _info));
+    guarantee(G1CMObjArrayProcessor::is_array_slice(obj) || !_g1h->obj_in_cs(obj),
               err_msg("obj: " PTR_FORMAT " in CSet, phase: %s, info: %d",
                       p2i((void*) obj), phase_str(), _info));
   }
@@ -3506,18 +3509,25 @@
 template<bool scan>
 inline void CMTask::process_grey_object(oop obj) {
   assert(scan || obj->is_typeArray(), "Skipping scan of grey non-typeArray");
-  assert(_nextMarkBitMap->isMarked((HeapWord*) obj), "invariant");
 
   if (_cm->verbose_high()) {
     gclog_or_tty->print_cr("[%u] processing grey object " PTR_FORMAT,
                            _worker_id, p2i((void*) obj));
   }
 
-  size_t obj_size = obj->size();
-  _words_scanned += obj_size;
+  assert(G1CMObjArrayProcessor::is_array_slice(obj) || _nextMarkBitMap->isMarked((HeapWord*) obj),
+         "Any stolen object should be a slice or marked");
 
   if (scan) {
-    obj->oop_iterate(_cm_oop_closure);
+    if (G1CMObjArrayProcessor::is_array_slice(obj)) {
+      _words_scanned += _objArray_processor.process_slice(obj);
+    } else if (G1CMObjArrayProcessor::should_be_sliced(obj)) {
+      _words_scanned += _objArray_processor.process_obj(obj);
+    } else {
+      size_t obj_size = obj->size();
+      _words_scanned += obj_size;
+      obj->oop_iterate(_cm_oop_closure);;
+    }
   }
   statsOnly( ++_objs_scanned );
   check_limits();
@@ -3877,6 +3887,8 @@
                              _worker_id, n);
     }
     for (int i = 0; i < n; ++i) {
+      assert(G1CMObjArrayProcessor::is_array_slice(buffer[i]) || buffer[i]->is_oop(),
+             err_msg("Element " PTR_FORMAT " must be an array slice or oop", p2i(buffer[i])));
       bool success = _task_queue->push(buffer[i]);
       // We only call this when the local queue is empty or under a
       // given target limit. So, we do not expect this push to fail.
@@ -3895,7 +3907,9 @@
 }
 
 void CMTask::drain_local_queue(bool partially) {
-  if (has_aborted()) return;
+  if (has_aborted()) {
+    return;
+  }
 
   // Decide what the target size is, depending whether we're going to
   // drain it partially (so that other tasks can steal if they run out
@@ -3923,10 +3937,6 @@
                                p2i((void*) obj));
       }
 
-      assert(_g1h->is_in_g1_reserved((HeapWord*) obj), "invariant" );
-      assert(!_g1h->is_on_master_free_list(
-                  _g1h->heap_region_containing((HeapWord*) obj)), "invariant");
-
       scan_object(obj);
 
       if (_task_queue->size() <= target_size || has_aborted()) {
@@ -4427,8 +4437,6 @@
 
         statsOnly( ++_steals );
 
-        assert(_nextMarkBitMap->isMarked((HeapWord*) obj),
-               "any stolen object should be marked");
         scan_object(obj);
 
         // And since we're towards the end, let's totally drain the
@@ -4602,6 +4610,7 @@
                CMTaskQueueSet* task_queues)
   : _g1h(G1CollectedHeap::heap()),
     _worker_id(worker_id), _cm(cm),
+    _objArray_processor(this),
     _claimed(false),
     _nextMarkBitMap(NULL), _hash_seed(17),
     _task_queue(task_queue),
--- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -26,6 +26,7 @@
 #define SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_HPP
 
 #include "classfile/javaClasses.hpp"
+#include "gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.hpp"
 #include "gc_implementation/g1/heapRegionSet.hpp"
 #include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
 #include "gc_implementation/shared/gcId.hpp"
@@ -942,7 +943,7 @@
     words_scanned_period          = 12*1024,
     // the regular clock call is called once the number of visited
     // references reaches this limit
-    refs_reached_period           = 384,
+    refs_reached_period           = 1024,
     // initial value for the hash seed, used in the work stealing code
     init_hash_seed                = 17,
     // how many entries will be transferred between global stack and
@@ -950,6 +951,8 @@
     global_stack_transfer_size    = 16
   };
 
+  G1CMObjArrayProcessor       _objArray_processor;
+
   uint                        _worker_id;
   G1CollectedHeap*            _g1h;
   ConcurrentMark*             _cm;
@@ -1110,6 +1113,9 @@
   template<bool scan> void process_grey_object(oop obj);
 
 public:
+  // Apply the closure on the given area of the objArray. Return the number of words
+  // scanned.
+  inline size_t scan_objArray(objArrayOop obj, MemRegion mr);
   // It resets the task; it should be called right at the beginning of
   // a marking phase.
   void reset(CMBitMap* _nextMarkBitMap);
--- a/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -27,6 +27,7 @@
 
 #include "gc_implementation/g1/concurrentMark.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+#include "gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp"
 
 // Utility routine to set an exclusive range of cards on the given
 // card liveness bitmap
@@ -224,11 +225,11 @@
 
 inline void CMTask::push(oop obj) {
   HeapWord* objAddr = (HeapWord*) obj;
-  assert(_g1h->is_in_g1_reserved(objAddr), "invariant");
-  assert(!_g1h->is_on_master_free_list(
+  assert(G1CMObjArrayProcessor::is_array_slice(obj) || _g1h->is_in_g1_reserved(objAddr), "invariant");
+  assert(G1CMObjArrayProcessor::is_array_slice(obj) || !_g1h->is_on_master_free_list(
               _g1h->heap_region_containing((HeapWord*) objAddr)), "invariant");
-  assert(!_g1h->is_obj_ill(obj), "invariant");
-  assert(_nextMarkBitMap->isMarked(objAddr), "invariant");
+  assert(G1CMObjArrayProcessor::is_array_slice(obj) || !_g1h->is_obj_ill(obj), "invariant");
+  assert(G1CMObjArrayProcessor::is_array_slice(obj) || _nextMarkBitMap->isMarked(objAddr), "invariant");
 
   if (_cm->verbose_high()) {
     gclog_or_tty->print_cr("[%u] pushing " PTR_FORMAT, _worker_id, p2i((void*) obj));
@@ -365,6 +366,11 @@
   }
 }
 
+inline size_t CMTask::scan_objArray(objArrayOop obj, MemRegion mr) {
+  obj->oop_iterate(_cm_oop_closure, mr);
+  return mr.word_size();
+}
+
 inline void ConcurrentMark::markPrev(oop p) {
   assert(!_prevMarkBitMap->isMarked((HeapWord*) p), "sanity");
   // Note we are overriding the read-only view of the prev map here, via
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_implementation/g1/concurrentMark.inline.hpp"
+#include "gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp"
+
+oop G1CMObjArrayProcessor::encode_array_slice(HeapWord* addr) {
+  return oop((void*)((uintptr_t)addr | ArraySliceBit));
+}
+
+HeapWord* G1CMObjArrayProcessor::decode_array_slice(oop value) {
+  assert(is_array_slice(value), err_msg("Given value " PTR_FORMAT " is not an array slice", p2i(value)));
+  return (HeapWord*)((uintptr_t)(void*)value & ~ArraySliceBit);
+}
+
+void G1CMObjArrayProcessor::push_array_slice(HeapWord* what) {
+  oop obj = encode_array_slice(what);
+  _task->push(obj);
+}
+
+size_t G1CMObjArrayProcessor::process_array_slice(objArrayOop obj, HeapWord* start_from, size_t remaining) {
+  size_t words_to_scan = MIN2(remaining, ObjArrayMarkingStride);
+
+  if (remaining > ObjArrayMarkingStride) {
+    push_array_slice(start_from + ObjArrayMarkingStride);
+  }
+
+  // Then process current area.
+  MemRegion mr(start_from, words_to_scan);
+  return _task->scan_objArray(obj, mr);
+}
+
+size_t G1CMObjArrayProcessor::process_obj(oop obj) {
+  assert(should_be_sliced(obj), err_msg("Must be an array object %d and large " SIZE_FORMAT, obj->is_objArray(), (size_t)obj->size()));
+
+  return process_array_slice(objArrayOop(obj), (HeapWord*)obj, (size_t)objArrayOop(obj)->size());
+}
+
+size_t G1CMObjArrayProcessor::process_slice(oop obj) {
+  HeapWord* const decoded_address = decode_array_slice(obj);
+
+  // Find the start address of the objArrayOop.
+  // Shortcut the BOT access if the given address is from a humongous object. The BOT
+  // slide is fast enough for "smaller" objects in non-humongous regions, but is slower
+  // than directly using heap region table.
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
+  HeapRegion* r = g1h->heap_region_containing(decoded_address);
+
+  HeapWord* const start_address = r->isHumongous() ?
+                                  r->humongous_start_region()->bottom() :
+                                  g1h->block_start(decoded_address);
+
+  assert(oop(start_address)->is_objArray(), err_msg("Address " PTR_FORMAT " does not refer to an object array ", p2i(start_address)));
+  assert(start_address < decoded_address,
+         err_msg("Object start address " PTR_FORMAT " must be smaller than decoded address " PTR_FORMAT,
+         p2i(start_address),
+         p2i(decoded_address)));
+
+  objArrayOop objArray = objArrayOop(start_address);
+
+  size_t already_scanned = decoded_address - start_address;
+  size_t remaining = objArray->size() - already_scanned;
+
+  return process_array_slice(objArray, decoded_address, remaining);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_HPP
+#define SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_HPP
+
+#include "oops/oopsHierarchy.hpp"
+#include "memory/allocation.hpp"
+
+class CMTask;
+
+// Helper class to mark through large objArrays during marking in an efficient way.
+// Instead of pushing large object arrays, we push continuations onto the
+// mark stack. These continuations are identified by having their LSB set.
+// This allows incremental processing of large objects.
+class G1CMObjArrayProcessor VALUE_OBJ_CLASS_SPEC {
+private:
+  // The bit mask for the continuation indicator of elements on the mark stack.
+  static const size_t ArraySliceBit = 1;
+
+  // Reference to the task for doing the actual work.
+  CMTask* _task;
+
+  // Encodes the given address as a continuation "oop".
+  oop encode_array_slice(HeapWord* addr);
+  // Remove the continuation marker from the given oop from the mark stack.
+  HeapWord* decode_array_slice(oop value);
+
+  // Push the continuation at the given address onto the mark stack.
+  void push_array_slice(HeapWord* addr);
+
+  // Process (apply the closure) on the given continuation of the given objArray.
+  size_t process_array_slice(objArrayOop const obj, HeapWord* start_from, size_t remaining);
+public:
+  static bool is_array_slice(void* obj) { return ((uintptr_t)obj & ArraySliceBit) != 0; }
+
+  static bool should_be_sliced(oop obj);
+
+  G1CMObjArrayProcessor(CMTask* task) : _task(task) {
+  }
+
+  // Process the given continuation "oop". Returns the number of words scanned.
+  size_t process_slice(oop obj);
+  // Start processing the given objArrayOop by scanning the header and pushing its
+  // continuation.
+  size_t process_obj(oop obj);
+};
+
+#endif /* SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_INLINE_HPP
+#define SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_INLINE_HPP
+
+#include "oops/oop.inline.hpp"
+#include "oops/oopsHierarchy.hpp"
+#include "runtime/globals.hpp"
+
+inline bool G1CMObjArrayProcessor::should_be_sliced(oop obj) {
+  return obj->is_objArray() && ((size_t)((objArrayOop)obj)->size()) >= 2 * ObjArrayMarkingStride;
+}
+
+#endif /* SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_INLINE_HPP */
--- a/src/share/vm/gc_implementation/g1/g1StringDedupTable.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/gc_implementation/g1/g1StringDedupTable.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -215,7 +215,7 @@
 uintx                    G1StringDedupTable::_resize_count = 0;
 uintx                    G1StringDedupTable::_rehash_count = 0;
 
-G1StringDedupTable::G1StringDedupTable(size_t size, jint hash_seed) :
+G1StringDedupTable::G1StringDedupTable(size_t size, uint64_t hash_seed) :
   _size(size),
   _entries(0),
   _grow_threshold((uintx)(size * _grow_load_factor)),
@@ -319,9 +319,8 @@
   if (use_java_hash()) {
     hash = java_lang_String::hash_code(data, length);
   } else {
-    hash = AltHashing::murmur3_32(_table->_hash_seed, data, length);
+    hash = AltHashing::halfsiphash_32(_table->_hash_seed, (const uint16_t*)data, length);
   }
-
   return hash;
 }
 
@@ -600,7 +599,7 @@
     "      [Size: " SIZE_FORMAT ", Min: " SIZE_FORMAT ", Max: " SIZE_FORMAT "]\n"
     "      [Entries: " UINTX_FORMAT ", Load: " G1_STRDEDUP_PERCENT_FORMAT_NS ", Cached: " SIZE_FORMAT ", Added: " UINTX_FORMAT ", Removed: " UINTX_FORMAT "]\n"
     "      [Resize Count: " UINTX_FORMAT ", Shrink Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS "), Grow Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS ")]\n"
-    "      [Rehash Count: " UINTX_FORMAT ", Rehash Threshold: " UINTX_FORMAT ", Hash Seed: 0x%x]\n"
+    "      [Rehash Count: " UINTX_FORMAT ", Rehash Threshold: " UINTX_FORMAT ", Hash Seed: " UINT64_FORMAT "]\n"
     "      [Age Threshold: " UINTX_FORMAT "]",
     G1_STRDEDUP_BYTES_PARAM(_table->_size * sizeof(G1StringDedupEntry*) + (_table->_entries + _entry_cache->size()) * sizeof(G1StringDedupEntry)),
     _table->_size, _min_size, _max_size,
--- a/src/share/vm/gc_implementation/g1/g1StringDedupTable.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/gc_implementation/g1/g1StringDedupTable.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -38,8 +38,8 @@
 class G1StringDedupEntry : public CHeapObj<mtGC> {
 private:
   G1StringDedupEntry* _next;
-  unsigned int      _hash;
-  typeArrayOop      _obj;
+  unsigned int        _hash;
+  typeArrayOop        _obj;
 
 public:
   G1StringDedupEntry() :
@@ -119,8 +119,8 @@
   // The hash seed also dictates which hash function to use. A
   // zero hash seed means we will use the Java compatible hash
   // function (which doesn't use a seed), and a non-zero hash
-  // seed means we use the murmur3 hash function.
-  jint                            _hash_seed;
+  // seed means we use the murmur3 and better hash function.
+  uint64_t                        _hash_seed;
 
   // Constants governing table resize/rehash/cache.
   static const size_t             _min_size;
@@ -137,7 +137,7 @@
   static uintx                    _resize_count;
   static uintx                    _rehash_count;
 
-  G1StringDedupTable(size_t size, jint hash_seed = 0);
+  G1StringDedupTable(size_t size, uint64_t hash_seed = 0);
   ~G1StringDedupTable();
 
   // Returns the hash bucket at the given index.
--- a/src/share/vm/jfr/instrumentation/jfrJvmtiAgent.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/jfr/instrumentation/jfrJvmtiAgent.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2019, 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
@@ -31,9 +31,7 @@
 #include "jfr/recorder/service/jfrOptionSet.hpp"
 #include "jfr/support/jfrEventClass.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvmtiEnvBase.hpp"
 #include "prims/jvmtiExport.hpp"
-#include "prims/jvmtiUtil.hpp"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/thread.inline.hpp"
 #include "utilities/exceptions.hpp"
@@ -53,17 +51,19 @@
   }
 }
 
-static bool set_event_notification_mode(jvmtiEventMode mode,
-                                        jvmtiEvent event,
-                                        jthread event_thread,
-                                        ...) {
-  assert(jfr_jvmti_env != NULL, "invariant");
+static jvmtiError set_event_notification_mode(jvmtiEventMode mode,
+                                              jvmtiEvent event,
+                                              jthread event_thread,
+                                              ...) {
+  if (jfr_jvmti_env == NULL) {
+    return JVMTI_ERROR_NONE;
+  }
   const jvmtiError jvmti_ret_code = jfr_jvmti_env->SetEventNotificationMode(mode, event, event_thread);
   check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "SetEventNotificationMode");
-  return jvmti_ret_code == JVMTI_ERROR_NONE;
+  return jvmti_ret_code;
 }
 
-static bool update_class_file_load_hook_event(jvmtiEventMode mode) {
+static jvmtiError update_class_file_load_hook_event(jvmtiEventMode mode) {
   return set_event_notification_mode(mode, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
 }
 
@@ -116,23 +116,12 @@
   return classes;
 }
 
-// caller needs ResourceMark
-static void log_and_throw(jvmtiError error, TRAPS) {
+static void log_and_throw(TRAPS) {
   if (!HAS_PENDING_EXCEPTION) {
     DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(THREAD));
     ThreadInVMfromNative tvmfn((JavaThread*)THREAD);
-    const char base_error_msg[] = "JfrJvmtiAgent::retransformClasses failed: ";
-    size_t length = sizeof base_error_msg; // includes terminating null
-    const char* const jvmti_error_name = JvmtiUtil::error_name(error);
-    assert(jvmti_error_name != NULL, "invariant");
-    length += strlen(jvmti_error_name);
-    char* error_msg = NEW_RESOURCE_ARRAY(char, length);
-    jio_snprintf(error_msg, length, "%s%s", base_error_msg, jvmti_error_name);
-    if (JVMTI_ERROR_INVALID_CLASS_FORMAT == error) {
-      JfrJavaSupport::throw_class_format_error(error_msg, THREAD);
-    } else {
-      JfrJavaSupport::throw_runtime_exception(error_msg, THREAD);
-    }
+    if (true) tty->print_cr("JfrJvmtiAgent::retransformClasses failed");
+    JfrJavaSupport::throw_class_format_error("JfrJvmtiAgent::retransformClasses failed", THREAD);
   }
 }
 
@@ -147,15 +136,12 @@
   }
 }
 
-static bool is_valid_jvmti_phase() {
-  return JvmtiEnvBase::get_phase() == JVMTI_PHASE_LIVE;
-}
-
 void JfrJvmtiAgent::retransform_classes(JNIEnv* env, jobjectArray classes_array, TRAPS) {
   assert(env != NULL, "invariant");
-  assert(classes_array != NULL, "invariant");
-  assert(is_valid_jvmti_phase(), "invariant");
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(THREAD));
+  if (classes_array == NULL) {
+    return;
+  }
   const jint classes_count = env->GetArrayLength(classes_array);
   if (classes_count <= 0) {
     return;
@@ -166,27 +152,27 @@
   for (jint i = 0; i < classes_count; i++) {
     jclass clz = (jclass)env->GetObjectArrayElement(classes_array, i);
     check_exception_and_log(env, THREAD);
-    classes[i] = clz;
-  }
-  {
+
     // inspecting the oop/klass requires a thread transition
-    ThreadInVMfromNative transition((JavaThread*)THREAD);
-    for (jint i = 0; i < classes_count; ++i) {
-      jclass clz = classes[i];
-      if (!JdkJfrEvent::is_a(clz)) {
+    {
+      ThreadInVMfromNative transition((JavaThread*)THREAD);
+      if (JdkJfrEvent::is_a(clz)) {
+        // should have been tagged already
+        assert(JdkJfrEvent::is_subklass(clz), "invariant");
+      } else {
         // outside the event hierarchy
         JdkJfrEvent::tag_as_host(clz);
       }
     }
+
+    classes[i] = clz;
   }
-  DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(THREAD));
-  const jvmtiError result = jfr_jvmti_env->RetransformClasses(classes_count, classes);
-  if (result != JVMTI_ERROR_NONE) {
-    log_and_throw(result, THREAD);
+  if (jfr_jvmti_env->RetransformClasses(classes_count, classes) != JVMTI_ERROR_NONE) {
+    log_and_throw(THREAD);
   }
 }
 
-static bool register_callbacks(JavaThread* jt) {
+static jvmtiError register_callbacks(JavaThread* jt) {
   assert(jfr_jvmti_env != NULL, "invariant");
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(jt));
   jvmtiEventCallbacks callbacks;
@@ -195,10 +181,10 @@
   callbacks.ClassFileLoadHook = jfr_on_class_file_load_hook;
   const jvmtiError jvmti_ret_code = jfr_jvmti_env->SetEventCallbacks(&callbacks, sizeof(callbacks));
   check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "SetEventCallbacks");
-  return jvmti_ret_code == JVMTI_ERROR_NONE;
+  return jvmti_ret_code;
 }
 
-static bool register_capabilities(JavaThread* jt) {
+static jvmtiError register_capabilities(JavaThread* jt) {
   assert(jfr_jvmti_env != NULL, "invariant");
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(jt));
   jvmtiCapabilities capabilities;
@@ -208,7 +194,7 @@
   capabilities.can_retransform_any_class = 1;
   const jvmtiError jvmti_ret_code = jfr_jvmti_env->AddCapabilities(&capabilities);
   check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "Add Capabilities");
-  return jvmti_ret_code == JVMTI_ERROR_NONE;
+  return jvmti_ret_code;
 }
 
 static jint create_jvmti_env(JavaThread* jt) {
@@ -219,14 +205,16 @@
   return vm->GetEnv((void **)&jfr_jvmti_env, JVMTI_VERSION);
 }
 
-static bool unregister_callbacks(JavaThread* jt) {
-  assert(jfr_jvmti_env != NULL, "invariant");
+static jvmtiError unregister_callbacks(JavaThread* jt) {
+  if (jfr_jvmti_env == NULL) {
+    return JVMTI_ERROR_NONE;
+  }
   jvmtiEventCallbacks callbacks;
   /* Set empty callbacks */
   memset(&callbacks, 0, sizeof(callbacks));
   const jvmtiError jvmti_ret_code = jfr_jvmti_env->SetEventCallbacks(&callbacks, sizeof(callbacks));
   check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "SetEventCallbacks");
-  return jvmti_ret_code == JVMTI_ERROR_NONE;
+  return jvmti_ret_code;
 }
 
 JfrJvmtiAgent::JfrJvmtiAgent() {}
@@ -234,17 +222,20 @@
 JfrJvmtiAgent::~JfrJvmtiAgent() {
   JavaThread* jt = current_java_thread();
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(jt));
+  ThreadToNativeFromVM transition(jt);
+  update_class_file_load_hook_event(JVMTI_DISABLE);
+  unregister_callbacks(jt);
   if (jfr_jvmti_env != NULL) {
-    ThreadToNativeFromVM transition(jt);
-    update_class_file_load_hook_event(JVMTI_DISABLE);
-    unregister_callbacks(jt);
     jfr_jvmti_env->DisposeEnvironment();
     jfr_jvmti_env = NULL;
   }
+  agent = NULL;
 }
 
-static bool initialize(JavaThread* jt) {
+static bool initialize() {
+  JavaThread* const jt = current_java_thread();
   assert(jt != NULL, "invariant");
+  assert(jt->thread_state() == _thread_in_vm, "invariant");
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(jt));
   ThreadToNativeFromVM transition(jt);
   if (create_jvmti_env(jt) != JNI_OK) {
@@ -252,38 +243,25 @@
     return false;
   }
   assert(jfr_jvmti_env != NULL, "invariant");
-  if (!register_capabilities(jt)) {
-    return false;
-  }
-  if (!register_callbacks(jt)) {
+  if (register_capabilities(jt) != JVMTI_ERROR_NONE) {
     return false;
   }
-  return update_class_file_load_hook_event(JVMTI_ENABLE);
-}
-
-static void log_and_throw_illegal_state_exception(TRAPS) {
-  DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
-  const char* const illegal_state_msg = "An attempt was made to start JFR too early in the VM initialization sequence.";
-  if (true) {
-    tty->print_cr("%s\n", illegal_state_msg);
-    tty->print_cr("JFR uses JVMTI RetransformClasses and requires the JVMTI state to have entered JVMTI_PHASE_LIVE.\n");
-    tty->print_cr("Please initialize JFR in response to event JVMTI_EVENT_VM_INIT instead of JVMTI_EVENT_VM_START.\n");
+  if (register_callbacks(jt) != JVMTI_ERROR_NONE) {
+    return false;
   }
-  JfrJavaSupport::throw_illegal_state_exception(illegal_state_msg, THREAD);
+  if (update_class_file_load_hook_event(JVMTI_ENABLE) != JVMTI_ERROR_NONE) {
+    return false;
+  }
+  return true;
 }
 
 bool JfrJvmtiAgent::create() {
-  assert(agent == NULL, "invariant");
-  JavaThread* const jt = current_java_thread();
-  if (!is_valid_jvmti_phase()) {
-    log_and_throw_illegal_state_exception(jt);
-    return false;
-  }
+  assert(jfr_jvmti_env == NULL, "invariant");
   agent = new JfrJvmtiAgent();
   if (agent == NULL) {
     return false;
   }
-  if (!initialize(jt)) {
+  if (!initialize()) {
     delete agent;
     agent = NULL;
     return false;
@@ -297,3 +275,4 @@
     agent = NULL;
   }
 }
+
--- a/src/share/vm/jfr/jfr.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/jfr/jfr.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -32,7 +32,6 @@
 #include "jfr/recorder/service/jfrOptionSet.hpp"
 #include "jfr/support/jfrThreadLocal.hpp"
 #include "runtime/java.hpp"
-#include "utilities/defaultStream.hpp"
 
 bool Jfr::is_enabled() {
   return JfrRecorder::is_enabled();
@@ -46,21 +45,15 @@
   return JfrRecorder::is_recording();
 }
 
-void Jfr::on_create_vm_1() {
-  if (!JfrRecorder::on_create_vm_1()) {
-    vm_exit_during_initialization("Failure when starting JFR on_create_vm_1");
+void Jfr::on_vm_init() {
+  if (!JfrRecorder::on_vm_init()) {
+    vm_exit_during_initialization("Failure when starting JFR on_vm_init");
   }
 }
 
-void Jfr::on_create_vm_2() {
-  if (!JfrRecorder::on_create_vm_2()) {
-    vm_exit_during_initialization("Failure when starting JFR on_create_vm_2");
-  }
-}
-
-void Jfr::on_create_vm_3() {
-  if (!JfrRecorder::on_create_vm_3()) {
-    vm_exit_during_initialization("Failure when starting JFR on_create_vm_3");
+void Jfr::on_vm_start() {
+  if (!JfrRecorder::on_vm_start()) {
+    vm_exit_during_initialization("Failure when starting JFR on_vm_start");
   }
 }
 
--- a/src/share/vm/jfr/jfr.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/jfr/jfr.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -43,9 +43,8 @@
   static bool is_enabled();
   static bool is_disabled();
   static bool is_recording();
-  static void on_create_vm_1();
-  static void on_create_vm_2();
-  static void on_create_vm_3();
+  static void on_vm_init();
+  static void on_vm_start();
   static void on_unloading_classes();
   static void on_thread_start(Thread* thread);
   static void on_thread_exit(Thread* thread);
--- a/src/share/vm/jfr/jni/jfrJavaSupport.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/jfr/jni/jfrJavaSupport.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -515,10 +515,6 @@
   create_and_throw(vmSymbols::java_lang_ClassFormatError(), message, THREAD);
 }
 
-void JfrJavaSupport::throw_runtime_exception(const char* message, TRAPS) {
-  create_and_throw(vmSymbols::java_lang_RuntimeException(), message, THREAD);
-}
-
 void JfrJavaSupport::abort(jstring errorMsg, Thread* t) {
   DEBUG_ONLY(check_java_thread_in_vm(t));
 
--- a/src/share/vm/jfr/jni/jfrJavaSupport.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/jfr/jni/jfrJavaSupport.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -81,7 +81,6 @@
   static void throw_internal_error(const char* message, TRAPS);
   static void throw_out_of_memory_error(const char* message, TRAPS);
   static void throw_class_format_error(const char* message, TRAPS);
-  static void throw_runtime_exception(const char* message, TRAPS);
 
   static jlong jfr_thread_id(jobject target_thread);
 
--- a/src/share/vm/jfr/jni/jfrJniMethod.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/jfr/jni/jfrJniMethod.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -191,9 +191,7 @@
     return JNI_TRUE;
   }
   if (!JfrRecorder::create(simulate_failure == JNI_TRUE)) {
-    if (!thread->has_pending_exception()) {
-      JfrJavaSupport::throw_illegal_state_exception("Unable to start Jfr", thread);
-    }
+    JfrJavaSupport::throw_illegal_state_exception("Unable to start Jfr", thread);
     return JNI_FALSE;
   }
   return JNI_TRUE;
--- a/src/share/vm/jfr/recorder/jfrRecorder.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/jfr/recorder/jfrRecorder.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -44,9 +44,6 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/globals_extension.hpp"
 #include "utilities/growableArray.hpp"
-#ifdef ASSERT
-#include "prims/jvmtiEnvBase.hpp"
-#endif
 
 bool JfrRecorder::_shutting_down = false;
 
@@ -60,9 +57,7 @@
 
 static bool enable() {
   assert(!_enabled, "invariant");
-  if (!FlightRecorder) {
-    FLAG_SET_MGMT(bool, FlightRecorder, true);
-  }
+  FLAG_SET_MGMT(bool, FlightRecorder, true);
   _enabled = FlightRecorder;
   assert(_enabled, "invariant");
   return _enabled;
@@ -72,7 +67,7 @@
   return _enabled;
 }
 
-bool JfrRecorder::on_create_vm_1() {
+bool JfrRecorder::on_vm_init() {
   if (!is_disabled()) {
     if (FlightRecorder || StartFlightRecording != NULL) {
       enable();
@@ -97,7 +92,7 @@
 
 static void teardown_startup_support() {
   release_recordings();
-  JfrOptionSet::release_start_flight_recording_options();
+  JfrOptionSet::release_startup_recording_options();
 }
 
 // Parsing options here to detect errors as soon as possible
@@ -115,7 +110,7 @@
 }
 
 static bool validate_recording_options(TRAPS) {
-  const GrowableArray<const char*>* options = JfrOptionSet::start_flight_recording_options();
+  const GrowableArray<const char*>* options = JfrOptionSet::startup_recording_options();
   if (options == NULL) {
     return true;
   }
@@ -148,7 +143,7 @@
   return true;
 }
 
-static bool launch_command_line_recordings(TRAPS) {
+static bool launch_recordings(TRAPS) {
   bool result = true;
   if (dcmd_recordings_array != NULL) {
     const int length = dcmd_recordings_array->length();
@@ -166,7 +161,7 @@
 
 static bool is_cds_dump_requested() {
   // we will not be able to launch recordings if a cds dump is being requested
-  if (DumpSharedSpaces && (JfrOptionSet::start_flight_recording_options() != NULL)) {
+  if (DumpSharedSpaces && (JfrOptionSet::startup_recording_options() != NULL)) {
     warning("JFR will be disabled during CDS dumping");
     teardown_startup_support();
     return true;
@@ -174,7 +169,7 @@
   return false;
 }
 
-bool JfrRecorder::on_create_vm_2() {
+bool JfrRecorder::on_vm_start() {
   if (is_cds_dump_requested()) {
     return true;
   }
@@ -201,14 +196,10 @@
   if (!is_enabled()) {
     return true;
   }
-  return true;
+
+  return launch_recordings(thread);
 }
 
-bool JfrRecorder::on_create_vm_3() {
-  assert(JvmtiEnvBase::get_phase() == JVMTI_PHASE_LIVE, "invalid init sequence");
-  return launch_command_line_recordings(Thread::current());
- }
-
 static bool _created = false;
 
 //
@@ -275,6 +266,7 @@
 }
 
 // subsystems
+static JfrJvmtiAgent* _jvmti_agent = NULL;
 static JfrPostBox* _post_box = NULL;
 static JfrStorage* _storage = NULL;
 static JfrCheckpointManager* _checkpoint_manager = NULL;
--- a/src/share/vm/jfr/recorder/jfrRecorder.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/jfr/recorder/jfrRecorder.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -40,9 +40,6 @@
  private:
   static bool _shutting_down;
 
-  static bool on_create_vm_1();
-  static bool on_create_vm_2();
-  static bool on_create_vm_3();
   static bool create_checkpoint_manager();
   static bool create_chunk_repository();
   static bool create_java_event_writer();
@@ -57,6 +54,8 @@
   static bool create_components();
   static void destroy_components();
   static void on_recorder_thread_exit();
+  static bool on_vm_start();
+  static bool on_vm_init();
 
  public:
   static bool is_enabled();
--- a/src/share/vm/jfr/recorder/service/jfrOptionSet.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/jfr/recorder/service/jfrOptionSet.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -676,7 +676,7 @@
   return false;
 }
 
-static GrowableArray<const char*>* start_flight_recording_options_array = NULL;
+static GrowableArray<const char*>* startup_recording_options_array = NULL;
 
 bool JfrOptionSet::parse_start_flight_recording_option(const JavaVMOption** option, char* delimiter) {
   assert(option != NULL, "invariant");
@@ -699,28 +699,28 @@
   assert(value != NULL, "invariant");
   const size_t value_length = strlen(value);
 
-  if (start_flight_recording_options_array == NULL) {
-    start_flight_recording_options_array = new (ResourceObj::C_HEAP, mtTracing) GrowableArray<const char*>(8, true, mtTracing);
+  if (startup_recording_options_array == NULL) {
+    startup_recording_options_array = new (ResourceObj::C_HEAP, mtTracing) GrowableArray<const char*>(8, true, mtTracing);
   }
-  assert(start_flight_recording_options_array != NULL, "invariant");
+  assert(startup_recording_options_array != NULL, "invariant");
   char* const startup_value = NEW_C_HEAP_ARRAY(char, value_length + 1, mtTracing);
   strncpy(startup_value, value, value_length + 1);
   assert(strncmp(startup_value, value, value_length) == 0, "invariant");
-  start_flight_recording_options_array->append(startup_value);
+  startup_recording_options_array->append(startup_value);
   return false;
 }
 
-const GrowableArray<const char*>* JfrOptionSet::start_flight_recording_options() {
-  return start_flight_recording_options_array;
+const GrowableArray<const char*>* JfrOptionSet::startup_recording_options() {
+  return startup_recording_options_array;
 }
 
-void JfrOptionSet::release_start_flight_recording_options() {
-  if (start_flight_recording_options_array != NULL) {
-    const int length = start_flight_recording_options_array->length();
+void JfrOptionSet::release_startup_recording_options() {
+  if (startup_recording_options_array != NULL) {
+    const int length = startup_recording_options_array->length();
     for (int i = 0; i < length; ++i) {
-      FREE_C_HEAP_ARRAY(char, start_flight_recording_options_array->at(i), mtTracing);
+      FREE_C_HEAP_ARRAY(char, startup_recording_options_array->at(i), mtTracing);
     }
-    delete start_flight_recording_options_array;
-    start_flight_recording_options_array = NULL;
+    delete startup_recording_options_array;
+    startup_recording_options_array = NULL;
   }
 }
--- a/src/share/vm/jfr/recorder/service/jfrOptionSet.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/jfr/recorder/service/jfrOptionSet.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -80,8 +80,8 @@
 
   static bool parse_flight_recorder_option(const JavaVMOption** option, char* delimiter);
   static bool parse_start_flight_recording_option(const JavaVMOption** option, char* delimiter);
-  static const GrowableArray<const char*>* start_flight_recording_options();
-  static void release_start_flight_recording_options();
+  static const GrowableArray<const char*>* startup_recording_options();
+  static void release_startup_recording_options();
 };
 
 #endif // SHARE_VM_JFR_RECORDER_SERVICE_JFROPTIONSET_HPP
--- a/src/share/vm/jfr/writers/jfrWriterHost.inline.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/jfr/writers/jfrWriterHost.inline.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -70,7 +70,8 @@
 inline void WriterHost<BE, IE, WriterPolicyImpl>::write(const T* value, size_t len) {
   assert(value != NULL, "invariant");
   assert(len > 0, "invariant");
-  u1* const pos = ensure_size(sizeof(T) * len);
+  // Might need T + 1 size
+  u1* const pos = ensure_size(sizeof(T) * len + len);
   if (pos) {
     this->set_current_pos(write(value, len, pos));
   }
@@ -124,7 +125,8 @@
 inline void WriterHost<BE, IE, WriterPolicyImpl>::be_write(const T* value, size_t len) {
   assert(value != NULL, "invariant");
   assert(len > 0, "invariant");
-  u1* const pos = ensure_size(sizeof(T) * len);
+  // Might need T + 1 size
+  u1* const pos = ensure_size(sizeof(T) * len + len);
   if (pos) {
     this->set_current_pos(BE::be_write(value, len, pos));
   }
@@ -137,10 +139,17 @@
   _compressed_integers(compressed_integers()) {
 }
 
+// Extra size added as a safety cushion when dimensioning memory.
+// With varint encoding, the worst case is
+// associated with writing negative values.
+// For example, writing a negative s1 (-1)
+// will encode as 0xff 0x0f (2 bytes).
+static const size_t size_safety_cushion = 1;
+
 template <typename BE, typename IE, typename WriterPolicyImpl >
 template <typename StorageType>
 inline WriterHost<BE, IE, WriterPolicyImpl>::WriterHost(StorageType* storage, size_t size) :
-  WriterPolicyImpl(storage, size),
+  WriterPolicyImpl(storage, size + size_safety_cushion),
   _compressed_integers(compressed_integers()) {
 }
 
@@ -150,30 +159,19 @@
   _compressed_integers(compressed_integers()) {
 }
 
-// Extra size added as a safety cushion when dimensioning memory.
-// With varint encoding, the worst case is
-// associated with writing negative values.
-// For example, writing a negative s1 (-1)
-// will encode as 0xff 0x0f (2 bytes).
-// In this example, the sizeof(T) == 1 and length == 1,
-// but the implementation will need to dimension
-// 2 bytes for the encoding.
-// Hopefully, negative values should be relatively rare.
-static const size_t size_safety_cushion = 1;
-
 template <typename BE, typename IE, typename WriterPolicyImpl>
-inline u1* WriterHost<BE, IE, WriterPolicyImpl>::ensure_size(size_t requested) {
+inline u1* WriterHost<BE, IE, WriterPolicyImpl>::ensure_size(size_t requested_size) {
   if (!this->is_valid()) {
     // cancelled
     return NULL;
   }
-  if (this->available_size() < requested + size_safety_cushion) {
-    if (!this->accommodate(this->used_size(), requested + size_safety_cushion)) {
+  if (this->available_size() < requested_size) {
+    if (!this->accommodate(this->used_size(), requested_size)) {
       this->cancel();
       return NULL;
     }
   }
-  assert(requested + size_safety_cushion <= this->available_size(), "invariant");
+  assert(requested_size <= this->available_size(), "invariant");
   return this->current_pos();
 }
 
--- a/src/share/vm/memory/filemap.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/memory/filemap.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -125,7 +125,7 @@
   } else {
     // Get the hash value.  Use a static seed because the hash needs to return the same
     // value over multiple jvm invocations.
-    unsigned int hash = AltHashing::murmur3_32(8191, (const jbyte*)vm_version, version_len);
+    uint32_t hash = AltHashing::halfsiphash_32(8191, (const uint8_t*)vm_version, version_len);
 
     // Truncate the ident, saving room for the 8 hex character hash value.
     strncpy(header_version, vm_version, JVM_IDENT_MAX-9);
--- a/src/share/vm/memory/metaspaceShared.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/memory/metaspaceShared.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -723,12 +723,15 @@
     int class_list_path_len = (int)strlen(class_list_path_str);
     if (class_list_path_len >= 3) {
       if (strcmp(class_list_path_str + class_list_path_len - 3, "lib") != 0) {
-        strcat(class_list_path_str, os::file_separator());
-        strcat(class_list_path_str, "lib");
+        jio_snprintf(class_list_path_str + class_list_path_len,
+                     sizeof(class_list_path_str) - class_list_path_len,
+                     "%slib", os::file_separator());
+        class_list_path_len += 4;
       }
     }
-    strcat(class_list_path_str, os::file_separator());
-    strcat(class_list_path_str, "classlist");
+    jio_snprintf(class_list_path_str + class_list_path_len,
+                 sizeof(class_list_path_str) - class_list_path_len,
+                 "%sclasslist", os::file_separator());
     class_list_path = class_list_path_str;
   } else {
     class_list_path = SharedClassListFile;
--- a/src/share/vm/oops/constantPool.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/oops/constantPool.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -504,7 +504,7 @@
 }
 
 
-Symbol* ConstantPool::klass_name_at(int which) {
+Symbol* ConstantPool::klass_name_at(int which) const {
   assert(tag_at(which).is_unresolved_klass() || tag_at(which).is_klass(),
          "Corrupted constant pool");
   // A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.
--- a/src/share/vm/oops/constantPool.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/oops/constantPool.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -128,7 +128,7 @@
  private:
   intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(ConstantPool)); }
 
-  CPSlot slot_at(int which) {
+  CPSlot slot_at(int which) const {
     assert(is_within_bounds(which), "index out of bounds");
     // Uses volatile because the klass slot changes without a lock.
     volatile intptr_t adr = (intptr_t)OrderAccess::load_ptr_acquire(obj_at_addr_raw(which));
@@ -356,7 +356,7 @@
     return klass_at_impl(h_this, which, THREAD);
   }
 
-  Symbol* klass_name_at(int which);  // Returns the name, w/o resolving.
+  Symbol* klass_name_at(int which) const;  // Returns the name, w/o resolving.
 
   Klass* resolved_klass_at(int which) const {  // Used by Compiler
     guarantee(tag_at(which).is_klass(), "Corrupted constant pool");
--- a/src/share/vm/oops/oop.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/oops/oop.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -111,7 +111,7 @@
   jchar* chars = java_lang_String::as_unicode_string(this, length, THREAD);
   if (chars != NULL) {
     // Use alternate hashing algorithm on the string
-    return AltHashing::murmur3_32(seed, chars, length);
+    return AltHashing::halfsiphash_32(seed, chars, length);
   } else {
     vm_exit_out_of_memory(length, OOM_MALLOC_ERROR, "unable to create Unicode strings for String table rehash");
     return 0;
--- a/src/share/vm/oops/symbol.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/oops/symbol.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -210,7 +210,7 @@
 unsigned int Symbol::new_hash(juint seed) {
   ResourceMark rm;
   // Use alternate hashing algorithm on this symbol.
-  return AltHashing::murmur3_32(seed, (const jbyte*)as_C_string(), utf8_length());
+  return AltHashing::halfsiphash_32(seed, (const uint8_t*)as_C_string(), utf8_length());
 }
 
 void Symbol::increment_refcount() {
--- a/src/share/vm/opto/addnode.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/opto/addnode.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -844,6 +844,14 @@
   return TypeInt::make( MAX2(r0->_lo,r1->_lo), MAX2(r0->_hi,r1->_hi), MAX2(r0->_widen,r1->_widen) );
 }
 
+// Check if addition of an integer with type 't' and a constant 'c' can overflow
+static bool can_overflow(const TypeInt* t, jint c) {
+  jint t_lo = t->_lo;
+  jint t_hi = t->_hi;
+  return ((c < 0 && (java_add(t_lo, c) > t_lo)) ||
+          (c > 0 && (java_add(t_hi, c) < t_hi)));
+}
+
 //=============================================================================
 //------------------------------Idealize---------------------------------------
 // MINs show up in range-check loop limit calculations.  Look for
@@ -866,7 +874,7 @@
 
   // Get left input & constant
   Node *x = l;
-  int x_off = 0;
+  jint x_off = 0;
   if( x->Opcode() == Op_AddI && // Check for "x+c0" and collect constant
       x->in(2)->is_Con() ) {
     const Type *t = x->in(2)->bottom_type();
@@ -877,7 +885,7 @@
 
   // Scan a right-spline-tree for MINs
   Node *y = r;
-  int y_off = 0;
+  jint y_off = 0;
   // Check final part of MIN tree
   if( y->Opcode() == Op_AddI && // Check for "y+c1" and collect constant
       y->in(2)->is_Con() ) {
@@ -891,6 +899,7 @@
     return this;
   }
 
+  const TypeInt* tx = phase->type(x)->isa_int();
 
   if( r->Opcode() == Op_MinI ) {
     assert( r != r->in(2), "dead loop in MinINode::Ideal" );
@@ -907,18 +916,23 @@
     if( x->_idx > y->_idx )
       return new (phase->C) MinINode(r->in(1),phase->transform(new (phase->C) MinINode(l,r->in(2))));
 
-    // See if covers: MIN2(x+c0,MIN2(y+c1,z))
-    if( !phase->eqv(x,y) ) return NULL;
-    // If (y == x) transform MIN2(x+c0, MIN2(x+c1,z)) into
-    // MIN2(x+c0 or x+c1 which less, z).
-    return new (phase->C) MinINode(phase->transform(new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2));
+    // Transform MIN2(x + c0, MIN2(x + c1, z)) into MIN2(x + MIN2(c0, c1), z)
+    // if x == y and the additions can't overflow.
+    if (phase->eqv(x,y) &&
+        !can_overflow(tx, x_off) &&
+        !can_overflow(tx, y_off)) {
+      return new (phase->C) MinINode(phase->transform(new (phase->C) AddINode(x, phase->intcon(MIN2(x_off, y_off)))), r->in(2));
+    }
   } else {
-    // See if covers: MIN2(x+c0,y+c1)
-    if( !phase->eqv(x,y) ) return NULL;
-    // If (y == x) transform MIN2(x+c0,x+c1) into x+c0 or x+c1 which less.
-    return new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off)));
+    // Transform MIN2(x + c0, y + c1) into x + MIN2(c0, c1)
+    // if x == y and the additions can't overflow.
+    if (phase->eqv(x,y) &&
+        !can_overflow(tx, x_off) &&
+        !can_overflow(tx, y_off)) {
+      return new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off)));
+    }
   }
-
+  return NULL;
 }
 
 //------------------------------add_ring---------------------------------------
--- a/src/share/vm/opto/compile.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/opto/compile.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -1164,6 +1164,9 @@
   _expensive_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
   _range_check_casts = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
   register_library_intrinsics();
+#ifdef ASSERT
+  _type_verify_symmetry = true;
+#endif
 }
 
 //---------------------------init_start----------------------------------------
--- a/src/share/vm/opto/compile.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/opto/compile.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -1224,6 +1224,9 @@
 
   // Auxiliary method for randomized fuzzing/stressing
   static bool randomized_select(int count);
+#ifdef ASSERT
+  bool _type_verify_symmetry;
+#endif
 };
 
 #endif // SHARE_VM_OPTO_COMPILE_HPP
--- a/src/share/vm/opto/loopTransform.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/opto/loopTransform.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -1530,65 +1530,78 @@
 }
 
 //------------------------------adjust_limit-----------------------------------
-// Helper function for add_constraint().
-Node* PhaseIdealLoop::adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl, bool round_up) {
-  // Compute "I :: (limit-offset)/scale"
-  Node *con = new (C) SubINode(rc_limit, offset);
-  register_new_node(con, pre_ctrl);
-  Node *X = new (C) DivINode(0, con, scale);
-  register_new_node(X, pre_ctrl);
+// Helper function that computes new loop limit as (rc_limit-offset)/scale
+Node* PhaseIdealLoop::adjust_limit(bool is_positive_stride, Node* scale, Node* offset, Node* rc_limit, Node* old_limit, Node* pre_ctrl, bool round) {
+  Node* sub = new (C) SubLNode(rc_limit, offset);
+  register_new_node(sub, pre_ctrl);
+  Node* limit = new (C) DivLNode(NULL, sub, scale);
+  register_new_node(limit, pre_ctrl);
 
-  // When the absolute value of scale is greater than one, the integer
-  // division may round limit down so add one to the limit.
-  if (round_up) {
-    X = new (C) AddINode(X, _igvn.intcon(1));
-    register_new_node(X, pre_ctrl);
+  // When the absolute value of scale is greater than one, the division
+  // may round limit down/up, so add/sub one to/from the limit.
+  if (round) {
+    limit = new (C) AddLNode(limit, _igvn.longcon(is_positive_stride ? -1 : 1));
+    register_new_node(limit, pre_ctrl);
   }
 
-  // Adjust loop limit
-  loop_limit = (stride_con > 0)
-               ? (Node*)(new (C) MinINode(loop_limit, X))
-               : (Node*)(new (C) MaxINode(loop_limit, X));
-  register_new_node(loop_limit, pre_ctrl);
-  return loop_limit;
+  // Clamp the limit to handle integer under-/overflows.
+  // When reducing the limit, clamp to [min_jint, old_limit]:
+  //   MIN(old_limit, MAX(limit, min_jint))
+  // When increasing the limit, clamp to [old_limit, max_jint]:
+  //   MAX(old_limit, MIN(limit, max_jint))
+  Node* cmp = new (C) CmpLNode(limit, _igvn.longcon(is_positive_stride ? min_jint : max_jint));
+  register_new_node(cmp, pre_ctrl);
+  Node* bol = new (C) BoolNode(cmp, is_positive_stride ? BoolTest::lt : BoolTest::gt);
+  register_new_node(bol, pre_ctrl);
+  limit = new (C) ConvL2INode(limit);
+  register_new_node(limit, pre_ctrl);
+  limit = new (C) CMoveINode(bol, limit, _igvn.intcon(is_positive_stride ? min_jint : max_jint), TypeInt::INT);
+  register_new_node(limit, pre_ctrl);
+
+  limit = is_positive_stride ? (Node*)(new (C) MinINode(old_limit, limit))
+                             : (Node*)(new (C) MaxINode(old_limit, limit));
+  register_new_node(limit, pre_ctrl);
+  return limit;
 }
 
 //------------------------------add_constraint---------------------------------
 // Constrain the main loop iterations so the conditions:
-//    low_limit <= scale_con * I + offset  <  upper_limit
-// always holds true.  That is, either increase the number of iterations in
-// the pre-loop or the post-loop until the condition holds true in the main
-// loop.  Stride, scale, offset and limit are all loop invariant.  Further,
-// stride and scale are constants (offset and limit often are).
-void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset, Node *low_limit, Node *upper_limit, Node *pre_ctrl, Node **pre_limit, Node **main_limit ) {
-  // For positive stride, the pre-loop limit always uses a MAX function
-  // and the main loop a MIN function.  For negative stride these are
-  // reversed.
+//    low_limit <= scale_con*I + offset < upper_limit
+// always hold true. That is, either increase the number of iterations in the
+// pre-loop or reduce the number of iterations in the main-loop until the condition
+// holds true in the main-loop. Stride, scale, offset and limit are all loop
+// invariant. Further, stride and scale are constants (offset and limit often are).
+void PhaseIdealLoop::add_constraint(jlong stride_con, jlong scale_con, Node* offset, Node* low_limit, Node* upper_limit, Node* pre_ctrl, Node** pre_limit, Node** main_limit) {
+  assert(_igvn.type(offset)->isa_long() != NULL && _igvn.type(low_limit)->isa_long() != NULL &&
+         _igvn.type(upper_limit)->isa_long() != NULL, "arguments should be long values");
 
-  // Also for positive stride*scale the affine function is increasing, so the
-  // pre-loop must check for underflow and the post-loop for overflow.
-  // Negative stride*scale reverses this; pre-loop checks for overflow and
-  // post-loop for underflow.
+  // For a positive stride, we need to reduce the main-loop limit and
+  // increase the pre-loop limit. This is reversed for a negative stride.
+  bool is_positive_stride = (stride_con > 0);
 
-  Node *scale = _igvn.intcon(scale_con);
+  // If the absolute scale value is greater one, division in 'adjust_limit' may require
+  // rounding. Make sure the ABS method correctly handles min_jint.
+  // Only do this for the pre-loop, one less iteration of the main loop doesn't hurt.
+  bool round = ABS(scale_con) > 1;
+
+  Node* scale = _igvn.longcon(scale_con);
   set_ctrl(scale, C->root());
 
   if ((stride_con^scale_con) >= 0) { // Use XOR to avoid overflow
+    // Positive stride*scale: the affine function is increasing,
+    // the pre-loop checks for underflow and the post-loop for overflow.
+
     // The overflow limit: scale*I+offset < upper_limit
-    // For main-loop compute
+    // For the main-loop limit compute:
     //   ( if (scale > 0) /* and stride > 0 */
     //       I < (upper_limit-offset)/scale
     //     else /* scale < 0 and stride < 0 */
     //       I > (upper_limit-offset)/scale
     //   )
-    //
-    // (upper_limit-offset) may overflow or underflow.
-    // But it is fine since main loop will either have
-    // less iterations or will be skipped in such case.
-    *main_limit = adjust_limit(stride_con, scale, offset, upper_limit, *main_limit, pre_ctrl, false);
+    *main_limit = adjust_limit(is_positive_stride, scale, offset, upper_limit, *main_limit, pre_ctrl, false);
 
-    // The underflow limit: low_limit <= scale*I+offset.
-    // For pre-loop compute
+    // The underflow limit: low_limit <= scale*I+offset
+    // For the pre-loop limit compute:
     //   NOT(scale*I+offset >= low_limit)
     //   scale*I+offset < low_limit
     //   ( if (scale > 0) /* and stride > 0 */
@@ -1596,40 +1609,13 @@
     //     else /* scale < 0 and stride < 0 */
     //       I > (low_limit-offset)/scale
     //   )
+    *pre_limit = adjust_limit(!is_positive_stride, scale, offset, low_limit, *pre_limit, pre_ctrl, round);
+  } else {
+    // Negative stride*scale: the affine function is decreasing,
+    // the pre-loop checks for overflow and the post-loop for underflow.
 
-    if (low_limit->get_int() == -max_jint) {
-      if (!RangeLimitCheck) return;
-      // We need this guard when scale*pre_limit+offset >= limit
-      // due to underflow. So we need execute pre-loop until
-      // scale*I+offset >= min_int. But (min_int-offset) will
-      // underflow when offset > 0 and X will be > original_limit
-      // when stride > 0. To avoid it we replace positive offset with 0.
-      //
-      // Also (min_int+1 == -max_int) is used instead of min_int here
-      // to avoid problem with scale == -1 (min_int/(-1) == min_int).
-      Node* shift = _igvn.intcon(31);
-      set_ctrl(shift, C->root());
-      Node* sign = new (C) RShiftINode(offset, shift);
-      register_new_node(sign, pre_ctrl);
-      offset = new (C) AndINode(offset, sign);
-      register_new_node(offset, pre_ctrl);
-    } else {
-      assert(low_limit->get_int() == 0, "wrong low limit for range check");
-      // The only problem we have here when offset == min_int
-      // since (0-min_int) == min_int. It may be fine for stride > 0
-      // but for stride < 0 X will be < original_limit. To avoid it
-      // max(pre_limit, original_limit) is used in do_range_check().
-    }
-    // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond);
-    *pre_limit = adjust_limit((-stride_con), scale, offset, low_limit, *pre_limit, pre_ctrl,
-                              scale_con > 1 && stride_con > 0);
-
-  } else { // stride_con*scale_con < 0
-    // For negative stride*scale pre-loop checks for overflow and
-    // post-loop for underflow.
-    //
     // The overflow limit: scale*I+offset < upper_limit
-    // For pre-loop compute
+    // For the pre-loop limit compute:
     //   NOT(scale*I+offset < upper_limit)
     //   scale*I+offset >= upper_limit
     //   scale*I+offset+1 > upper_limit
@@ -1638,58 +1624,24 @@
     //     else /* scale > 0 and stride < 0 */
     //       I > (upper_limit-(offset+1))/scale
     //   )
-    //
-    // (upper_limit-offset-1) may underflow or overflow.
-    // To avoid it min(pre_limit, original_limit) is used
-    // in do_range_check() for stride > 0 and max() for < 0.
-    Node *one  = _igvn.intcon(1);
+    Node* one = _igvn.longcon(1);
     set_ctrl(one, C->root());
-
-    Node *plus_one = new (C) AddINode(offset, one);
+    Node* plus_one = new (C) AddLNode(offset, one);
     register_new_node( plus_one, pre_ctrl );
-    // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond);
-    *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl,
-                              scale_con < -1 && stride_con > 0);
+    *pre_limit = adjust_limit(!is_positive_stride, scale, plus_one, upper_limit, *pre_limit, pre_ctrl, round);
 
-    if (low_limit->get_int() == -max_jint) {
-      if (!RangeLimitCheck) return;
-      // We need this guard when scale*main_limit+offset >= limit
-      // due to underflow. So we need execute main-loop while
-      // scale*I+offset+1 > min_int. But (min_int-offset-1) will
-      // underflow when (offset+1) > 0 and X will be < main_limit
-      // when scale < 0 (and stride > 0). To avoid it we replace
-      // positive (offset+1) with 0.
-      //
-      // Also (min_int+1 == -max_int) is used instead of min_int here
-      // to avoid problem with scale == -1 (min_int/(-1) == min_int).
-      Node* shift = _igvn.intcon(31);
-      set_ctrl(shift, C->root());
-      Node* sign = new (C) RShiftINode(plus_one, shift);
-      register_new_node(sign, pre_ctrl);
-      plus_one = new (C) AndINode(plus_one, sign);
-      register_new_node(plus_one, pre_ctrl);
-    } else {
-      assert(low_limit->get_int() == 0, "wrong low limit for range check");
-      // The only problem we have here when offset == max_int
-      // since (max_int+1) == min_int and (0-min_int) == min_int.
-      // But it is fine since main loop will either have
-      // less iterations or will be skipped in such case.
-    }
-    // The underflow limit: low_limit <= scale*I+offset.
-    // For main-loop compute
+    // The underflow limit: low_limit <= scale*I+offset
+    // For the main-loop limit compute:
     //   scale*I+offset+1 > low_limit
     //   ( if (scale < 0) /* and stride > 0 */
     //       I < (low_limit-(offset+1))/scale
     //     else /* scale > 0 and stride < 0 */
     //       I > (low_limit-(offset+1))/scale
     //   )
-
-    *main_limit = adjust_limit(stride_con, scale, plus_one, low_limit, *main_limit, pre_ctrl,
-                               false);
+    *main_limit = adjust_limit(is_positive_stride, scale, plus_one, low_limit, *main_limit, pre_ctrl, false);
   }
 }
 
-
 //------------------------------is_scaled_iv---------------------------------
 // Return true if exp is a constant times an induction var
 bool PhaseIdealLoop::is_scaled_iv(Node* exp, Node* iv, int* p_scale) {
@@ -1854,22 +1806,14 @@
   // Must know if its a count-up or count-down loop
 
   int stride_con = cl->stride_con();
-  Node *zero = _igvn.intcon(0);
-  Node *one  = _igvn.intcon(1);
+  Node* zero = _igvn.longcon(0);
+  Node* one  = _igvn.longcon(1);
   // Use symmetrical int range [-max_jint,max_jint]
-  Node *mini = _igvn.intcon(-max_jint);
+  Node* mini = _igvn.longcon(-max_jint);
   set_ctrl(zero, C->root());
   set_ctrl(one,  C->root());
   set_ctrl(mini, C->root());
 
-  // Range checks that do not dominate the loop backedge (ie.
-  // conditionally executed) can lengthen the pre loop limit beyond
-  // the original loop limit. To prevent this, the pre limit is
-  // (for stride > 0) MINed with the original loop limit (MAXed
-  // stride < 0) when some range_check (rc) is conditionally
-  // executed.
-  bool conditional_rc = false;
-
   // Check loop body for tests of trip-counter plus loop-invariant vs
   // loop-invariant.
   for( uint i = 0; i < loop->_body.size(); i++ ) {
@@ -1948,15 +1892,20 @@
       // stride_con and scale_con can be negative which will flip about the
       // sense of the test.
 
+      // Perform the limit computations in jlong to avoid overflow
+      jlong lscale_con = scale_con;
+      Node* int_offset = offset;
+      offset = new (C) ConvI2LNode(offset);
+      register_new_node(offset, pre_ctrl);
+      Node* int_limit = limit;
+      limit = new (C) ConvI2LNode(limit);
+      register_new_node(limit, pre_ctrl);
+
       // Adjust pre and main loop limits to guard the correct iteration set
       if( cmp->Opcode() == Op_CmpU ) {// Unsigned compare is really 2 tests
         if( b_test._test == BoolTest::lt ) { // Range checks always use lt
           // The underflow and overflow limits: 0 <= scale*I+offset < limit
-          add_constraint( stride_con, scale_con, offset, zero, limit, pre_ctrl, &pre_limit, &main_limit );
-          if (!conditional_rc) {
-            // (0-offset)/scale could be outside of loop iterations range.
-            conditional_rc = !loop->dominates_backedge(iff) || RangeLimitCheck;
-          }
+          add_constraint(stride_con, lscale_con, offset, zero, limit, pre_ctrl, &pre_limit, &main_limit);
         } else {
 #ifndef PRODUCT
           if( PrintOpto )
@@ -1970,16 +1919,16 @@
           // Fall into GE case
         case BoolTest::ge:
           // Convert (I*scale+offset) >= Limit to (I*(-scale)+(-offset)) <= -Limit
-          scale_con = -scale_con;
-          offset = new (C) SubINode( zero, offset );
+          lscale_con = -lscale_con;
+          offset = new (C) SubLNode(zero, offset);
           register_new_node( offset, pre_ctrl );
-          limit  = new (C) SubINode( zero, limit  );
+          limit  = new (C) SubLNode(zero, limit);
           register_new_node( limit, pre_ctrl );
           // Fall into LE case
         case BoolTest::le:
           if (b_test._test != BoolTest::gt) {
             // Convert X <= Y to X < Y+1
-            limit = new (C) AddINode( limit, one );
+            limit = new (C) AddLNode(limit, one);
             register_new_node( limit, pre_ctrl );
           }
           // Fall into LT case
@@ -1987,13 +1936,7 @@
           // The underflow and overflow limits: MIN_INT <= scale*I+offset < limit
           // Note: (MIN_INT+1 == -MAX_INT) is used instead of MIN_INT here
           // to avoid problem with scale == -1: MIN_INT/(-1) == MIN_INT.
-          add_constraint( stride_con, scale_con, offset, mini, limit, pre_ctrl, &pre_limit, &main_limit );
-          if (!conditional_rc) {
-            // ((MIN_INT+1)-offset)/scale could be outside of loop iterations range.
-            // Note: negative offset is replaced with 0 but (MIN_INT+1)/scale could
-            // still be outside of loop range.
-            conditional_rc = !loop->dominates_backedge(iff) || RangeLimitCheck;
-          }
+          add_constraint(stride_con, lscale_con, offset, mini, limit, pre_ctrl, &pre_limit, &main_limit);
           break;
         default:
 #ifndef PRODUCT
@@ -2029,7 +1972,8 @@
   }
 
   // Update loop limits
-  if (conditional_rc) {
+  if (pre_limit != orig_limit) {
+    // Computed pre-loop limit can be outside of loop iterations range.
     pre_limit = (stride_con > 0) ? (Node*)new (C) MinINode(pre_limit, orig_limit)
                                  : (Node*)new (C) MaxINode(pre_limit, orig_limit);
     register_new_node(pre_limit, pre_ctrl);
--- a/src/share/vm/opto/loopnode.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/opto/loopnode.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -961,9 +961,9 @@
   // always holds true.  That is, either increase the number of iterations in
   // the pre-loop or the post-loop until the condition holds true in the main
   // loop.  Scale_con, offset and limit are all loop invariant.
-  void add_constraint( int stride_con, int scale_con, Node *offset, Node *low_limit, Node *upper_limit, Node *pre_ctrl, Node **pre_limit, Node **main_limit );
+  void add_constraint(jlong stride_con, jlong scale_con, Node* offset, Node* low_limit, Node* upper_limit, Node* pre_ctrl, Node** pre_limit, Node** main_limit);
   // Helper function for add_constraint().
-  Node* adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl, bool round_up);
+  Node* adjust_limit(bool reduce, Node* scale, Node* offset, Node* rc_limit, Node* old_limit, Node* pre_ctrl, bool round);
 
   // Partially peel loop up through last_peel node.
   bool partial_peel( IdealLoopTree *loop, Node_List &old_new );
--- a/src/share/vm/opto/output.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/opto/output.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -1672,6 +1672,8 @@
       }
       if (method() != NULL) {
         method()->print_metadata();
+      } else if (stub_name() != NULL) {
+        tty->print_cr("Generating RuntimeStub - %s", stub_name());
       }
       dump_asm(node_offsets, node_offset_limit);
       if (xtty != NULL) {
--- a/src/share/vm/opto/type.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/opto/type.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -668,6 +668,35 @@
 
 #endif
 
+void Type::check_symmetrical(const Type *t, const Type *mt) const {
+#ifdef ASSERT
+  assert(mt == t->xmeet(this), "meet not commutative");
+  const Type* dual_join = mt->_dual;
+  const Type *t2t    = dual_join->xmeet(t->_dual);
+  const Type *t2this = dual_join->xmeet(this->_dual);
+
+  // Interface meet Oop is Not Symmetric:
+  // Interface:AnyNull meet Oop:AnyNull == Interface:AnyNull
+  // Interface:NotNull meet Oop:NotNull == java/lang/Object:NotNull
+
+  if( !interface_vs_oop(t) && (t2t != t->_dual || t2this != this->_dual) ) {
+    tty->print_cr("=== Meet Not Symmetric ===");
+    tty->print("t   =                   ");              t->dump(); tty->cr();
+    tty->print("this=                   ");                 dump(); tty->cr();
+    tty->print("mt=(t meet this)=       ");             mt->dump(); tty->cr();
+
+    tty->print("t_dual=                 ");       t->_dual->dump(); tty->cr();
+    tty->print("this_dual=              ");          _dual->dump(); tty->cr();
+    tty->print("mt_dual=                ");      mt->_dual->dump(); tty->cr();
+
+    tty->print("mt_dual meet t_dual=    "); t2t           ->dump(); tty->cr();
+    tty->print("mt_dual meet this_dual= "); t2this        ->dump(); tty->cr();
+
+    fatal("meet not symmetric" );
+  }
+#endif
+}
+
 //------------------------------meet-------------------------------------------
 // Compute the MEET of two types.  NOT virtual.  It enforces that meet is
 // commutative and the lattice is symmetric.
@@ -685,33 +714,28 @@
   t = t->maybe_remove_speculative(include_speculative);
 
   const Type *mt = this_t->xmeet(t);
+#ifdef ASSERT
   if (isa_narrowoop() || t->isa_narrowoop()) return mt;
   if (isa_narrowklass() || t->isa_narrowklass()) return mt;
-#ifdef ASSERT
-  assert(mt == t->xmeet(this_t), "meet not commutative");
-  const Type* dual_join = mt->_dual;
-  const Type *t2t    = dual_join->xmeet(t->_dual);
-  const Type *t2this = dual_join->xmeet(this_t->_dual);
-
-  // Interface meet Oop is Not Symmetric:
-  // Interface:AnyNull meet Oop:AnyNull == Interface:AnyNull
-  // Interface:NotNull meet Oop:NotNull == java/lang/Object:NotNull
-
-  if( !interface_vs_oop(t) && (t2t != t->_dual || t2this != this_t->_dual) ) {
-    tty->print_cr("=== Meet Not Symmetric ===");
-    tty->print("t   =                   ");              t->dump(); tty->cr();
-    tty->print("this=                   ");         this_t->dump(); tty->cr();
-    tty->print("mt=(t meet this)=       ");             mt->dump(); tty->cr();
-
-    tty->print("t_dual=                 ");       t->_dual->dump(); tty->cr();
-    tty->print("this_dual=              ");  this_t->_dual->dump(); tty->cr();
-    tty->print("mt_dual=                ");      mt->_dual->dump(); tty->cr();
-
-    tty->print("mt_dual meet t_dual=    "); t2t           ->dump(); tty->cr();
-    tty->print("mt_dual meet this_dual= "); t2this        ->dump(); tty->cr();
-
-    fatal("meet not symmetric" );
+  Compile* C = Compile::current();
+  if (!C->_type_verify_symmetry) {
+    return mt;
   }
+  this_t->check_symmetrical(t, mt);
+  // In the case of an array, computing the meet above, caused the
+  // computation of the meet of the elements which at verification
+  // time caused the computation of the meet of the dual of the
+  // elements. Computing the meet of the dual of the arrays here
+  // causes the meet of the dual of the elements to be computed which
+  // would cause the meet of the dual of the dual of the elements,
+  // that is the meet of the elements already computed above to be
+  // computed. Avoid redundant computations by requesting no
+  // verification.
+  C->_type_verify_symmetry = false;
+  const Type *mt_dual = this_t->_dual->xmeet(t->_dual);
+  this_t->_dual->check_symmetrical(t->_dual, mt_dual);
+  assert(!C->_type_verify_symmetry, "shouldn't have changed");
+  C->_type_verify_symmetry = true;
 #endif
   return mt;
 }
@@ -3966,10 +3990,10 @@
            (tap->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) ||
            // 'this' is exact and super or unrelated:
            (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) {
-      if (above_centerline(ptr)) {
+      if (above_centerline(ptr) || (tary->_elem->make_ptr() && above_centerline(tary->_elem->make_ptr()->_ptr))) {
         tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable);
       }
-      return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot);
+      return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot, speculative, depth);
     }
 
     bool xk = false;
--- a/src/share/vm/opto/type.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/opto/type.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -165,6 +165,7 @@
 #endif
 
   const Type *meet_helper(const Type *t, bool include_speculative) const;
+  void check_symmetrical(const Type *t, const Type *mt) const;
 
 protected:
   // Each class of type is also identified by its base.
--- a/src/share/vm/prims/jniCheck.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/prims/jniCheck.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -431,21 +431,20 @@
   size_t sz;
   void* orig_result = check_wrapped_array(thr, fn_name, obj, carray, &sz);
   switch (mode) {
+  // As we never make copies, mode 0 and JNI_COMMIT are the same.
   case 0:
-    memcpy(orig_result, carray, sz);
-    GuardedMemory::free_copy(carray);
-    break;
   case JNI_COMMIT:
     memcpy(orig_result, carray, sz);
     break;
   case JNI_ABORT:
-    GuardedMemory::free_copy(carray);
     break;
   default:
     tty->print_cr("%s: Unrecognized mode %i releasing array "
         PTR_FORMAT " elements " PTR_FORMAT, fn_name, mode, p2i(obj), p2i(carray));
     NativeReportJNIFatalError(thr, "Unrecognized array release mode");
   }
+  // We always need to release the copy we made with GuardedMemory
+  GuardedMemory::free_copy(carray);
   return orig_result;
 }
 
--- a/src/share/vm/prims/jvm.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/prims/jvm.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -525,6 +525,17 @@
 JVM_END
 
 
+JVM_ENTRY_NO_ENV(jboolean, JVM_IsUseContainerSupport(void))
+  JVMWrapper("JVM_IsUseContainerSupport");
+#ifdef TARGET_OS_FAMILY_linux
+  if (UseContainerSupport) {
+      return JNI_TRUE;
+  }
+#endif
+  return JNI_FALSE;
+JVM_END
+
+
 
 // java.lang.Throwable //////////////////////////////////////////////////////
 
--- a/src/share/vm/prims/jvm.h	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/prims/jvm.h	Tue Oct 27 06:33:36 2020 +0000
@@ -202,6 +202,9 @@
 JNIEXPORT jint JNICALL
 JVM_ActiveProcessorCount(void);
 
+JNIEXPORT jboolean JNICALL
+JVM_IsUseContainerSupport(void);
+
 JNIEXPORT void * JNICALL
 JVM_LoadLibrary(const char *name);
 
--- a/src/share/vm/prims/nativeLookup.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/prims/nativeLookup.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -61,27 +61,118 @@
 #endif
 
 
-static void mangle_name_on(outputStream* st, Symbol* name, int begin, int end) {
+/*
+
+The JNI specification defines the mapping from a Java native method name to
+a C native library implementation function name as follows:
+
+  The mapping produces a native method name by concatenating the following components
+  derived from a `native` method declaration:
+
+  1. the prefix Java_
+  2. given the binary name, in internal form, of the class which declares the native method:
+     the result of escaping the name.
+  3. an underscore ("_")
+  4. the escaped method name
+  5. if the native method declaration is overloaded: two underscores ("__") followed by the
+   escaped parameter descriptor (JVMS 4.3.3) of the method declaration.
+
+  Escaping leaves every alphanumeric ASCII character (A-Za-z0-9) unchanged, and replaces each
+  UTF-16 code unit n the table below with the corresponding escape sequence. If the name to be
+  escaped contains a surrogate pair, then the high-surrogate code unit and the low-surrogate code
+  unit are escaped separately. The result of escaping is a string consisting only of the ASCII
+  characters A-Za-z0-9 and underscore.
+
+  ------------------------------                  ------------------------------------
+  UTF-16 code unit                                Escape sequence
+  ------------------------------                  ------------------------------------
+  Forward slash (/, U+002F)                       _
+  Underscore (_, U+005F)                          _1
+  Semicolon (;, U+003B)                           _2
+  Left square bracket ([, U+005B)                 _3
+  Any UTF-16 code unit \u_WXYZ_ that does not     _0wxyz where w, x, y, and z are the lower-case
+  represent alphanumeric ASCII (A-Za-z0-9),       forms of the hexadecimal digits W, X, Y, and Z.
+  forward slash, underscore, semicolon,           (For example, U+ABCD becomes _0abcd.)
+  or left square bracket
+  ------------------------------                  ------------------------------------
+
+  Note that escape sequences can safely begin _0, _1, etc, because class and method
+  names in Java source code never begin with a number. However, that is not the case in
+  class files that were not generated from Java source code.
+
+  To preserve the 1:1 mapping to a native method name, the VM checks the resulting name as
+  follows. If the process of escaping any precursor string from the native  method declaration
+  (class or method name, or argument type) causes a "0", "1", "2", or "3" character
+  from the precursor string to appear unchanged in the result *either* immediately after an
+  underscore *or* at the beginning of the escaped string (where it will follow an underscore
+  in the fully assembled name), then the escaping process is said to have "failed".
+  In such cases, no native library search is performed, and the attempt to link the native
+  method invocation will throw UnsatisfiedLinkError.
+
+
+For example:
+
+  package/my_class/method
+
+and
+
+  package/my/1class/method
+
+both map to
+
+  Java_package_my_1class_method
+
+To address this potential conflict we need only check if the character after
+/ is a digit 0..3, or if the first character after an injected '_' seperator
+is a digit 0..3. If we encounter an invalid identifier we reset the
+stringStream and return false. Otherwise the stringStream contains the mapped
+name and we return true.
+
+To address legacy compatibility, the UseLegacyJNINameEscaping flag can be set
+which skips the extra checks.
+
+*/
+static bool map_escaped_name_on(stringStream* st, Symbol* name, int begin, int end) {
   char* bytes = (char*)name->bytes() + begin;
   char* end_bytes = (char*)name->bytes() + end;
+  bool check_escape_char = true; // initially true as first character here follows '_'
   while (bytes < end_bytes) {
     jchar c;
     bytes = UTF8::next(bytes, &c);
     if (c <= 0x7f && isalnum(c)) {
+      if (check_escape_char && (c >= '0' && c <= '3') &&
+          !UseLegacyJNINameEscaping) {
+        // This is a non-Java identifier and we won't escape it to
+        // ensure no name collisions with a Java identifier.
+        if (PrintJNIResolving) {
+          ResourceMark rm;
+          tty->print_cr("[Lookup of native method with non-Java identifier rejected: %s]",
+                                  name->as_C_string());
+        }
+        st->reset();  // restore to "" on error
+        return false;
+      }
       st->put((char) c);
+      check_escape_char = false;
     } else {
-           if (c == '_') st->print("_1");
-      else if (c == '/') st->print("_");
+      check_escape_char = false;
+      if (c == '_') st->print("_1");
+      else if (c == '/') {
+        st->print("_");
+        // Following a / we must have non-escape character
+        check_escape_char = true;
+      }
       else if (c == ';') st->print("_2");
       else if (c == '[') st->print("_3");
       else               st->print("_%.5x", c);
     }
   }
+  return true;
 }
 
 
-static void mangle_name_on(outputStream* st, Symbol* name) {
-  mangle_name_on(st, name, 0, name->utf8_length());
+static bool map_escaped_name_on(stringStream* st, Symbol* name) {
+  return map_escaped_name_on(st, name, 0, name->utf8_length());
 }
 
 
@@ -90,10 +181,14 @@
   // Prefix
   st.print("Java_");
   // Klass name
-  mangle_name_on(&st, method->klass_name());
+  if (!map_escaped_name_on(&st, method->klass_name())) {
+    return NULL;
+  }
   st.print("_");
   // Method name
-  mangle_name_on(&st, method->name());
+  if (!map_escaped_name_on(&st, method->name())) {
+    return NULL;
+  }
   return st.as_string();
 }
 
@@ -103,16 +198,20 @@
   // Prefix
   st.print("JavaCritical_");
   // Klass name
-  mangle_name_on(&st, method->klass_name());
+  if (!map_escaped_name_on(&st, method->klass_name())) {
+    return NULL;
+  }
   st.print("_");
   // Method name
-  mangle_name_on(&st, method->name());
+  if (!map_escaped_name_on(&st, method->name())) {
+    return NULL;
+  }
   return st.as_string();
 }
 
 
 char* NativeLookup::long_jni_name(methodHandle method) {
-  // Signature ignore the wrapping parenteses and the trailing return type
+  // Signatures ignore the wrapping parentheses and the trailing return type
   stringStream st;
   Symbol* signature = method->signature();
   st.print("__");
@@ -120,7 +219,10 @@
   int end;
   for (end = 0; end < signature->utf8_length() && signature->byte_at(end) != ')'; end++);
   // skip first '('
-  mangle_name_on(&st, signature, 1, end);
+  if (!map_escaped_name_on(&st, signature, 1, end)) {
+    return NULL;
+  }
+
   return st.as_string();
 }
 
@@ -247,6 +349,11 @@
   in_base_library = false;
   // Compute pure name
   char* pure_name = pure_jni_name(method);
+  if (pure_name == NULL) {
+    // JNI name mapping rejected this method so return
+    // NULL to indicate UnsatisfiedLinkError should be thrown.
+    return NULL;
+  }
 
   // Compute argument size
   int args_size = 1                             // JNIEnv
@@ -260,6 +367,11 @@
 
   // Compute long name
   char* long_name = long_jni_name(method);
+  if (long_name == NULL) {
+    // JNI name mapping rejected this method so return
+    // NULL to indicate UnsatisfiedLinkError should be thrown.
+    return NULL;
+  }
 
   // 2) Try JNI long style
   entry = lookup_style(method, pure_name, long_name, args_size, true,  in_base_library, CHECK_NULL);
@@ -299,6 +411,11 @@
 
   // Compute critical name
   char* critical_name = critical_jni_name(method);
+  if (critical_name == NULL) {
+    // JNI name mapping rejected this method so return
+    // NULL to indicate UnsatisfiedLinkError should be thrown.
+    return NULL;
+  }
 
   // Compute argument size
   int args_size = 1                             // JNIEnv
@@ -312,6 +429,11 @@
 
   // Compute long name
   char* long_name = long_jni_name(method);
+  if (long_name == NULL) {
+    // JNI name mapping rejected this method so return
+    // NULL to indicate UnsatisfiedLinkError should be thrown.
+    return NULL;
+  }
 
   // 2) Try JNI long style
   entry = lookup_critical_style(method, critical_name, long_name, args_size, true);
--- a/src/share/vm/runtime/globals.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/runtime/globals.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -718,6 +718,9 @@
   product(bool, CriticalJNINatives, true,                                   \
           "Check for critical JNI entry points")                            \
                                                                             \
+  product(bool, UseLegacyJNINameEscaping, false,                            \
+          "Use the original JNI name escaping scheme")                      \
+                                                                            \
   notproduct(bool, StressCriticalJNINatives, false,                         \
           "Exercise register saving code in critical natives")              \
                                                                             \
@@ -1351,7 +1354,7 @@
   develop(bool, TraceClassInitialization, false,                            \
           "Trace class initialization")                                     \
                                                                             \
-  develop(bool, TraceExceptions, false,                                     \
+  product(bool, TraceExceptions, false,                                     \
           "Trace exceptions")                                               \
                                                                             \
   develop(bool, TraceICs, false,                                            \
@@ -2031,7 +2034,7 @@
   experimental(uintx, WorkStealingSpinToYieldRatio, 10,                     \
           "Ratio of hard spins to calls to yield")                          \
                                                                             \
-  develop(uintx, ObjArrayMarkingStride, 512,                                \
+  develop(uintx, ObjArrayMarkingStride, 2048,                               \
           "Number of object array elements to push onto the marking stack " \
           "before pushing a continuation entry")                            \
                                                                             \
--- a/src/share/vm/runtime/reflection.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/runtime/reflection.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -506,7 +506,7 @@
       (accessor_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION &&
        accessee_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION)) {
     return classloader_only &&
-      Verifier::relax_access_for(accessor_ik->class_loader()) &&
+      Verifier::relax_verify_for(accessor_ik->class_loader()) &&
       accessor_ik->protection_domain() == accessee_ik->protection_domain() &&
       accessor_ik->class_loader() == accessee_ik->class_loader();
   } else {
--- a/src/share/vm/runtime/thread.cpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/runtime/thread.cpp	Tue Oct 27 06:33:36 2020 +0000
@@ -3440,7 +3440,7 @@
     return status;
   }
 
-  JFR_ONLY(Jfr::on_create_vm_1();)
+  JFR_ONLY(Jfr::on_vm_init();)
 
   // Should be done after the heap is fully created
   main_thread->cache_global_variables();
@@ -3491,16 +3491,12 @@
     ShouldNotReachHere();
   }
 
-#if !INCLUDE_JFR
-  // if JFR is not enabled at the build time keep the original JvmtiExport location
-
   // Always call even when there are not JVMTI environments yet, since environments
   // may be attached late and JVMTI must track phases of VM execution
   JvmtiExport::enter_start_phase();
 
   // Notify JVMTI agents that VM has started (JNI is up) - nop if no agents.
   JvmtiExport::post_vm_start();
-#endif
 
   {
     TraceTime timer("Initialize java.lang classes", TraceStartupTime);
@@ -3547,19 +3543,6 @@
     initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK_0);
   }
 
-  JFR_ONLY(
-    Jfr::on_create_vm_2();
-
-    // if JFR is enabled at build time the JVMTI needs to be handled only after on_create_vm_2() call
-
-    // Always call even when there are not JVMTI environments yet, since environments
-    // may be attached late and JVMTI must track phases of VM execution
-    JvmtiExport::enter_start_phase();
-
-    // Notify JVMTI agents that VM has started (JNI is up) - nop if no agents.
-    JvmtiExport::post_vm_start();
-  )
-
   // See        : bugid 4211085.
   // Background : the static initializer of java.lang.Compiler tries to read
   //              property"java.compiler" and read & write property "java.vm.info".
@@ -3654,7 +3637,7 @@
   // Notify JVMTI agents that VM initialization is complete - nop if no agents.
   JvmtiExport::post_vm_initialized();
 
-  JFR_ONLY(Jfr::on_create_vm_3();)
+  JFR_ONLY(Jfr::on_vm_start();)
 
   if (CleanChunkPoolAsync) {
     Chunk::start_chunk_pool_cleaner_task();
--- a/src/share/vm/utilities/globalDefinitions.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -1066,6 +1066,7 @@
 const intptr_t badAddressVal    = -2;                       // generic "bad address" value
 const intptr_t badOopVal        = -1;                       // generic "bad oop" value
 const intptr_t badHeapOopVal    = (intptr_t) CONST64(0x2BAD4B0BBAADBABE); // value used to zap heap after GC
+const int      badStackSegVal   = 0xCA;                     // value used to zap stack segments
 const int      badHandleValue   = 0xBC;                     // value used to zap vm handle area
 const int      badResourceValue = 0xAB;                     // value used to zap resource area
 const int      freeBlockPad     = 0xBA;                     // value used to pad freed blocks.
--- a/src/share/vm/utilities/stack.inline.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/utilities/stack.inline.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -26,6 +26,7 @@
 #define SHARE_VM_UTILITIES_STACK_INLINE_HPP
 
 #include "utilities/stack.hpp"
+#include "utilities/copy.hpp"
 
 template <MEMFLAGS F> StackBase<F>::StackBase(size_t segment_size, size_t max_cache_size,
                      size_t max_size):
@@ -227,11 +228,7 @@
 {
   if (!ZapStackSegments) return;
   const size_t zap_bytes = segment_bytes() - (zap_link_field ? 0 : sizeof(E*));
-  uint32_t* cur = (uint32_t*)seg;
-  const uint32_t* end = cur + zap_bytes / sizeof(uint32_t);
-  while (cur < end) {
-    *cur++ = 0xfadfaded;
-  }
+  Copy::fill_to_bytes(seg, zap_bytes, badStackSegVal);
 }
 #endif
 
--- a/src/share/vm/utilities/taskqueue.hpp	Tue Oct 27 03:35:20 2020 +0000
+++ b/src/share/vm/utilities/taskqueue.hpp	Tue Oct 27 06:33:36 2020 +0000
@@ -332,7 +332,8 @@
     //            index, &_elems[index], _elems[index]);
     E* t = (E*)&_elems[index];      // cast away volatility
     oop* p = (oop*)t;
-    assert((*t)->is_oop_or_null(), "Not an oop or null");
+    // G1 does its own checking
+    assert(UseG1GC || (*t)->is_oop_or_null(), "Not an oop or null");
     f->do_oop(p);
   }
   // tty->print_cr("END OopTaskQueue::oops_do");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/types/TestArrayMeetNotSymmetrical.java	Tue Oct 27 06:33:36 2020 +0000
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2020, Red Hat, Inc. 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.
+ */
+
+/**
+ * @test
+ * @bug 8240676
+ * @summary Meet not symmetric failure when running lucene on jdk8
+ *
+ * @run main/othervm -XX:-BackgroundCompilation TestArrayMeetNotSymmetrical
+ *
+ */
+
+public class TestArrayMeetNotSymmetrical {
+    private static final Object field = new Object[0];
+    private static final Object field2 = new A[0];
+
+    public static void main(String[] args) {
+        Object array = new A[10];
+        for (int i = 0; i < 20_000; i++) {
+            test1(true, 10);
+            test1(false, 10);
+            test2(true);
+            test2(false);
+        }
+    }
+
+    private static Object test1(boolean flag, int len) {
+        Object o;
+        if (flag) {
+            o = field;
+        } else {
+            o = new A[len];
+        }
+        return o;
+    }
+
+    private static Object test2(boolean flag) {
+        Object o;
+        if (flag) {
+            o = field;
+        } else {
+            o = field2;
+        }
+        return o;
+    }
+
+
+    private static class A {
+    }
+}
--- a/test/runtime/8233197/T.java	Tue Oct 27 03:35:20 2020 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-public class T
-{
-  public static void main(String[] args) throws Exception
-  {
-    for (int i = 0; i < 50; i++) {
-      System.out.print("+");
-      Thread.sleep(1);
-    }
-    System.out.println();
-  }
-}
--- a/test/runtime/8233197/Test8233197.sh	Tue Oct 27 03:35:20 2020 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2013, 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.
-
-##
-## @test Test8233197.sh
-## @bug 8233197
-## @summary Check that JFR subsystem can be initialized from VMStart JVMTI event
-## @compile T.java
-## @run shell Test8233197.sh
-##
-
-set -x
-if [ "${TESTSRC}" = "" ]
-then
-  TESTSRC=${PWD}
-  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
-fi
-echo "TESTSRC=${TESTSRC}"
-## Adding common setup Variables for running shell tests.
-. ${TESTSRC}/../../test_env.sh
-
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
-  Linux)
-    gcc_cmd=`which gcc`
-    if [ "x$gcc_cmd" == "x" ]; then
-        echo "WARNING: gcc not found. Cannot execute test." 2>&1
-        exit 0;
-    fi
-    NULL=/dev/null
-    PS=":"
-    FS="/"
-    ;;
-  * )
-    echo "Test passed; only valid for Linux"
-    exit 0;
-    ;;
-esac
-
-${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xinternalversion > vm_version.out 2>&1
-
-# Bitness:
-# Cannot simply look at TESTVMOPTS as -d64 is not
-# passed if there is only a 64-bit JVM available.
-
-grep "64-Bit" vm_version.out > ${NULL}
-if [ "$?" = "0" ]
-then
-  COMP_FLAG="-m64"
-else
-  COMP_FLAG="-m32"
-fi
-
-
-# Architecture:
-# Translate uname output to JVM directory name, but permit testing
-# 32-bit x86 on an x64 platform.
-ARCH=`uname -m`
-case "$ARCH" in
-  x86_64)
-    if [ "$COMP_FLAG" = "-m32" ]; then
-      ARCH=i386
-    else
-      ARCH=amd64
-    fi
-    ;;
-  ppc64)
-    if [ "$COMP_FLAG" = "-m32" ]; then
-      ARCH=ppc
-    else
-      ARCH=ppc64
-    fi
-    ;;
-  sparc64)
-    if [ "$COMP_FLAG" = "-m32" ]; then
-      ARCH=sparc
-    else
-      ARCH=sparc64
-    fi
-    ;;
-  arm*)
-    # 32-bit ARM machine: compiler may not recognise -m32
-    COMP_FLAG=""
-    ARCH=arm
-    ;;
-  aarch64)
-    # 64-bit arm machine, could be testing 32 or 64-bit:
-    if [ "$COMP_FLAG" = "-m32" ]; then
-      ARCH=arm
-    else
-      ARCH=aarch64
-    fi
-    ;;
-  i586)
-    ARCH=i386
-    ;;
-  i686)
-    ARCH=i386
-    ;;
-  # Assuming other ARCH values need no translation
-esac
-
-
-# VM type: need to know server or client
-VMTYPE=client
-grep Server vm_version.out > ${NULL}
-if [ "$?" = "0" ]
-then
-  VMTYPE=server
-fi
-
-
-LD_LIBRARY_PATH=.:${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE}:/usr/lib:$LD_LIBRARY_PATH
-export LD_LIBRARY_PATH
-
-cp ${TESTSRC}${FS}libJvmtiAgent.c .
-
-# Copy the result of our @compile action:
-cp ${TESTCLASSES}${FS}T.class .
-
-echo "Architecture: ${ARCH}"
-echo "Compilation flag: ${COMP_FLAG}"
-echo "VM type: ${VMTYPE}"
-
-$gcc_cmd -DLINUX ${COMP_FLAG} -Wl, -g -fno-strict-aliasing -fPIC -fno-omit-frame-pointer -W -Wall  -Wno-unused -Wno-parentheses -c -o libJvmtiAgent.o \
-    -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \
-    -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \
-    libJvmtiAgent.c
-$gcc_cmd -shared -o libJvmtiAgent.so libJvmtiAgent.o
-
-"$TESTJAVA/bin/java" $TESTVMOPTS -agentlib:JvmtiAgent -cp $(pwd) T > T.out
-exit $?
\ No newline at end of file
--- a/test/runtime/8233197/libJvmtiAgent.c	Tue Oct 27 03:35:20 2020 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "jvmti.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef JNI_ENV_ARG
-
-#ifdef __cplusplus
-#define JNI_ENV_ARG(x, y) y
-#define JNI_ENV_PTR(x) x
-#else
-#define JNI_ENV_ARG(x,y) x, y
-#define JNI_ENV_PTR(x) (*x)
-#endif
-
-#endif
-
-#define TranslateError(err) "JVMTI error"
-
-static jvmtiEnv *jvmti = NULL;
-
-static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved);
-
-JNIEXPORT
-jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
-    return Agent_Initialize(jvm, options, reserved);
-}
-
-JNIEXPORT
-jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) {
-    return Agent_Initialize(jvm, options, reserved);
-}
-
-JNIEXPORT
-jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
-    return JNI_VERSION_1_8;
-}
-
-static void JNICALL
-Callback_VMStart(jvmtiEnv *jvmti_env, JNIEnv *env) {
-    printf("Localizing jdk.jfr.FlightRecorder\n");
-    // without fix for 8233197 the process will crash at the following line
-    jclass cls = (*env)->FindClass(env, "jdk/jfr/FlightRecorder");
-    jmethodID mid = (*env)->GetStaticMethodID(env, cls, "getFlightRecorder", "()Ljdk/jfr/FlightRecorder;");
-    if (mid == 0) {
-        printf("Unable to localize jdk.jfr.FlightRecorder#getFlightRecorder() method\n");
-        // crash the tested JVM to make the test fail
-        exit(-1);
-    }
-    printf("Going to initialize JFR subsystem ...\n");
-    jobject jfr = (*env)->CallStaticObjectMethod(env, cls, mid);
-
-    if (!(*env)->ExceptionCheck(env)) {
-        // crash the tested JVM to make the test fail
-        printf("JFR subsystem is wrongly initialized too early\n");
-        exit(-2);
-    }
-    // exit VM
-    exit(0);
-}
-
-static
-jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
-    jint res, size;
-    jvmtiCapabilities caps;
-    jvmtiEventCallbacks callbacks;
-    jvmtiError err;
-
-    res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti),
-        JVMTI_VERSION_1_2);
-    if (res != JNI_OK || jvmti == NULL) {
-        printf("    Error: wrong result of a valid call to GetEnv!\n");
-        return JNI_ERR;
-    }
-
-    size = (jint)sizeof(callbacks);
-
-    memset(&callbacks, 0, sizeof(callbacks));
-    callbacks.VMStart = Callback_VMStart;
-
-    err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, size);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("    Error in SetEventCallbacks: %s (%d)\n", TranslateError(err), err);
-        return JNI_ERR;
-    }
-
-    err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_START, (jthread)NULL);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("    Error in SetEventNotificationMode: %s (%d)\n", TranslateError(err), err);
-        return JNI_ERR;
-    }
-    return JNI_OK;
-}
-
-#ifdef __cplusplus
-}
-#endif
--- a/test/runtime/ClassFile/BadHelloWorld.jcod	Tue Oct 27 03:35:20 2020 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * This file fuzzes the class name #15 to have a leading 'L' and ending ';'.
- */
-
-class BadHelloWorld {
-  0xCAFEBABE;
-  0; // minor version
-  52; // version
-  [31] { // Constant Pool
-    ; // first element is empty
-    Utf8 "BadHelloWorld"; // #1     at 0x0A
-    class #1; // #2     at 0x1A
-    Utf8 "java/lang/Object"; // #3     at 0x1D
-    class #3; // #4     at 0x30
-    Utf8 "<init>"; // #5     at 0x33
-    Utf8 "()V"; // #6     at 0x3C
-    NameAndType #5 #6; // #7     at 0x42
-    Method #4 #7; // #8     at 0x47
-    Utf8 "toString"; // #9     at 0x4C
-    Utf8 "()Ljava/lang/String;"; // #10     at 0x57
-    Utf8 "Hello, world!"; // #11     at 0x6E
-    String #11; // #12     at 0x7E
-    Utf8 "main"; // #13     at 0x81
-    Utf8 "([Ljava/lang/String;)V"; // #14     at 0x88
-    Utf8 "LBadHelloWorld;"; // #15     at 0xA1
-    class #15; // #16     at 0xB3
-    Method #16 #7; // #17     at 0xB6
-    Utf8 "java/lang/System"; // #18     at 0xBB
-    class #18; // #19     at 0xCE
-    Utf8 "out"; // #20     at 0xD1
-    Utf8 "Ljava/io/PrintStream;"; // #21     at 0xD7
-    NameAndType #20 #21; // #22     at 0xEF
-    Field #19 #22; // #23     at 0xF4
-    Utf8 "java/io/PrintStream"; // #24     at 0xF9
-    class #24; // #25     at 0x010F
-    Utf8 "println"; // #26     at 0x0112
-    Utf8 "(Ljava/lang/Object;)V"; // #27     at 0x011C
-    NameAndType #26 #27; // #28     at 0x0134
-    Method #25 #28; // #29     at 0x0139
-    Utf8 "Code"; // #30     at 0x013E
-  } // Constant Pool
-
-  0x0021; // access
-  #2;// this_cpx
-  #4;// super_cpx
-
-  [0] { // Interfaces
-  } // Interfaces
-
-  [0] { // fields
-  } // fields
-
-  [3] { // methods
-    { // Member at 0x0151
-      0x0001; // access
-      #5; // name_cpx
-      #6; // sig_cpx
-      [1] { // Attributes
-        Attr(#30, 17) { // Code at 0x0159
-          1; // max_stack
-          1; // max_locals
-          Bytes[5]{
-            0x2AB70008B1;
-          };
-          [0] { // Traps
-          } // end Traps
-          [0] { // Attributes
-          } // Attributes
-        } // end Code
-      } // Attributes
-    } // Member
-    ;
-    { // Member at 0x0170
-      0x0001; // access
-      #9; // name_cpx
-      #10; // sig_cpx
-      [1] { // Attributes
-        Attr(#30, 15) { // Code at 0x0178
-          1; // max_stack
-          1; // max_locals
-          Bytes[3]{
-            0x120CB0;
-          };
-          [0] { // Traps
-          } // end Traps
-          [0] { // Attributes
-          } // Attributes
-        } // end Code
-      } // Attributes
-    } // Member
-    ;
-    { // Member at 0x018D
-      0x0089; // access
-      #13; // name_cpx
-      #14; // sig_cpx
-      [1] { // Attributes
-        Attr(#30, 28) { // Code at 0x0195
-          2; // max_stack
-          2; // max_locals
-          Bytes[16]{
-            0xBB001059B700114C;
-            0xB200172BB6001DB1;
-          };
-          [0] { // Traps
-          } // end Traps
-          [0] { // Attributes
-          } // Attributes
-        } // end Code
-      } // Attributes
-    } // Member
-  } // methods
-
-  [0] { // Attributes
-  } // Attributes
-} // end class BadHelloWorld
--- a/test/runtime/ClassFile/FormatCheckingTest.java	Tue Oct 27 03:35:20 2020 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * @test
- * @bug 8148854
- * @summary Ensure class name loaded by app class loader is format checked by default
- * @library /testlibrary
- * @compile BadHelloWorld.jcod
- * @run main FormatCheckingTest
- */
-
-import com.oracle.java.testlibrary.OutputAnalyzer;
-import com.oracle.java.testlibrary.ProcessTools;
-
-public class FormatCheckingTest {
-    public static void main(String args[]) throws Throwable {
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("BadHelloWorld");
-        OutputAnalyzer output = new OutputAnalyzer(pb.start());
-        output.shouldContain("java.lang.ClassFormatError: Illegal class name");
-        output.shouldHaveExitValue(1);
-    }
-}
--- a/test/runtime/CommandLine/TraceExceptionsTest.java	Tue Oct 27 03:35:20 2020 +0000
+++ b/test/runtime/CommandLine/TraceExceptionsTest.java	Tue Oct 27 06:33:36 2020 +0000
@@ -33,11 +33,6 @@
 public class TraceExceptionsTest {
     public static void main(String[] args) throws Exception {
 
-        if (!Platform.isDebugBuild()) {
-          System.out.println("Skip the test on product builds since XX:+TraceExceptions is not available on product builds");
-          return;
-        }
-
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-XX:+TraceExceptions", "NoClassFound");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/containers/docker/CheckOperatingSystemMXBean.java	Tue Oct 27 06:33:36 2020 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Red Hat Inc. 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.
+ */
+
+import com.sun.management.OperatingSystemMXBean;
+import java.lang.management.ManagementFactory;
+
+public class CheckOperatingSystemMXBean {
+
+    public static void main(String[] args) {
+        System.out.println("Checking OperatingSystemMXBean");
+
+        OperatingSystemMXBean osBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
+        System.out.println(String.format("Runtime.availableProcessors: %d", Runtime.getRuntime().availableProcessors()));
+        System.out.println(String.format("OperatingSystemMXBean.getAvailableProcessors: %d", osBean.getAvailableProcessors()));
+        System.out.println(String.format("OperatingSystemMXBean.getTotalPhysicalMemorySize: %d", osBean.getTotalPhysicalMemorySize()));
+        System.out.println(String.format("OperatingSystemMXBean.getFreePhysicalMemorySize: %d", osBean.getFreePhysicalMemorySize()));
+        System.out.println(String.format("OperatingSystemMXBean.getTotalSwapSpaceSize: %d", osBean.getTotalSwapSpaceSize()));
+        System.out.println(String.format("OperatingSystemMXBean.getFreeSwapSpaceSize: %d", osBean.getFreeSwapSpaceSize()));
+        System.out.println(String.format("OperatingSystemMXBean.getSystemCpuLoad: %f", osBean.getSystemCpuLoad()));
+    }
+
+}
--- a/test/runtime/containers/docker/Dockerfile-BasicTest	Tue Oct 27 03:35:20 2020 +0000
+++ b/test/runtime/containers/docker/Dockerfile-BasicTest	Tue Oct 27 06:33:36 2020 +0000
@@ -1,4 +1,4 @@
-FROM oraclelinux:7.2
+FROM oraclelinux:7.6
 MAINTAINER mikhailo.seledtsov@oracle.com
 
 COPY /jdk /jdk
--- a/test/runtime/containers/docker/TestCPUAwareness.java	Tue Oct 27 03:35:20 2020 +0000
+++ b/test/runtime/containers/docker/TestCPUAwareness.java	Tue Oct 27 06:33:36 2020 +0000
@@ -25,7 +25,9 @@
 /*
  * @test
  * @summary Test JVM's CPU resource awareness when running inside docker container
- * @library /testlibrary
+ * @library /testlibrary /testlibrary/whitebox
+ * @build sun.hotspot.WhiteBox PrintContainerInfo CheckOperatingSystemMXBean
+ * @run driver ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
  * @run driver TestCPUAwareness
  */
 
@@ -72,6 +74,14 @@
             testCpuQuotaAndPeriod(150*1000, 100*1000);
             testCpuQuotaAndPeriod(400*1000, 100*1000);
 
+            testOperatingSystemMXBeanAwareness("0.5", "1");
+            testOperatingSystemMXBeanAwareness("1.0", "1");
+            if (availableCPUs > 2) {
+                testOperatingSystemMXBeanAwareness("1.2", "2");
+                testOperatingSystemMXBeanAwareness("1.8", "2");
+                testOperatingSystemMXBeanAwareness("2.0", "2");
+            }
+
         } finally {
             DockerTestUtils.removeDockerImage(imageName);
         }
@@ -202,4 +212,21 @@
             .shouldMatch("CPU Shares is.*" + shares)
             .shouldMatch("active_processor_count.*" + expectedAPC);
     }
+
+    private static void testOperatingSystemMXBeanAwareness(String cpuAllocation, String expectedCpus) throws Exception {
+        Common.logNewTestCase("Check OperatingSystemMXBean");
+
+        DockerRunOptions opts = Common.newOpts(imageName, "CheckOperatingSystemMXBean")
+            .addDockerOpts(
+                "--cpus", cpuAllocation
+            );
+
+        DockerTestUtils.dockerRunJava(opts)
+            .shouldHaveExitValue(0)
+            .shouldContain("Checking OperatingSystemMXBean")
+            .shouldContain("Runtime.availableProcessors: " + expectedCpus)
+            .shouldContain("OperatingSystemMXBean.getAvailableProcessors: " + expectedCpus)
+            .shouldMatch("OperatingSystemMXBean\\.getSystemCpuLoad: [0-9]+\\.[0-9]+")
+            ;
+    }
 }
--- a/test/runtime/containers/docker/TestMemoryAwareness.java	Tue Oct 27 03:35:20 2020 +0000
+++ b/test/runtime/containers/docker/TestMemoryAwareness.java	Tue Oct 27 06:33:36 2020 +0000
@@ -26,7 +26,7 @@
  * @test
  * @summary Test JVM's memory resource awareness when running inside docker container
  * @library /testlibrary /testlibrary/whitebox
- * @build AttemptOOM sun.hotspot.WhiteBox PrintContainerInfo
+ * @build AttemptOOM sun.hotspot.WhiteBox PrintContainerInfo CheckOperatingSystemMXBean
  * @run driver ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
  * @run driver TestMemoryAwareness
  */
@@ -59,6 +59,18 @@
             // Add extra 10 Mb to allocator limit, to be sure to cause OOM
             testOOM("256m", 256 + 10);
 
+            testOperatingSystemMXBeanAwareness(
+                "100M", Integer.toString(((int) Math.pow(2, 20)) * 100),
+                "150M", Integer.toString(((int) Math.pow(2, 20)) * (150 - 100))
+            );
+            testOperatingSystemMXBeanAwareness(
+                "128M", Integer.toString(((int) Math.pow(2, 20)) * 128),
+                "256M", Integer.toString(((int) Math.pow(2, 20)) * (256 - 128))
+            );
+            testOperatingSystemMXBeanAwareness(
+                "1G", Integer.toString(((int) Math.pow(2, 20)) * 1024),
+                "1500M", Integer.toString(((int) Math.pow(2, 20)) * (1500 - 1024))
+            );
         } finally {
             DockerTestUtils.removeDockerImage(imageName);
         }
@@ -106,4 +118,24 @@
             .shouldContain("java.lang.OutOfMemoryError");
     }
 
+    private static void testOperatingSystemMXBeanAwareness(String memoryAllocation, String expectedMemory,
+            String swapAllocation, String expectedSwap) throws Exception {
+        Common.logNewTestCase("Check OperatingSystemMXBean");
+
+        DockerRunOptions opts = Common.newOpts(imageName, "CheckOperatingSystemMXBean")
+            .addDockerOpts(
+                "--memory", memoryAllocation,
+                "--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]+")
+            ;
+    }
+
 }