changeset 46426:02a1fc064144

Merge
author sspitsyn
date Wed, 03 May 2017 02:32:02 +0000
parents 2f733d553ca0 2dfc07162b35
children 54713555867e
files
diffstat 67 files changed, 655 insertions(+), 583 deletions(-) [+]
line wrap: on
line diff
--- a/hotspot/.hgtags	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/.hgtags	Wed May 03 02:32:02 2017 +0000
@@ -560,6 +560,7 @@
 a9fdfd55835ef9dccb7f317b07249bd66653b874 jdk-9+154
 f3b3d77a1751897413aae43ac340a130b6fa2ae1 jdk-9+155
 43139c588ea48b6504e52b6c3dec530b17b1fdb4 jdk-9+156
+1ea217626ba0995dd03127f8322ba3687926a085 jdk-10+1
 b2d0a906afd73dcf27f572217eb1be0f196ec16c jdk-9+157
 4e78f30935229f13ce7c43089621cf7169f5abac jdk-9+158
 9211c2e89c1cd11ec2d5752b0f97131a7d7525c7 jdk-9+159
@@ -570,3 +571,4 @@
 0af429be8bbaeaaf0cb838e9af28c953dda6a9c8 jdk-9+164
 c92c6416ca03b1464d5ed99cf6201e52b5ba0a70 jdk-9+165
 560d7aa083a24b6a56443feb8de0f40435d33aa9 jdk-9+166
+48809c513ed5ebb4d4dbf2f454afcce2780db6db jdk-10+2
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed May 03 02:32:02 2017 +0000
@@ -968,10 +968,11 @@
         // than prefetch distance.
         __ set(prefetch_count, O4);
         __ cmp_and_brx_short(count, O4, Assembler::less, Assembler::pt, L_block_copy);
-        __ sub(count, prefetch_count, count);
+        __ sub(count, O4, count);
 
         (this->*copy_loop_func)(from, to, count, count_dec, L_block_copy_prefetch, true, true);
-        __ add(count, prefetch_count, count); // restore count
+        __ set(prefetch_count, O4);
+        __ add(count, O4, count);
 
       } // prefetch_count > 0
 
@@ -992,11 +993,12 @@
       // than prefetch distance.
       __ set(prefetch_count, O4);
       __ cmp_and_brx_short(count, O4, Assembler::lessUnsigned, Assembler::pt, L_copy);
-      __ sub(count, prefetch_count, count);
+      __ sub(count, O4, count);
 
       Label L_copy_prefetch;
       (this->*copy_loop_func)(from, to, count, count_dec, L_copy_prefetch, true, false);
-      __ add(count, prefetch_count, count); // restore count
+      __ set(prefetch_count, O4);
+      __ add(count, O4, count);
 
     } // prefetch_count > 0
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/AltHashing.java	Wed May 03 02:32:02 2017 +0000
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.memory;
+
+public class AltHashing {
+    public static long murmur3_32(long seed, byte[] data) {
+      long h1 = seed;
+      int len = data.length;
+      int count = len;
+
+      int offset = 0;
+
+      // body
+      while (count >= 4) {
+          long k1 = (data[offset] & 0x0FF)
+              | (data[offset + 1] & 0x0FF) << 8
+              | (data[offset + 2] & 0x0FF) << 16
+              | data[offset + 3] << 24;
+
+          count -= 4;
+          offset += 4;
+
+          k1 *= 0xcc9e2d51;
+          k1 = Integer.rotateLeft((int)k1, 15);
+          k1 *= 0x1b873593;
+          k1 &= 0xFFFFFFFFL;
+
+          h1 ^= k1;
+          h1 = Integer.rotateLeft((int)h1, 13);
+          h1 = h1 * 5 + 0xe6546b64;
+          h1 &= 0xFFFFFFFFL;
+      }
+
+      //tail
+      if (count > 0) {
+          long k1 = 0;
+
+          switch (count) {
+              case 3:
+                  k1 ^= (data[offset + 2] & 0xff) << 16;
+                  // fall through
+              case 2:
+                  k1 ^= (data[offset + 1] & 0xff) << 8;
+                  // fall through
+              case 1:
+                  k1 ^= (data[offset] & 0xff);
+                  // fall through
+              default:
+                  k1 *= 0xcc9e2d51;
+                  k1 = Integer.rotateLeft((int)k1, 15);
+                  k1 *= 0x1b873593;
+                  k1 &= 0xFFFFFFFFL;
+                  h1 ^= k1;
+                  h1 &= 0xFFFFFFFFL;
+          }
+      }
+
+      // finalization
+      h1 ^= len;
+
+      // finalization mix force all bits of a hash block to avalanche
+      h1 ^= h1 >> 16;
+      h1 *= 0x85ebca6b;
+      h1 &= 0xFFFFFFFFL;
+      h1 ^= h1 >> 13;
+      h1 *= 0xc2b2ae35;
+      h1 &= 0xFFFFFFFFL;
+      h1 ^= h1 >> 16;
+
+      return h1 & 0xFFFFFFFFL;
+  }
+}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/SymbolTable.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/SymbolTable.java	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -45,11 +45,14 @@
     Type type = db.lookupType("SymbolTable");
     theTableField  = type.getAddressField("_the_table");
     sharedTableField = type.getAddressField("_shared_table");
+    type = db.lookupType("RehashableSymbolHashtable");
+    seedField = type.getCIntegerField("_seed");
   }
 
   // Fields
   private static AddressField theTableField;
   private static AddressField sharedTableField;
+  private static CIntegerField seedField;
 
   private CompactHashTable sharedTable;
 
@@ -62,6 +65,17 @@
     return table;
   }
 
+  public static long getSeed() {
+      return (long) seedField.getValue();
+  }
+
+  public static boolean useAlternateHashcode() {
+      if (getSeed() != 0) {
+          return true;
+      }
+      return false;
+  }
+
   public SymbolTable(Address addr) {
     super(addr);
   }
@@ -86,11 +100,17 @@
   public Symbol probe(byte[] name) {
     long hashValue = hashSymbol(name);
 
+    // shared table does not use alternate hashing algorithm,
+    // it always uses the same original hash code.
     Symbol s = sharedTable.probe(name, hashValue);
     if (s != null) {
       return s;
     }
 
+    if (useAlternateHashcode()) {
+        hashValue = AltHashing.murmur3_32(getSeed(), name);
+    }
+
     for (HashtableEntry e = (HashtableEntry) bucket(hashToIndex(hashValue)); e != null; e = (HashtableEntry) e.next()) {
       if (e.hash() == hashValue) {
          Symbol sym = Symbol.create(e.literalValue());
--- a/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -42,23 +42,18 @@
 inline void Atomic::store_ptr(void*    store_value, volatile void*     dest) { *(void* volatile *)dest = store_value; }
 
 
-// Adding a lock prefix to an instruction on MP machine
-#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: "
-
 inline jint     Atomic::add    (jint     add_value, volatile jint*     dest) {
   jint addend = add_value;
-  int mp = os::is_MP();
-  __asm__ volatile (  LOCK_IF_MP(%3) "xaddl %0,(%2)"
+  __asm__ volatile (  "lock xaddl %0,(%2)"
                     : "=r" (addend)
-                    : "0" (addend), "r" (dest), "r" (mp)
+                    : "0" (addend), "r" (dest)
                     : "cc", "memory");
   return addend + add_value;
 }
 
 inline void Atomic::inc    (volatile jint*     dest) {
-  int mp = os::is_MP();
-  __asm__ volatile (LOCK_IF_MP(%1) "addl $1,(%0)" :
-                    : "r" (dest), "r" (mp) : "cc", "memory");
+  __asm__ volatile (  "lock addl $1,(%0)" :
+                    : "r" (dest) : "cc", "memory");
 }
 
 inline void Atomic::inc_ptr(volatile void*     dest) {
@@ -66,9 +61,8 @@
 }
 
 inline void Atomic::dec    (volatile jint*     dest) {
-  int mp = os::is_MP();
-  __asm__ volatile (LOCK_IF_MP(%1) "subl $1,(%0)" :
-                    : "r" (dest), "r" (mp) : "cc", "memory");
+  __asm__ volatile (  "lock subl $1,(%0)" :
+                    : "r" (dest) : "cc", "memory");
 }
 
 inline void Atomic::dec_ptr(volatile void*     dest) {
@@ -89,19 +83,17 @@
 
 #define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
 inline jbyte    Atomic::cmpxchg    (jbyte    exchange_value, volatile jbyte*    dest, jbyte    compare_value, cmpxchg_memory_order order) {
-  int mp = os::is_MP();
-  __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)"
+  __asm__ volatile (  "lock cmpxchgb %1,(%3)"
                     : "=a" (exchange_value)
-                    : "q" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
+                    : "q" (exchange_value), "a" (compare_value), "r" (dest)
                     : "cc", "memory");
   return exchange_value;
 }
 
 inline jint     Atomic::cmpxchg    (jint     exchange_value, volatile jint*     dest, jint     compare_value, cmpxchg_memory_order order) {
-  int mp = os::is_MP();
-  __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)"
+  __asm__ volatile (  "lock cmpxchgl %1,(%3)"
                     : "=a" (exchange_value)
-                    : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
+                    : "r" (exchange_value), "a" (compare_value), "r" (dest)
                     : "cc", "memory");
   return exchange_value;
 }
@@ -112,10 +104,9 @@
 
 inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
   intptr_t addend = add_value;
-  bool mp = os::is_MP();
-  __asm__ __volatile__ (LOCK_IF_MP(%3) "xaddq %0,(%2)"
+  __asm__ __volatile__ (  "lock xaddq %0,(%2)"
                         : "=r" (addend)
-                        : "0" (addend), "r" (dest), "r" (mp)
+                        : "0" (addend), "r" (dest)
                         : "cc", "memory");
   return addend + add_value;
 }
@@ -125,18 +116,16 @@
 }
 
 inline void Atomic::inc_ptr(volatile intptr_t* dest) {
-  bool mp = os::is_MP();
-  __asm__ __volatile__ (LOCK_IF_MP(%1) "addq $1,(%0)"
+  __asm__ __volatile__ (  "lock addq $1,(%0)"
                         :
-                        : "r" (dest), "r" (mp)
+                        : "r" (dest)
                         : "cc", "memory");
 }
 
 inline void Atomic::dec_ptr(volatile intptr_t* dest) {
-  bool mp = os::is_MP();
-  __asm__ __volatile__ (LOCK_IF_MP(%1) "subq $1,(%0)"
+  __asm__ __volatile__ (  "lock subq $1,(%0)"
                         :
-                        : "r" (dest), "r" (mp)
+                        : "r" (dest)
                         : "cc", "memory");
 }
 
@@ -149,10 +138,9 @@
 }
 
 inline jlong    Atomic::cmpxchg    (jlong    exchange_value, volatile jlong*    dest, jlong    compare_value, cmpxchg_memory_order order) {
-  bool mp = os::is_MP();
-  __asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)"
+  __asm__ __volatile__ (  "lock cmpxchgq %1,(%3)"
                         : "=a" (exchange_value)
-                        : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
+                        : "r" (exchange_value), "a" (compare_value), "r" (dest)
                         : "cc", "memory");
   return exchange_value;
 }
--- a/hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -42,23 +42,18 @@
 inline void Atomic::store_ptr(void*    store_value, volatile void*     dest) { *(void* volatile *)dest = store_value; }
 
 
-// Adding a lock prefix to an instruction on MP machine
-#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: "
-
 inline jint     Atomic::add    (jint     add_value, volatile jint*     dest) {
   jint addend = add_value;
-  int mp = os::is_MP();
-  __asm__ volatile (  LOCK_IF_MP(%3) "xaddl %0,(%2)"
+  __asm__ volatile (  "lock xaddl %0,(%2)"
                     : "=r" (addend)
-                    : "0" (addend), "r" (dest), "r" (mp)
+                    : "0" (addend), "r" (dest)
                     : "cc", "memory");
   return addend + add_value;
 }
 
 inline void Atomic::inc    (volatile jint*     dest) {
-  int mp = os::is_MP();
-  __asm__ volatile (LOCK_IF_MP(%1) "addl $1,(%0)" :
-                    : "r" (dest), "r" (mp) : "cc", "memory");
+  __asm__ volatile (  "lock addl $1,(%0)" :
+                    : "r" (dest) : "cc", "memory");
 }
 
 inline void Atomic::inc_ptr(volatile void*     dest) {
@@ -66,9 +61,8 @@
 }
 
 inline void Atomic::dec    (volatile jint*     dest) {
-  int mp = os::is_MP();
-  __asm__ volatile (LOCK_IF_MP(%1) "subl $1,(%0)" :
-                    : "r" (dest), "r" (mp) : "cc", "memory");
+  __asm__ volatile (  "lock subl $1,(%0)" :
+                    : "r" (dest) : "cc", "memory");
 }
 
 inline void Atomic::dec_ptr(volatile void*     dest) {
@@ -89,19 +83,17 @@
 
 #define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
 inline jbyte    Atomic::cmpxchg    (jbyte    exchange_value, volatile jbyte*    dest, jbyte    compare_value, cmpxchg_memory_order order) {
-  int mp = os::is_MP();
-  __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)"
+  __asm__ volatile ("lock cmpxchgb %1,(%3)"
                     : "=a" (exchange_value)
-                    : "q" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
+                    : "q" (exchange_value), "a" (compare_value), "r" (dest)
                     : "cc", "memory");
   return exchange_value;
 }
 
 inline jint     Atomic::cmpxchg    (jint     exchange_value, volatile jint*     dest, jint     compare_value, cmpxchg_memory_order order) {
-  int mp = os::is_MP();
-  __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)"
+  __asm__ volatile ("lock cmpxchgl %1,(%3)"
                     : "=a" (exchange_value)
-                    : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
+                    : "r" (exchange_value), "a" (compare_value), "r" (dest)
                     : "cc", "memory");
   return exchange_value;
 }
@@ -112,10 +104,9 @@
 
 inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
   intptr_t addend = add_value;
-  bool mp = os::is_MP();
-  __asm__ __volatile__ (LOCK_IF_MP(%3) "xaddq %0,(%2)"
+  __asm__ __volatile__ ("lock xaddq %0,(%2)"
                         : "=r" (addend)
-                        : "0" (addend), "r" (dest), "r" (mp)
+                        : "0" (addend), "r" (dest)
                         : "cc", "memory");
   return addend + add_value;
 }
@@ -125,18 +116,16 @@
 }
 
 inline void Atomic::inc_ptr(volatile intptr_t* dest) {
-  bool mp = os::is_MP();
-  __asm__ __volatile__ (LOCK_IF_MP(%1) "addq $1,(%0)"
+  __asm__ __volatile__ ("lock addq $1,(%0)"
                         :
-                        : "r" (dest), "r" (mp)
+                        : "r" (dest)
                         : "cc", "memory");
 }
 
 inline void Atomic::dec_ptr(volatile intptr_t* dest) {
-  bool mp = os::is_MP();
-  __asm__ __volatile__ (LOCK_IF_MP(%1) "subq $1,(%0)"
+  __asm__ __volatile__ ("lock subq $1,(%0)"
                         :
-                        : "r" (dest), "r" (mp)
+                        : "r" (dest)
                         : "cc", "memory");
 }
 
@@ -149,10 +138,9 @@
 }
 
 inline jlong    Atomic::cmpxchg    (jlong    exchange_value, volatile jlong*    dest, jlong    compare_value, cmpxchg_memory_order order) {
-  bool mp = os::is_MP();
-  __asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)"
+  __asm__ __volatile__ ("lock cmpxchgq %1,(%3)"
                         : "=a" (exchange_value)
-                        : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
+                        : "r" (exchange_value), "a" (compare_value), "r" (dest)
                         : "cc", "memory");
   return exchange_value;
 }
@@ -192,12 +180,12 @@
 
 extern "C" {
   // defined in linux_x86.s
-  jlong _Atomic_cmpxchg_long(jlong, volatile jlong*, jlong, bool);
+  jlong _Atomic_cmpxchg_long(jlong, volatile jlong*, jlong);
   void _Atomic_move_long(volatile jlong* src, volatile jlong* dst);
 }
 
 inline jlong    Atomic::cmpxchg    (jlong    exchange_value, volatile jlong*    dest, jlong    compare_value, cmpxchg_memory_order order) {
-  return _Atomic_cmpxchg_long(exchange_value, dest, compare_value, os::is_MP());
+  return _Atomic_cmpxchg_long(exchange_value, dest, compare_value);
 }
 
 inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) {
--- a/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.s	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.s	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 # 
-# Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 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
@@ -614,8 +614,7 @@
 
         # Support for jlong Atomic::cmpxchg(jlong exchange_value,
         #                                   volatile jlong* dest,
-        #                                   jlong compare_value,
-        #                                   bool is_MP)
+        #                                   jlong compare_value)
         #
         .p2align 4,,15
 	.type    _Atomic_cmpxchg_long,@function
@@ -628,10 +627,7 @@
         movl     24(%esp), %eax    # 24(%esp) : compare_value (low)
         movl     28(%esp), %edx    # 28(%esp) : compare_value (high)
         movl     20(%esp), %edi    # 20(%esp) : dest
-        cmpl     $0, 32(%esp)      # 32(%esp) : is_MP
-        je       1f
-        lock
-1:      cmpxchg8b (%edi)
+        lock cmpxchg8b (%edi)
         popl     %edi
         popl     %ebx
         ret
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Wed May 03 02:32:02 2017 +0000
@@ -404,7 +404,7 @@
   // is available to us as well
   Sysinfo cpu_info(SI_CPUBRAND);
   bool use_solaris_12_api = cpu_info.valid();
-  const char* impl;
+  const char* impl = "unknown";
   int impl_m = 0;
   if (use_solaris_12_api) {
     impl = cpu_info.value();
@@ -431,7 +431,7 @@
       kstat_close(kc);
     }
   }
-  assert(impl_m != 0, "Unknown CPU implementation %s", impl);
+  assert(impl_m != 0, "Unrecognized CPU implementation: %s", impl);
   features |= impl_m;
 
   bool is_sun4v = (features & sun4v_m) != 0;
--- a/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -52,31 +52,19 @@
 // For Sun Studio - implementation is in solaris_x86_[32/64].il.
 // For gcc - implementation is just below.
 
-// The lock prefix can be omitted for certain instructions on uniprocessors; to
-// facilitate this, os::is_MP() is passed as an additional argument.  64-bit
-// processors are assumed to be multi-threaded and/or multi-core, so the extra
-// argument is unnecessary.
-#ifndef _LP64
-#define IS_MP_DECL() , int is_mp
-#define IS_MP_ARG()  , (int) os::is_MP()
-#else
-#define IS_MP_DECL()
-#define IS_MP_ARG()
-#endif // _LP64
-
 extern "C" {
-  jint _Atomic_add(jint add_value, volatile jint* dest IS_MP_DECL());
+  jint _Atomic_add(jint add_value, volatile jint* dest);
   jint _Atomic_xchg(jint exchange_value, volatile jint* dest);
   jbyte _Atomic_cmpxchg_byte(jbyte exchange_value, volatile jbyte* dest,
-                       jbyte compare_value IS_MP_DECL());
+                             jbyte compare_value);
   jint _Atomic_cmpxchg(jint exchange_value, volatile jint* dest,
-                       jint compare_value IS_MP_DECL());
+                       jint compare_value);
   jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest,
-                             jlong compare_value IS_MP_DECL());
+                             jlong compare_value);
 }
 
 inline jint     Atomic::add    (jint     add_value, volatile jint*     dest) {
-  return _Atomic_add(add_value, dest IS_MP_ARG());
+  return _Atomic_add(add_value, dest);
 }
 
 inline jint     Atomic::xchg       (jint     exchange_value, volatile jint*     dest) {
@@ -85,15 +73,15 @@
 
 #define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
 inline jbyte    Atomic::cmpxchg    (jbyte    exchange_value, volatile jbyte*    dest, jbyte    compare_value, cmpxchg_memory_order order) {
-  return _Atomic_cmpxchg_byte(exchange_value, dest, compare_value IS_MP_ARG());
+  return _Atomic_cmpxchg_byte(exchange_value, dest, compare_value);
 }
 
 inline jint     Atomic::cmpxchg    (jint     exchange_value, volatile jint*     dest, jint     compare_value, cmpxchg_memory_order order) {
-  return _Atomic_cmpxchg(exchange_value, dest, compare_value IS_MP_ARG());
+  return _Atomic_cmpxchg(exchange_value, dest, compare_value);
 }
 
 inline jlong    Atomic::cmpxchg    (jlong    exchange_value, volatile jlong*    dest, jlong    compare_value, cmpxchg_memory_order order) {
-  return _Atomic_cmpxchg_long(exchange_value, dest, compare_value IS_MP_ARG());
+  return _Atomic_cmpxchg_long(exchange_value, dest, compare_value);
 }
 
 
@@ -174,25 +162,23 @@
 #endif // AMD64
 
 #ifdef _GNU_SOURCE
-// Add a lock prefix to an instruction on an MP machine
-#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: "
 
 extern "C" {
-  inline jint _Atomic_add(jint add_value, volatile jint* dest, int mp) {
+  inline jint _Atomic_add(jint add_value, volatile jint* dest) {
     jint addend = add_value;
-    __asm__ volatile (  LOCK_IF_MP(%3) "xaddl %0,(%2)"
+    __asm__ volatile ("lock xaddl %0,(%2)"
                     : "=r" (addend)
-                    : "0" (addend), "r" (dest), "r" (mp)
+                    : "0" (addend), "r" (dest)
                     : "cc", "memory");
     return addend + add_value;
   }
 
 #ifdef AMD64
-  inline jlong _Atomic_add_long(jlong add_value, volatile jlong* dest, int mp) {
+  inline jlong _Atomic_add_long(jlong add_value, volatile jlong* dest) {
     intptr_t addend = add_value;
-    __asm__ __volatile__ (LOCK_IF_MP(%3) "xaddq %0,(%2)"
+    __asm__ __volatile__ ("lock xaddq %0,(%2)"
                         : "=r" (addend)
-                        : "0" (addend), "r" (dest), "r" (mp)
+                        : "0" (addend), "r" (dest)
                         : "cc", "memory");
     return addend + add_value;
   }
@@ -215,35 +201,35 @@
     return exchange_value;
   }
 
-  inline jint _Atomic_cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value, int mp) {
-    __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)"
+  inline jint _Atomic_cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value) {
+    __asm__ volatile ("lock cmpxchgl %1,(%3)"
                     : "=a" (exchange_value)
-                    : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
+                    : "r" (exchange_value), "a" (compare_value), "r" (dest)
                     : "cc", "memory");
     return exchange_value;
   }
 
 
-  inline jbyte _Atomic_cmpxchg_byte(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, int mp) {
-    __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)"
+  inline jbyte _Atomic_cmpxchg_byte(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
+    __asm__ volatile ("lock cmpxchgb %1,(%3)"
                     : "=a" (exchange_value)
-                    : "q" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
+                    : "q" (exchange_value), "a" (compare_value), "r" (dest)
                     : "cc", "memory");
     return exchange_value;
   }
 
   // This is the interface to the atomic instruction in solaris_i486.s.
-  jlong _Atomic_cmpxchg_long_gcc(jlong exchange_value, volatile jlong* dest, jlong compare_value, int mp);
+  jlong _Atomic_cmpxchg_long_gcc(jlong exchange_value, volatile jlong* dest, jlong compare_value);
 
-  inline jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest, jlong compare_value, int mp) {
+  inline jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest, jlong compare_value) {
 #ifdef AMD64
-    __asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)"
+    __asm__ __volatile__ ("lock cmpxchgq %1,(%3)"
                         : "=a" (exchange_value)
-                        : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
+                        : "r" (exchange_value), "a" (compare_value), "r" (dest)
                         : "cc", "memory");
     return exchange_value;
 #else
-    return _Atomic_cmpxchg_long_gcc(exchange_value, dest, compare_value, os::is_MP());
+    return _Atomic_cmpxchg_long_gcc(exchange_value, dest, compare_value);
 
     #if 0
     // The code below does not work presumably because of the bug in gcc
@@ -255,23 +241,19 @@
     volatile jlong_accessor evl, cvl, rv;
     evl.long_value = exchange_value;
     cvl.long_value = compare_value;
-    int mp = os::is_MP();
 
-    __asm__ volatile ("cmp $0, %%esi\n\t"
-       "je 1f \n\t"
-       "lock\n\t"
-       "1: cmpxchg8b (%%edi)\n\t"
+    __asm__ volatile (
+       "lock cmpxchg8b (%%edi)\n\t"
        : "=a"(cvl.words[0]),   "=d"(cvl.words[1])
        : "a"(cvl.words[0]), "d"(cvl.words[1]),
          "b"(evl.words[0]), "c"(evl.words[1]),
-         "D"(dest), "S"(mp)
+         "D"(dest)
        :  "cc", "memory");
     return cvl.long_value;
     #endif // if 0
 #endif // AMD64
   }
 }
-#undef LOCK_IF_MP
 
 #endif // _GNU_SOURCE
 
--- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -55,18 +55,12 @@
       .end
 
   // Support for jint Atomic::add(jint inc, volatile jint* dest)
-  // An additional bool (os::is_MP()) is passed as the last argument.
       .inline _Atomic_add,3
       movl     0(%esp), %eax   // inc
       movl     4(%esp), %edx   // dest
       movl     %eax, %ecx
-      cmpl     $0, 8(%esp)     // MP test
-      jne      1f
-      xaddl    %eax, (%edx)
-      jmp      2f
-1:    lock
-      xaddl    %eax, (%edx)
-2:    addl     %ecx, %eax
+      lock xaddl %eax, (%edx)
+      addl     %ecx, %eax
       .end
 
   // Support for jint Atomic::xchg(jint exchange_value, volatile jint* dest).
@@ -79,41 +73,26 @@
   // Support for jbyte Atomic::cmpxchg(jbyte exchange_value,
   //                                   volatile jbyte *dest,
   //                                   jbyte compare_value)
-  // An additional bool (os::is_MP()) is passed as the last argument.
       .inline _Atomic_cmpxchg_byte,4
       movb     8(%esp), %al   // compare_value
       movb     0(%esp), %cl   // exchange_value
       movl     4(%esp), %edx   // dest
-      cmp      $0, 12(%esp)    // MP test
-      jne      1f
-      cmpxchgb %cl, (%edx)
-      jmp      2f
-1:    lock
-      cmpxchgb %cl, (%edx)
-2:
+      lock cmpxchgb %cl, (%edx)
       .end
 
   // Support for jint Atomic::cmpxchg(jint exchange_value,
   //                                  volatile jint *dest,
   //                                  jint compare_value)
-  // An additional bool (os::is_MP()) is passed as the last argument.
       .inline _Atomic_cmpxchg,4
       movl     8(%esp), %eax   // compare_value
       movl     0(%esp), %ecx   // exchange_value
       movl     4(%esp), %edx   // dest
-      cmp      $0, 12(%esp)    // MP test
-      jne      1f
-      cmpxchgl %ecx, (%edx)
-      jmp      2f
-1:    lock
-      cmpxchgl %ecx, (%edx)
-2:
+      lock cmpxchgl %ecx, (%edx)
       .end
 
   // Support for jlong Atomic::cmpxchg(jlong exchange_value,
   //                                   volatile jlong* dest,
   //                                   jlong compare_value)
-  // An additional bool (os::is_MP()) is passed as the last argument.
       .inline _Atomic_cmpxchg_long,6
       pushl    %ebx
       pushl    %edi
@@ -122,13 +101,8 @@
       movl     16(%esp), %edi  // dest
       movl     8(%esp), %ebx   // exchange_value (low)
       movl     12(%esp), %ecx  // exchange_high (high)
-      cmp      $0, 28(%esp)    // MP test
-      jne      1f
-      cmpxchg8b (%edi)
-      jmp      2f
-1:    lock
-      cmpxchg8b (%edi)
-2:    popl     %edi
+      lock cmpxchg8b (%edi)
+      popl     %edi
       popl     %ebx
       .end
 
--- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.s	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.s	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2004, 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
@@ -643,8 +643,7 @@
 
         / Support for jlong Atomic::cmpxchg(jlong exchange_value,
         /                                   volatile jlong* dest,
-        /                                   jlong compare_value,
-        /                                   bool is_MP)
+        /                                   jlong compare_value)
         / Used only for Solaris/gcc builds
         .align 16
 _Atomic_cmpxchg_long_gcc:
@@ -656,10 +655,7 @@
         movl     24(%esp), %eax    / 24(%esp) : compare_value (low)
         movl     28(%esp), %edx    / 28(%esp) : compare_value (high)
         movl     20(%esp), %edi    / 20(%esp) : dest
-        cmpl     $0, 32(%esp)      / 32(%esp) : is_MP
-        je       1f
-        lock
-1:      cmpxchg8b (%edi)
+        lock cmpxchg8b (%edi)
         popl     %edi
         popl     %ebx
         ret
--- a/hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -57,15 +57,6 @@
 inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; }
 inline void Atomic::store_ptr(void*    store_value, volatile void*     dest) { *(void* volatile *)dest = store_value; }
 
-// Adding a lock prefix to an instruction on MP machine
-// VC++ doesn't like the lock prefix to be on a single line
-// so we can't insert a label after the lock prefix.
-// By emitting a lock prefix, we can define a label after it.
-#define LOCK_IF_MP(mp) __asm cmp mp, 0  \
-                       __asm je L0      \
-                       __asm _emit 0xF0 \
-                       __asm L0:
-
 #ifdef AMD64
 inline void Atomic::store    (jlong    store_value, jlong*    dest) { *dest = store_value; }
 inline void Atomic::store    (jlong    store_value, volatile jlong*    dest) { *dest = store_value; }
@@ -144,13 +135,11 @@
 #else // !AMD64
 
 inline jint     Atomic::add    (jint     add_value, volatile jint*     dest) {
-  int mp = os::is_MP();
   __asm {
     mov edx, dest;
     mov eax, add_value;
     mov ecx, eax;
-    LOCK_IF_MP(mp)
-    xadd dword ptr [edx], eax;
+    lock xadd dword ptr [edx], eax;
     add eax, ecx;
   }
 }
@@ -165,11 +154,9 @@
 
 inline void Atomic::inc    (volatile jint*     dest) {
   // alternative for InterlockedIncrement
-  int mp = os::is_MP();
   __asm {
     mov edx, dest;
-    LOCK_IF_MP(mp)
-    add dword ptr [edx], 1;
+    lock add dword ptr [edx], 1;
   }
 }
 
@@ -183,11 +170,9 @@
 
 inline void Atomic::dec    (volatile jint*     dest) {
   // alternative for InterlockedDecrement
-  int mp = os::is_MP();
   __asm {
     mov edx, dest;
-    LOCK_IF_MP(mp)
-    sub dword ptr [edx], 1;
+    lock sub dword ptr [edx], 1;
   }
 }
 
@@ -219,30 +204,25 @@
 #define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
 inline jbyte    Atomic::cmpxchg    (jbyte    exchange_value, volatile jbyte*    dest, jbyte    compare_value, cmpxchg_memory_order order) {
   // alternative for InterlockedCompareExchange
-  int mp = os::is_MP();
   __asm {
     mov edx, dest
     mov cl, exchange_value
     mov al, compare_value
-    LOCK_IF_MP(mp)
-    cmpxchg byte ptr [edx], cl
+    lock cmpxchg byte ptr [edx], cl
   }
 }
 
 inline jint     Atomic::cmpxchg    (jint     exchange_value, volatile jint*     dest, jint     compare_value, cmpxchg_memory_order order) {
   // alternative for InterlockedCompareExchange
-  int mp = os::is_MP();
   __asm {
     mov edx, dest
     mov ecx, exchange_value
     mov eax, compare_value
-    LOCK_IF_MP(mp)
-    cmpxchg dword ptr [edx], ecx
+    lock cmpxchg dword ptr [edx], ecx
   }
 }
 
 inline jlong    Atomic::cmpxchg    (jlong    exchange_value, volatile jlong*    dest, jlong    compare_value, cmpxchg_memory_order order) {
-  int mp = os::is_MP();
   jint ex_lo  = (jint)exchange_value;
   jint ex_hi  = *( ((jint*)&exchange_value) + 1 );
   jint cmp_lo = (jint)compare_value;
@@ -255,8 +235,7 @@
     mov edi, dest
     mov ebx, ex_lo
     mov ecx, ex_hi
-    LOCK_IF_MP(mp)
-    cmpxchg8b qword ptr [edi]
+    lock cmpxchg8b qword ptr [edi]
     pop edi
     pop ebx
   }
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Wed May 03 02:32:02 2017 +0000
@@ -102,6 +102,7 @@
   // ModuleEntryTable or PackageEntryTable created for it. The defining package
   // and module for an anonymous class will be found in its host class.
   if (!is_anonymous) {
+    _packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size);
     if (h_class_loader.is_null()) {
       // Create unnamed module for boot loader
       _unnamed_module = ModuleEntry::create_boot_unnamed_module(this);
@@ -297,8 +298,8 @@
   if (_modules != NULL) {
     for (int i = 0; i < _modules->table_size(); i++) {
       for (ModuleEntry* entry = _modules->bucket(i);
-                              entry != NULL;
-                              entry = entry->next()) {
+           entry != NULL;
+           entry = entry->next()) {
         f(entry);
       }
     }
@@ -306,13 +307,12 @@
 }
 
 void ClassLoaderData::packages_do(void f(PackageEntry*)) {
-  // Lock-free access requires load_ptr_acquire
-  PackageEntryTable* packages = load_ptr_acquire(&_packages);
-  if (packages != NULL) {
-    for (int i = 0; i < packages->table_size(); i++) {
-      for (PackageEntry* entry = packages->bucket(i);
-                              entry != NULL;
-                              entry = entry->next()) {
+  assert_locked_or_safepoint(Module_lock);
+  if (_packages != NULL) {
+    for (int i = 0; i < _packages->table_size(); i++) {
+      for (PackageEntry* entry = _packages->bucket(i);
+           entry != NULL;
+           entry = entry->next()) {
         f(entry);
       }
     }
@@ -494,22 +494,6 @@
   free_deallocate_list();
 }
 
-PackageEntryTable* ClassLoaderData::packages() {
-  // Lazily create the package entry table at first request.
-  // Lock-free access requires load_ptr_acquire.
-  PackageEntryTable* packages = load_ptr_acquire(&_packages);
-  if (packages == NULL) {
-    MutexLockerEx m1(metaspace_lock(), Mutex::_no_safepoint_check_flag);
-    // Check if _packages got allocated while we were waiting for this lock.
-    if ((packages = _packages) == NULL) {
-      packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size);
-      // Ensure _packages is stable, since it is examined without a lock
-      OrderAccess::release_store_ptr(&_packages, packages);
-    }
-  }
-  return packages;
-}
-
 ModuleEntryTable* ClassLoaderData::modules() {
   // Lazily create the module entry table at first request.
   // Lock-free access requires load_ptr_acquire.
@@ -1096,7 +1080,7 @@
     // occur after each class loader's aliveness is determined.
     data = _head;
     while (data != NULL) {
-      if (data->packages_defined()) {
+      if (data->packages() != NULL) {
         data->packages()->purge_all_package_exports();
       }
       if (data->modules_defined()) {
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp	Wed May 03 02:32:02 2017 +0000
@@ -347,8 +347,7 @@
   bool contains_klass(Klass* k);
   void record_dependency(const Klass* to, TRAPS);
   void init_dependencies(TRAPS);
-  PackageEntryTable* packages();
-  bool packages_defined() { return (_packages != NULL); }
+  PackageEntryTable* packages() { return _packages; }
   ModuleEntry* unnamed_module() { return _unnamed_module; }
   ModuleEntryTable* modules();
   bool modules_defined() { return (_modules != NULL); }
--- a/hotspot/src/share/vm/classfile/packageEntry.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/classfile/packageEntry.cpp	Wed May 03 02:32:02 2017 +0000
@@ -174,8 +174,6 @@
 }
 
 PackageEntryTable::~PackageEntryTable() {
-  assert_locked_or_safepoint(Module_lock);
-
   // Walk through all buckets and all entries in each bucket,
   // freeing each entry.
   for (int i = 0; i < table_size(); ++i) {
@@ -271,6 +269,7 @@
 // Called when a define module for java.base is being processed.
 // Verify the packages loaded thus far are in java.base's package list.
 void PackageEntryTable::verify_javabase_packages(GrowableArray<Symbol*> *pkg_list) {
+  assert_lock_strong(Module_lock);
   for (int i = 0; i < table_size(); i++) {
     for (PackageEntry* entry = bucket(i);
                        entry != NULL;
--- a/hotspot/src/share/vm/code/vtableStubs.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/code/vtableStubs.cpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -218,11 +218,11 @@
   HandleMark hm;
   Klass* klass = receiver->klass();
   InstanceKlass* ik = InstanceKlass::cast(klass);
-  klassVtable* vt = ik->vtable();
+  klassVtable vt = ik->vtable();
   ik->print();
   fatal("bad compiled vtable dispatch: receiver " INTPTR_FORMAT ", "
         "index %d (vtable length %d)",
-        p2i(receiver), index, vt->length());
+        p2i(receiver), index, vt.length());
 }
 
 #endif // PRODUCT
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp	Wed May 03 02:32:02 2017 +0000
@@ -923,8 +923,6 @@
 
           double end_vtime_sec = os::elapsedVTime();
           double elapsed_vtime_sec = end_vtime_sec - start_vtime_sec;
-          _cm->clear_has_overflown();
-
           _cm->do_yield_check();
 
           jlong sleep_time_ms;
--- a/hotspot/src/share/vm/gc/serial/markSweep.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/gc/serial/markSweep.cpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -224,12 +224,12 @@
   mark_and_push_closure.set_ref_processor(_ref_processor);
 }
 
-MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure;
+AdjustPointerClosure MarkSweep::adjust_pointer_closure;
 
 template <typename T>
-void MarkSweep::AdjustPointerClosure::do_oop_nv(T* p)      { adjust_pointer(p); }
-void MarkSweep::AdjustPointerClosure::do_oop(oop* p)       { do_oop_nv(p); }
-void MarkSweep::AdjustPointerClosure::do_oop(narrowOop* p) { do_oop_nv(p); }
+void AdjustPointerClosure::do_oop_nv(T* p)      { MarkSweep::adjust_pointer(p); }
+void AdjustPointerClosure::do_oop(oop* p)       { do_oop_nv(p); }
+void AdjustPointerClosure::do_oop(narrowOop* p) { do_oop_nv(p); }
 
 void MarkSweep::adjust_marks() {
   assert( _preserved_oop_stack.size() == _preserved_mark_stack.size(),
@@ -280,79 +280,5 @@
   MarkSweep::_gc_tracer = new (ResourceObj::C_HEAP, mtGC) SerialOldTracer();
 }
 
-int InstanceKlass::oop_ms_adjust_pointers(oop obj) {
-  int size = size_helper();
-  oop_oop_iterate_oop_maps<true>(obj, &MarkSweep::adjust_pointer_closure);
-  return size;
-}
-
-int InstanceMirrorKlass::oop_ms_adjust_pointers(oop obj) {
-  int size = oop_size(obj);
-  InstanceKlass::oop_ms_adjust_pointers(obj);
-
-  oop_oop_iterate_statics<true>(obj, &MarkSweep::adjust_pointer_closure);
-  return size;
-}
-
-int InstanceClassLoaderKlass::oop_ms_adjust_pointers(oop obj) {
-  return InstanceKlass::oop_ms_adjust_pointers(obj);
-}
-
-#ifdef ASSERT
-template <class T> static void trace_reference_gc(const char *s, oop obj,
-                                                  T* referent_addr,
-                                                  T* next_addr,
-                                                  T* discovered_addr) {
-  log_develop_trace(gc, ref)("%s obj " PTR_FORMAT, s, p2i(obj));
-  log_develop_trace(gc, ref)("     referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
-                             p2i(referent_addr), p2i(referent_addr ? (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL));
-  log_develop_trace(gc, ref)("     next_addr/* " PTR_FORMAT " / " PTR_FORMAT,
-                             p2i(next_addr), p2i(next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL));
-  log_develop_trace(gc, ref)("     discovered_addr/* " PTR_FORMAT " / " PTR_FORMAT,
-                             p2i(discovered_addr), p2i(discovered_addr ? (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL));
-}
-#endif
-
-template <class T> void static adjust_object_specialized(oop obj) {
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
-  MarkSweep::adjust_pointer(referent_addr);
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
-  MarkSweep::adjust_pointer(next_addr);
-  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
-  MarkSweep::adjust_pointer(discovered_addr);
-  debug_only(trace_reference_gc("InstanceRefKlass::oop_ms_adjust_pointers", obj,
-                                referent_addr, next_addr, discovered_addr);)
-}
-
-int InstanceRefKlass::oop_ms_adjust_pointers(oop obj) {
-  int size = size_helper();
-  InstanceKlass::oop_ms_adjust_pointers(obj);
-
-  if (UseCompressedOops) {
-    adjust_object_specialized<narrowOop>(obj);
-  } else {
-    adjust_object_specialized<oop>(obj);
-  }
-  return size;
-}
-
-int ObjArrayKlass::oop_ms_adjust_pointers(oop obj) {
-  assert(obj->is_objArray(), "obj must be obj array");
-  objArrayOop a = objArrayOop(obj);
-  // Get size before changing pointers.
-  // Don't call size() or oop_size() since that is a virtual call.
-  int size = a->object_size();
-  oop_oop_iterate_elements<true>(a, &MarkSweep::adjust_pointer_closure);
-  return size;
-}
-
-int TypeArrayKlass::oop_ms_adjust_pointers(oop obj) {
-  assert(obj->is_typeArray(), "must be a type array");
-  typeArrayOop t = typeArrayOop(obj);
-  // Performance tweak: We skip iterating over the klass pointer since we
-  // know that Universe::TypeArrayKlass never moves.
-  return t->object_size();
-}
-
 // Generate MS specialized oop_oop_iterate functions.
 SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_MS(ALL_KLASS_OOP_OOP_ITERATE_DEFN)
--- a/hotspot/src/share/vm/gc/serial/markSweep.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/gc/serial/markSweep.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,6 +50,7 @@
 // declared at end
 class PreservedMark;
 class MarkAndPushClosure;
+class AdjustPointerClosure;
 
 class MarkSweep : AllStatic {
   //
@@ -66,16 +67,6 @@
     virtual void do_void();
   };
 
-  class AdjustPointerClosure: public OopsInGenClosure {
-   public:
-    template <typename T> void do_oop_nv(T* p);
-    virtual void do_oop(oop* p);
-    virtual void do_oop(narrowOop* p);
-
-    // This closure provides its own oop verification code.
-    debug_only(virtual bool should_verify_oops() { return false; })
-  };
-
   // Used for java/lang/ref handling
   class IsAliveClosure: public BoolObjectClosure {
    public:
@@ -201,6 +192,17 @@
   }
 };
 
+class AdjustPointerClosure: public OopsInGenClosure {
+ public:
+  template <typename T> void do_oop_nv(T* p);
+  virtual void do_oop(oop* p);
+  virtual void do_oop(narrowOop* p);
+  virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS; }
+
+  // This closure provides its own oop verification code.
+  debug_only(virtual bool should_verify_oops() { return false; })
+};
+
 class PreservedMark VALUE_OBJ_CLASS_SPEC {
 private:
   oop _obj;
--- a/hotspot/src/share/vm/gc/serial/markSweep.inline.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/gc/serial/markSweep.inline.hpp	Wed May 03 02:32:02 2017 +0000
@@ -42,7 +42,7 @@
 }
 
 inline int MarkSweep::adjust_pointers(oop obj) {
-  return obj->ms_adjust_pointers();
+  return obj->oop_iterate_size(&MarkSweep::adjust_pointer_closure);
 }
 
 template <class T> inline void MarkSweep::adjust_pointer(T* p) {
--- a/hotspot/src/share/vm/gc/shared/specialized_oop_closures.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/gc/shared/specialized_oop_closures.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -44,6 +44,7 @@
 class FilteringClosure;
 // MarkSweep
 class MarkAndPushClosure;
+class AdjustPointerClosure;
 // ParNew
 class ParScanWithBarrierClosure;
 class ParScanWithoutBarrierClosure;
@@ -90,7 +91,8 @@
   SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f)
 
 #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_MS(f)      \
-  f(MarkAndPushClosure,_nv)
+  f(MarkAndPushClosure,_nv)                             \
+  f(AdjustPointerClosure,_nv)
 
 #if INCLUDE_ALL_GCS
 #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_CMS(f)     \
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Wed May 03 02:32:02 2017 +0000
@@ -86,14 +86,15 @@
 // State accessors
 
 void InterpreterRuntime::set_bcp_and_mdp(address bcp, JavaThread *thread) {
-  last_frame(thread).interpreter_frame_set_bcp(bcp);
+  LastFrameAccessor last_frame(thread);
+  last_frame.set_bcp(bcp);
   if (ProfileInterpreter) {
     // ProfileTraps uses MDOs independently of ProfileInterpreter.
     // That is why we must check both ProfileInterpreter and mdo != NULL.
-    MethodData* mdo = last_frame(thread).interpreter_frame_method()->method_data();
+    MethodData* mdo = last_frame.method()->method_data();
     if (mdo != NULL) {
       NEEDS_CLEANUP;
-      last_frame(thread).interpreter_frame_set_mdp(mdo->bci_to_dp(last_frame(thread).interpreter_frame_bci()));
+      last_frame.set_mdp(mdo->bci_to_dp(last_frame.bci()));
     }
   }
 }
@@ -104,8 +105,9 @@
 
 IRT_ENTRY(void, InterpreterRuntime::ldc(JavaThread* thread, bool wide))
   // access constant pool
-  ConstantPool* pool = method(thread)->constants();
-  int index = wide ? get_index_u2(thread, Bytecodes::_ldc_w) : get_index_u1(thread, Bytecodes::_ldc);
+  LastFrameAccessor last_frame(thread);
+  ConstantPool* pool = last_frame.method()->constants();
+  int index = wide ? last_frame.get_index_u2(Bytecodes::_ldc_w) : last_frame.get_index_u1(Bytecodes::_ldc);
   constantTag tag = pool->tag_at(index);
 
   assert (tag.is_unresolved_klass() || tag.is_klass(), "wrong ldc call");
@@ -118,13 +120,14 @@
   assert(bytecode == Bytecodes::_fast_aldc ||
          bytecode == Bytecodes::_fast_aldc_w, "wrong bc");
   ResourceMark rm(thread);
-  methodHandle m (thread, method(thread));
-  Bytecode_loadconstant ldc(m, bci(thread));
+  LastFrameAccessor last_frame(thread);
+  methodHandle m (thread, last_frame.method());
+  Bytecode_loadconstant ldc(m, last_frame.bci());
   oop result = ldc.resolve_constant(CHECK);
 #ifdef ASSERT
   {
     // The bytecode wrappers aren't GC-safe so construct a new one
-    Bytecode_loadconstant ldc2(m, bci(thread));
+    Bytecode_loadconstant ldc2(m, last_frame.bci());
     oop coop = m->constants()->resolved_references()->obj_at(ldc2.cache_index());
     assert(result == coop, "expected result for assembly code");
   }
@@ -181,10 +184,11 @@
 
 IRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
   // We may want to pass in more arguments - could make this slightly faster
-  ConstantPool* constants = method(thread)->constants();
-  int          i = get_index_u2(thread, Bytecodes::_multianewarray);
-  Klass* klass = constants->klass_at(i, CHECK);
-  int   nof_dims = number_of_dimensions(thread);
+  LastFrameAccessor last_frame(thread);
+  ConstantPool* constants = last_frame.method()->constants();
+  int          i = last_frame.get_index_u2(Bytecodes::_multianewarray);
+  Klass* klass   = constants->klass_at(i, CHECK);
+  int   nof_dims = last_frame.number_of_dimensions();
   assert(klass->is_klass(), "not a class");
   assert(nof_dims >= 1, "multianewarray rank must be nonzero");
 
@@ -216,8 +220,9 @@
 // Quicken instance-of and check-cast bytecodes
 IRT_ENTRY(void, InterpreterRuntime::quicken_io_cc(JavaThread* thread))
   // Force resolving; quicken the bytecode
-  int which = get_index_u2(thread, Bytecodes::_checkcast);
-  ConstantPool* cpool = method(thread)->constants();
+  LastFrameAccessor last_frame(thread);
+  int which = last_frame.get_index_u2(Bytecodes::_checkcast);
+  ConstantPool* cpool = last_frame.method()->constants();
   // We'd expect to assert that we're only here to quicken bytecodes, but in a multithreaded
   // program we might have seen an unquick'd bytecode in the interpreter but have another
   // thread quicken the bytecode before we get here.
@@ -256,8 +261,9 @@
 // If necessary, create an MDO to hold the information, and record it.
 void InterpreterRuntime::note_trap(JavaThread* thread, int reason, TRAPS) {
   assert(ProfileTraps, "call me only if profiling");
-  methodHandle trap_method(thread, method(thread));
-  int trap_bci = trap_method->bci_from(bcp(thread));
+  LastFrameAccessor last_frame(thread);
+  methodHandle trap_method(thread, last_frame.method());
+  int trap_bci = trap_method->bci_from(last_frame.bcp());
   note_trap_inner(thread, reason, trap_method, trap_bci, THREAD);
 }
 
@@ -390,12 +396,13 @@
 // invoke w/o arguments (i.e., as if one were inside the call).
 IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThread* thread, oopDesc* exception))
 
+  LastFrameAccessor last_frame(thread);
   Handle             h_exception(thread, exception);
-  methodHandle       h_method   (thread, method(thread));
+  methodHandle       h_method   (thread, last_frame.method());
   constantPoolHandle h_constants(thread, h_method->constants());
   bool               should_repeat;
   int                handler_bci;
-  int                current_bci = bci(thread);
+  int                current_bci = last_frame.bci();
 
   if (thread->frames_to_pop_failed_realloc() > 0) {
     // Allocation of scalar replaced object used in this frame
@@ -493,7 +500,7 @@
   // notify JVMTI of an exception throw; JVMTI will detect if this is a first
   // time throw or a stack unwinding throw and accordingly notify the debugger
   if (JvmtiExport::can_post_on_exceptions()) {
-    JvmtiExport::post_exception_throw(thread, h_method(), bcp(thread), h_exception());
+    JvmtiExport::post_exception_throw(thread, h_method(), last_frame.bcp(), h_exception());
   }
 
 #ifdef CC_INTERP
@@ -556,20 +563,21 @@
   Thread* THREAD = thread;
   // resolve field
   fieldDescriptor info;
-  constantPoolHandle pool(thread, method(thread)->constants());
-  methodHandle m(thread, method(thread));
+  LastFrameAccessor last_frame(thread);
+  constantPoolHandle pool(thread, last_frame.method()->constants());
+  methodHandle m(thread, last_frame.method());
   bool is_put    = (bytecode == Bytecodes::_putfield  || bytecode == Bytecodes::_nofast_putfield ||
                     bytecode == Bytecodes::_putstatic);
   bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
 
   {
     JvmtiHideSingleStepping jhss(thread);
-    LinkResolver::resolve_field_access(info, pool, get_index_u2_cpcache(thread, bytecode),
+    LinkResolver::resolve_field_access(info, pool, last_frame.get_index_u2_cpcache(bytecode),
                                        m, bytecode, CHECK);
   } // end JvmtiHideSingleStepping
 
   // check if link resolution caused cpCache to be updated
-  ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
+  ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry();
   if (cp_cache_entry->is_resolved(bytecode)) return;
 
   // compute auxiliary field attributes
@@ -718,15 +726,15 @@
 
 void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode) {
   Thread* THREAD = thread;
+  LastFrameAccessor last_frame(thread);
   // extract receiver from the outgoing argument list if necessary
   Handle receiver(thread, NULL);
   if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) {
     ResourceMark rm(thread);
-    methodHandle m (thread, method(thread));
-    Bytecode_invoke call(m, bci(thread));
+    methodHandle m (thread, last_frame.method());
+    Bytecode_invoke call(m, last_frame.bci());
     Symbol* signature = call.signature();
-    receiver = Handle(thread,
-                  thread->last_frame().interpreter_callee_receiver(signature));
+    receiver = Handle(thread, last_frame.callee_receiver(signature));
     assert(Universe::heap()->is_in_reserved_or_null(receiver()),
            "sanity check");
     assert(receiver.is_null() ||
@@ -736,12 +744,12 @@
 
   // resolve method
   CallInfo info;
-  constantPoolHandle pool(thread, method(thread)->constants());
+  constantPoolHandle pool(thread, last_frame.method()->constants());
 
   {
     JvmtiHideSingleStepping jhss(thread);
     LinkResolver::resolve_invoke(info, receiver, pool,
-                                 get_index_u2_cpcache(thread, bytecode), bytecode,
+                                 last_frame.get_index_u2_cpcache(bytecode), bytecode,
                                  CHECK);
     if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
       int retry_count = 0;
@@ -753,14 +761,14 @@
                   "Could not resolve to latest version of redefined method");
         // method is redefined in the middle of resolve so re-try.
         LinkResolver::resolve_invoke(info, receiver, pool,
-                                     get_index_u2_cpcache(thread, bytecode), bytecode,
+                                     last_frame.get_index_u2_cpcache(bytecode), bytecode,
                                      CHECK);
       }
     }
   } // end JvmtiHideSingleStepping
 
   // check if link resolution caused cpCache to be updated
-  ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
+  ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry();
   if (cp_cache_entry->is_resolved(bytecode)) return;
 
 #ifdef ASSERT
@@ -815,33 +823,35 @@
 void InterpreterRuntime::resolve_invokehandle(JavaThread* thread) {
   Thread* THREAD = thread;
   const Bytecodes::Code bytecode = Bytecodes::_invokehandle;
+  LastFrameAccessor last_frame(thread);
 
   // resolve method
   CallInfo info;
-  constantPoolHandle pool(thread, method(thread)->constants());
+  constantPoolHandle pool(thread, last_frame.method()->constants());
   {
     JvmtiHideSingleStepping jhss(thread);
     LinkResolver::resolve_invoke(info, Handle(), pool,
-                                 get_index_u2_cpcache(thread, bytecode), bytecode,
+                                 last_frame.get_index_u2_cpcache(bytecode), bytecode,
                                  CHECK);
   } // end JvmtiHideSingleStepping
 
-  ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
+  ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry();
   cp_cache_entry->set_method_handle(pool, info);
 }
 
 // First time execution:  Resolve symbols, create a permanent CallSite object.
 void InterpreterRuntime::resolve_invokedynamic(JavaThread* thread) {
   Thread* THREAD = thread;
+  LastFrameAccessor last_frame(thread);
   const Bytecodes::Code bytecode = Bytecodes::_invokedynamic;
 
   //TO DO: consider passing BCI to Java.
-  //  int caller_bci = method(thread)->bci_from(bcp(thread));
+  //  int caller_bci = last_frame.method()->bci_from(last_frame.bcp());
 
   // resolve method
   CallInfo info;
-  constantPoolHandle pool(thread, method(thread)->constants());
-  int index = get_index_u4(thread, bytecode);
+  constantPoolHandle pool(thread, last_frame.method()->constants());
+  int index = last_frame.get_index_u4(bytecode);
   {
     JvmtiHideSingleStepping jhss(thread);
     LinkResolver::resolve_invoke(info, Handle(), pool,
@@ -895,9 +905,9 @@
     // nm could have been unloaded so look it up again.  It's unsafe
     // to examine nm directly since it might have been freed and used
     // for something else.
-    frame fr = thread->last_frame();
-    Method* method =  fr.interpreter_frame_method();
-    int bci = method->bci_from(fr.interpreter_frame_bcp());
+    LastFrameAccessor last_frame(thread);
+    Method* method =  last_frame.method();
+    int bci = method->bci_from(last_frame.bcp());
     nm = method->lookup_osr_nmethod_for(bci, CompLevel_none, false);
   }
 #ifndef PRODUCT
@@ -917,11 +927,11 @@
   // flag, in case this method triggers classloading which will call into Java.
   UnlockFlagSaver fs(thread);
 
-  frame fr = thread->last_frame();
-  assert(fr.is_interpreted_frame(), "must come from interpreter");
-  methodHandle method(thread, fr.interpreter_frame_method());
+  LastFrameAccessor last_frame(thread);
+  assert(last_frame.is_interpreted_frame(), "must come from interpreter");
+  methodHandle method(thread, last_frame.method());
   const int branch_bci = branch_bcp != NULL ? method->bci_from(branch_bcp) : InvocationEntryBci;
-  const int bci = branch_bcp != NULL ? method->bci_from(fr.interpreter_frame_bcp()) : InvocationEntryBci;
+  const int bci = branch_bcp != NULL ? method->bci_from(last_frame.bcp()) : InvocationEntryBci;
 
   assert(!HAS_PENDING_EXCEPTION, "Should not have any exceptions pending");
   nmethod* osr_nm = CompilationPolicy::policy()->event(method, method, branch_bci, bci, CompLevel_none, NULL, thread);
@@ -937,9 +947,9 @@
     if (UseBiasedLocking) {
       ResourceMark rm;
       GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
-      for( BasicObjectLock *kptr = fr.interpreter_frame_monitor_end();
-           kptr < fr.interpreter_frame_monitor_begin();
-           kptr = fr.next_monitor_in_interpreter_frame(kptr) ) {
+      for( BasicObjectLock *kptr = last_frame.monitor_end();
+           kptr < last_frame.monitor_begin();
+           kptr = last_frame.next_monitor(kptr) ) {
         if( kptr->obj() != NULL ) {
           objects_to_revoke->append(Handle(THREAD, kptr->obj()));
         }
@@ -964,9 +974,9 @@
   UnlockFlagSaver fs(thread);
 
   assert(ProfileInterpreter, "must be profiling interpreter");
-  frame fr = thread->last_frame();
-  assert(fr.is_interpreted_frame(), "must come from interpreter");
-  methodHandle method(thread, fr.interpreter_frame_method());
+  LastFrameAccessor last_frame(thread);
+  assert(last_frame.is_interpreted_frame(), "must come from interpreter");
+  methodHandle method(thread, last_frame.method());
   Method::build_interpreter_method_data(method, THREAD);
   if (HAS_PENDING_EXCEPTION) {
     assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here");
@@ -1011,9 +1021,9 @@
   assert(ProfileInterpreter, "must be profiling interpreter");
   ResourceMark rm(thread);
   HandleMark hm(thread);
-  frame fr = thread->last_frame();
-  assert(fr.is_interpreted_frame(), "must come from interpreter");
-  MethodData* h_mdo = fr.interpreter_frame_method()->method_data();
+  LastFrameAccessor last_frame(thread);
+  assert(last_frame.is_interpreted_frame(), "must come from interpreter");
+  MethodData* h_mdo = last_frame.method()->method_data();
 
   // Grab a lock to ensure atomic access to setting the return bci and
   // the displacement.  This can block and GC, invalidating all naked oops.
@@ -1021,10 +1031,10 @@
 
   // ProfileData is essentially a wrapper around a derived oop, so we
   // need to take the lock before making any ProfileData structures.
-  ProfileData* data = h_mdo->data_at(h_mdo->dp_to_di(fr.interpreter_frame_mdp()));
+  ProfileData* data = h_mdo->data_at(h_mdo->dp_to_di(last_frame.mdp()));
   RetData* rdata = data->as_RetData();
   address new_mdp = rdata->fixup_ret(return_bci, h_mdo);
-  fr.interpreter_frame_set_mdp(new_mdp);
+  last_frame.set_mdp(new_mdp);
 IRT_END
 
 IRT_ENTRY(MethodCounters*, InterpreterRuntime::build_method_counters(JavaThread* thread, Method* m))
@@ -1049,7 +1059,8 @@
     // We are called during regular safepoints and when the VM is
     // single stepping. If any thread is marked for single stepping,
     // then we may have JVMTI work to do.
-    JvmtiExport::at_single_stepping_point(thread, method(thread), bcp(thread));
+    LastFrameAccessor last_frame(thread);
+    JvmtiExport::at_single_stepping_point(thread, last_frame.method(), last_frame.bcp());
   }
 IRT_END
 
@@ -1072,7 +1083,8 @@
   }
   InstanceKlass* cp_entry_f1 = InstanceKlass::cast(cp_entry->f1_as_klass());
   jfieldID fid = jfieldIDWorkaround::to_jfieldID(cp_entry_f1, cp_entry->f2_as_index(), is_static);
-  JvmtiExport::post_field_access(thread, method(thread), bcp(thread), cp_entry_f1, h_obj, fid);
+  LastFrameAccessor last_frame(thread);
+  JvmtiExport::post_field_access(thread, last_frame.method(), last_frame.bcp(), cp_entry_f1, h_obj, fid);
 IRT_END
 
 IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread,
@@ -1127,17 +1139,20 @@
     h_obj = Handle(thread, obj);
   }
 
-  JvmtiExport::post_raw_field_modification(thread, method(thread), bcp(thread), ik, h_obj,
+  LastFrameAccessor last_frame(thread);
+  JvmtiExport::post_raw_field_modification(thread, last_frame.method(), last_frame.bcp(), ik, h_obj,
                                            fid, sig_type, &fvalue);
 IRT_END
 
 IRT_ENTRY(void, InterpreterRuntime::post_method_entry(JavaThread *thread))
-  JvmtiExport::post_method_entry(thread, InterpreterRuntime::method(thread), InterpreterRuntime::last_frame(thread));
+  LastFrameAccessor last_frame(thread);
+  JvmtiExport::post_method_entry(thread, last_frame.method(), last_frame.get_frame());
 IRT_END
 
 
 IRT_ENTRY(void, InterpreterRuntime::post_method_exit(JavaThread *thread))
-  JvmtiExport::post_method_exit(thread, InterpreterRuntime::method(thread), InterpreterRuntime::last_frame(thread));
+  LastFrameAccessor last_frame(thread);
+  JvmtiExport::post_method_exit(thread, last_frame.method(), last_frame.get_frame());
 IRT_END
 
 IRT_LEAF(int, InterpreterRuntime::interpreter_contains(address pc))
@@ -1362,10 +1377,10 @@
   ResetNoHandleMark rnm; // In a LEAF entry.
   HandleMark hm;
   ResourceMark rm;
-  frame fr = thread->last_frame();
-  assert(fr.is_interpreted_frame(), "");
-  jint bci = fr.interpreter_frame_bci();
-  methodHandle mh(thread, fr.interpreter_frame_method());
+  LastFrameAccessor last_frame(thread);
+  assert(last_frame.is_interpreted_frame(), "");
+  jint bci = last_frame.bci();
+  methodHandle mh(thread, last_frame.method());
   Bytecode_invoke invoke(mh, bci);
   ArgumentSizeComputer asc(invoke.signature());
   int size_of_arguments = (asc.size() + (invoke.has_receiver() ? 1 : 0)); // receiver
@@ -1411,10 +1426,10 @@
 // The generated code still uses call_VM because that will set up the frame pointer for
 // bcp and method.
 IRT_LEAF(intptr_t, InterpreterRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2))
-  const frame f = thread->last_frame();
-  assert(f.is_interpreted_frame(), "must be an interpreted frame");
-  methodHandle mh(thread, f.interpreter_frame_method());
-  BytecodeTracer::trace(mh, f.interpreter_frame_bcp(), tos, tos2);
+  LastFrameAccessor last_frame(thread);
+  assert(last_frame.is_interpreted_frame(), "must be an interpreted frame");
+  methodHandle mh(thread, last_frame.method());
+  BytecodeTracer::trace(mh, last_frame.bcp(), tos, tos2);
   return preserve_this_value;
 IRT_END
 #endif // !PRODUCT
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Wed May 03 02:32:02 2017 +0000
@@ -42,29 +42,54 @@
   friend class PrintingClosure; // for method and bcp
 
  private:
-  // Helper functions to access current interpreter state
-  static frame     last_frame(JavaThread *thread)    { return thread->last_frame(); }
-  static Method*   method(JavaThread *thread)        { return last_frame(thread).interpreter_frame_method(); }
-  static address   bcp(JavaThread *thread)           { return last_frame(thread).interpreter_frame_bcp(); }
-  static int       bci(JavaThread *thread)           { return last_frame(thread).interpreter_frame_bci(); }
+  // Helper class to access current interpreter state
+  class LastFrameAccessor : public StackObj {
+    frame _last_frame;
+  public:
+    LastFrameAccessor(JavaThread* thread) {
+      assert(thread == Thread::current(), "sanity");
+      _last_frame = thread->last_frame();
+    }
+    bool is_interpreted_frame() const              { return _last_frame.is_interpreted_frame(); }
+    Method*   method() const                       { return _last_frame.interpreter_frame_method(); }
+    address   bcp() const                          { return _last_frame.interpreter_frame_bcp(); }
+    int       bci() const                          { return _last_frame.interpreter_frame_bci(); }
+    address   mdp() const                          { return _last_frame.interpreter_frame_mdp(); }
+
+    void      set_bcp(address bcp)                 { _last_frame.interpreter_frame_set_bcp(bcp); }
+    void      set_mdp(address dp)                  { _last_frame.interpreter_frame_set_mdp(dp); }
+
+    // pass method to avoid calling unsafe bcp_to_method (partial fix 4926272)
+    Bytecodes::Code code() const                   { return Bytecodes::code_at(method(), bcp()); }
+
+    Bytecode  bytecode() const                     { return Bytecode(method(), bcp()); }
+    int get_index_u1(Bytecodes::Code bc) const     { return bytecode().get_index_u1(bc); }
+    int get_index_u2(Bytecodes::Code bc) const     { return bytecode().get_index_u2(bc); }
+    int get_index_u2_cpcache(Bytecodes::Code bc) const
+                                                   { return bytecode().get_index_u2_cpcache(bc); }
+    int get_index_u4(Bytecodes::Code bc) const     { return bytecode().get_index_u4(bc); }
+    int number_of_dimensions() const               { return bcp()[3]; }
+    ConstantPoolCacheEntry* cache_entry_at(int i) const
+                                                   { return method()->constants()->cache()->entry_at(i); }
+    ConstantPoolCacheEntry* cache_entry() const    { return cache_entry_at(Bytes::get_native_u2(bcp() + 1)); }
+
+    oop callee_receiver(Symbol* signature) {
+      return _last_frame.interpreter_callee_receiver(signature);
+    }
+    BasicObjectLock* monitor_begin() const {
+      return _last_frame.interpreter_frame_monitor_end();
+    }
+    BasicObjectLock* monitor_end() const {
+      return _last_frame.interpreter_frame_monitor_begin();
+    }
+    BasicObjectLock* next_monitor(BasicObjectLock* current) const {
+      return _last_frame.next_monitor_in_interpreter_frame(current);
+    }
+
+    frame& get_frame()                             { return _last_frame; }
+  };
+
   static void      set_bcp_and_mdp(address bcp, JavaThread*thread);
-  static Bytecodes::Code code(JavaThread *thread)    {
-    // pass method to avoid calling unsafe bcp_to_method (partial fix 4926272)
-    return Bytecodes::code_at(method(thread), bcp(thread));
-  }
-  static Bytecode  bytecode(JavaThread *thread)      { return Bytecode(method(thread), bcp(thread)); }
-  static int       get_index_u1(JavaThread *thread, Bytecodes::Code bc)
-                                                        { return bytecode(thread).get_index_u1(bc); }
-  static int       get_index_u2(JavaThread *thread, Bytecodes::Code bc)
-                                                        { return bytecode(thread).get_index_u2(bc); }
-  static int       get_index_u2_cpcache(JavaThread *thread, Bytecodes::Code bc)
-                                                        { return bytecode(thread).get_index_u2_cpcache(bc); }
-  static int       get_index_u4(JavaThread *thread, Bytecodes::Code bc)
-                                                        { return bytecode(thread).get_index_u4(bc); }
-  static int       number_of_dimensions(JavaThread *thread)  { return bcp(thread)[3]; }
-
-  static ConstantPoolCacheEntry* cache_entry_at(JavaThread *thread, int i)  { return method(thread)->constants()->cache()->entry_at(i); }
-  static ConstantPoolCacheEntry* cache_entry(JavaThread *thread)            { return cache_entry_at(thread, Bytes::get_native_u2(bcp(thread) + 1)); }
   static void      note_trap_inner(JavaThread* thread, int reason,
                                    methodHandle trap_method, int trap_bci, TRAPS);
   static void      note_trap(JavaThread *thread, int reason, TRAPS);
@@ -139,7 +164,7 @@
   static void _breakpoint(JavaThread* thread, Method* method, address bcp);
   static Bytecodes::Code get_original_bytecode_at(JavaThread* thread, Method* method, address bcp);
   static void            set_original_bytecode_at(JavaThread* thread, Method* method, address bcp, Bytecodes::Code new_code);
-  static bool is_breakpoint(JavaThread *thread) { return Bytecodes::code_or_bp_at(bcp(thread)) == Bytecodes::_breakpoint; }
+  static bool is_breakpoint(JavaThread *thread) { return Bytecodes::code_or_bp_at(LastFrameAccessor(thread).bcp()) == Bytecodes::_breakpoint; }
 
   // Safepoints
   static void    at_safepoint(JavaThread* thread);
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp	Wed May 03 02:32:02 2017 +0000
@@ -150,8 +150,6 @@
     kind = CallInfo::vtable_call;
   } else if (!resolved_klass->is_interface()) {
     // A default or miranda method.  Compute the vtable index.
-    ResourceMark rm;
-    klassVtable* vt = resolved_klass->vtable();
     index = LinkResolver::vtable_index_of_interface_method(resolved_klass,
                            resolved_method);
     assert(index >= 0 , "we should have valid vtable index at this point");
@@ -163,7 +161,7 @@
 #ifdef ASSERT
     // Ensure that this is really the case.
     Klass* object_klass = SystemDictionary::Object_klass();
-    Method * object_resolved_method = object_klass->vtable()->method_at(index);
+    Method * object_resolved_method = object_klass->vtable().method_at(index);
     assert(object_resolved_method->name() == resolved_method->name(),
       "Object and interface method names should match at vtable index %d, %s != %s",
       index, object_resolved_method->name()->as_C_string(), resolved_method->name()->as_C_string());
@@ -400,9 +398,8 @@
   }
   if (vtable_index == Method::invalid_vtable_index) {
     // get vtable_index for miranda methods
-    ResourceMark rm;
-    klassVtable *vt = ik->vtable();
-    vtable_index = vt->index_of_miranda(name, signature);
+    klassVtable vt = ik->vtable();
+    vtable_index = vt.index_of_miranda(name, signature);
   }
   return vtable_index;
 }
--- a/hotspot/src/share/vm/memory/iterator.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/memory/iterator.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -65,6 +65,16 @@
  public:
   ReferenceProcessor* ref_processor() const { return _ref_processor; }
 
+  // Iteration of InstanceRefKlasses differ depending on the closure,
+  // the below enum describes the different alternatives.
+  enum ReferenceIterationMode {
+    DO_DISCOVERY, // Apply closure and discover references
+    DO_FIELDS     // Apply closure to all fields
+  };
+
+  // The default iteration mode is to do discovery.
+  virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERY; }
+
   // If the do_metadata functions return "true",
   // we invoke the following when running oop_iterate():
   //
--- a/hotspot/src/share/vm/memory/universe.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/memory/universe.cpp	Wed May 03 02:32:02 2017 +0000
@@ -526,8 +526,7 @@
 // In case those ever change we use handles for oops
 void Universe::reinitialize_vtable_of(Klass* ko, TRAPS) {
   // init vtable of k and all subclasses
-  klassVtable* vt = ko->vtable();
-  if (vt) vt->initialize_vtable(false, CHECK);
+  ko->vtable().initialize_vtable(false, CHECK);
   if (ko->is_instance_klass()) {
     for (Klass* sk = ko->subklass();
          sk != NULL;
@@ -539,7 +538,7 @@
 
 
 void initialize_itable_for_klass(Klass* k, TRAPS) {
-  InstanceKlass::cast(k)->itable()->initialize_itable(false, CHECK);
+  InstanceKlass::cast(k)->itable().initialize_itable(false, CHECK);
 }
 
 
--- a/hotspot/src/share/vm/oops/arrayKlass.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/arrayKlass.cpp	Wed May 03 02:32:02 2017 +0000
@@ -99,7 +99,7 @@
 void ArrayKlass::complete_create_array_klass(ArrayKlass* k, Klass* super_klass, ModuleEntry* module_entry, TRAPS) {
   ResourceMark rm(THREAD);
   k->initialize_supers(super_klass, CHECK);
-  k->vtable()->initialize_vtable(false, CHECK);
+  k->vtable().initialize_vtable(false, CHECK);
 
   // During bootstrapping, before java.base is defined, the module_entry may not be present yet.
   // These classes will be put on a fixup list and their module fields will be patched once
--- a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -48,8 +48,6 @@
 
   // GC specific object visitors
   //
-  // Mark Sweep
-  int  oop_ms_adjust_pointers(oop obj);
 #if INCLUDE_ALL_GCS
   // Parallel Scavenge
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed May 03 02:32:02 2017 +0000
@@ -373,8 +373,8 @@
   return !is_initialized();
 }
 
-klassItable* InstanceKlass::itable() const {
-  return new klassItable(const_cast<InstanceKlass*>(this));
+klassItable InstanceKlass::itable() const {
+  return klassItable(const_cast<InstanceKlass*>(this));
 }
 
 void InstanceKlass::eager_initialize(Thread *thread) {
@@ -621,15 +621,14 @@
       if (!(is_shared() &&
             loader_data->is_the_null_class_loader_data())) {
         ResourceMark rm(THREAD);
-        vtable()->initialize_vtable(true, CHECK_false);
-        itable()->initialize_itable(true, CHECK_false);
+        vtable().initialize_vtable(true, CHECK_false);
+        itable().initialize_itable(true, CHECK_false);
       }
 #ifdef ASSERT
       else {
-        ResourceMark rm(THREAD);
-        vtable()->verify(tty, true);
+        vtable().verify(tty, true);
         // In case itable verification is ever added.
-        // itable()->verify(tty, true);
+        // itable().verify(tty, true);
       }
 #endif
       set_init_state(linked);
@@ -807,8 +806,8 @@
   // Step 9
   if (!HAS_PENDING_EXCEPTION) {
     set_initialization_state_and_notify(fully_initialized, CHECK);
-    { ResourceMark rm(THREAD);
-      debug_only(vtable()->verify(tty, true);)
+    {
+      debug_only(vtable().verify(tty, true);)
     }
   }
   else {
@@ -2041,8 +2040,8 @@
     // vtables in the shared system dictionary, only the main one.
     // It also redefines the itable too so fix that too.
     ResourceMark rm(THREAD);
-    vtable()->initialize_vtable(false, CHECK);
-    itable()->initialize_itable(false, CHECK);
+    vtable().initialize_vtable(false, CHECK);
+    itable().initialize_itable(false, CHECK);
   }
 
   // restore constant pool resolved references
@@ -3212,10 +3211,9 @@
 
   // Verify vtables
   if (is_linked()) {
-    ResourceMark rm;
     // $$$ This used to be done only for m/s collections.  Doing it
     // always seemed a valid generalization.  (DLD -- 6/00)
-    vtable()->verify(st);
+    vtable().verify(st);
   }
 
   // Verify first subklass
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1127,7 +1127,7 @@
   }
 
   // Java itable
-  klassItable* itable() const;        // return new klassItable wrapper
+  klassItable itable() const;        // return klassItable wrapper
   Method* method_at_itable(Klass* holder, int index, TRAPS);
 
 #if INCLUDE_JVMTI
@@ -1163,8 +1163,6 @@
 
   // GC specific object visitors
   //
-  // Mark Sweep
-  int  oop_ms_adjust_pointers(oop obj);
 #if INCLUDE_ALL_GCS
   // Parallel Scavenge
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp	Wed May 03 02:32:02 2017 +0000
@@ -89,8 +89,6 @@
 
   // GC specific object visitors
   //
-  // Mark Sweep
-  int  oop_ms_adjust_pointers(oop obj);
 #if INCLUDE_ALL_GCS
   // Parallel Scavenge
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
--- a/hotspot/src/share/vm/oops/instanceRefKlass.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,8 +58,6 @@
 
   // GC specific object visitors
   //
-  // Mark Sweep
-  int  oop_ms_adjust_pointers(oop obj);
 #if INCLUDE_ALL_GCS
   // Parallel Scavenge
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
@@ -107,6 +105,30 @@
   template <bool nv, class OopClosureType>
   inline void oop_oop_iterate_ref_processing(oop obj, OopClosureType* closure);
 
+  // Building blocks for specialized handling.
+  template <bool nv, typename T, class OopClosureType, class Contains>
+  static void do_referent(oop obj, OopClosureType* closure, Contains& contains);
+
+  template <bool nv, typename T, class OopClosureType, class Contains>
+  static void do_next(oop obj, OopClosureType* closure, Contains& contains);
+
+  template <bool nv, typename T, class OopClosureType, class Contains>
+  static void do_discovered(oop obj, OopClosureType* closure, Contains& contains);
+
+  template <typename T, class OopClosureType>
+  static bool try_discover(oop obj, ReferenceType type, OopClosureType* closure);
+
+  // Do discovery while handling InstanceRefKlasses. Reference discovery
+  // is only done if the closure provides a ReferenceProcessor.
+  template <bool nv, typename T, class OopClosureType, class Contains>
+  static void oop_oop_iterate_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains);
+
+  // Apply the closure to all fields. No reference discovery is done.
+  template <bool nv, typename T, class OopClosureType, class Contains>
+  static void oop_oop_iterate_fields(oop obj, OopClosureType* closure, Contains& contains);
+
+  template <typename T>
+  static void trace_reference_gc(const char *s, oop obj, T* referent_addr, T* next_addr, T* discovered_addr) NOT_DEBUG_RETURN;
 
  public:
 
--- a/hotspot/src/share/vm/oops/instanceRefKlass.inline.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.inline.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -36,36 +36,96 @@
 #include "utilities/macros.hpp"
 
 template <bool nv, typename T, class OopClosureType, class Contains>
-void InstanceRefKlass::oop_oop_iterate_ref_processing_specialized(oop obj, OopClosureType* closure, Contains& contains) {
-  T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+void InstanceRefKlass::do_referent(oop obj, OopClosureType* closure, Contains& contains) {
+  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+  if (contains(referent_addr)) {
+    Devirtualizer<nv>::do_oop(closure, referent_addr);
+  }
+}
+
+template <bool nv, typename T, class OopClosureType, class Contains>
+void InstanceRefKlass::do_next(oop obj, OopClosureType* closure, Contains& contains) {
+  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+  if (contains(next_addr)) {
+    Devirtualizer<nv>::do_oop(closure, next_addr);
+  }
+}
+
+template <bool nv, typename T, class OopClosureType, class Contains>
+void InstanceRefKlass::do_discovered(oop obj, OopClosureType* closure, Contains& contains) {
+  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+  if (contains(discovered_addr)) {
+    Devirtualizer<nv>::do_oop(closure, discovered_addr);
+  }
+}
+
+template <typename T, class OopClosureType>
+bool InstanceRefKlass::try_discover(oop obj, ReferenceType type, OopClosureType* closure) {
+  ReferenceProcessor* rp = closure->ref_processor();
+  if (rp != NULL) {
+    T referent_oop = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::referent_addr(obj));
+    if (!oopDesc::is_null(referent_oop)) {
+      oop referent = oopDesc::decode_heap_oop_not_null(referent_oop);
+      if (!referent->is_gc_marked()) {
+        // Only try to discover if not yet marked.
+        return rp->discover_reference(obj, type);
+      }
+    }
+  }
+  return false;
+}
+
+template <bool nv, typename T, class OopClosureType, class Contains>
+void InstanceRefKlass::oop_oop_iterate_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains) {
+  log_develop_trace(gc, ref)("Process reference with discovery " PTR_FORMAT, p2i(obj));
+
+  // Special case for some closures.
   if (closure->apply_to_weak_ref_discovered_field()) {
-    Devirtualizer<nv>::do_oop(closure, disc_addr);
+    do_discovered<nv, T>(obj, closure, contains);
   }
 
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
-  T heap_oop = oopDesc::load_heap_oop(referent_addr);
-  ReferenceProcessor* rp = closure->ref_processor();
-  if (!oopDesc::is_null(heap_oop)) {
-    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
-    if (!referent->is_gc_marked() && (rp != NULL) &&
-        rp->discover_reference(obj, reference_type())) {
-      return;
-    } else if (contains(referent_addr)) {
-      // treat referent as normal oop
-      Devirtualizer<nv>::do_oop(closure, referent_addr);
-    }
+  // Try to discover reference and return if it succeeds.
+  if (try_discover<T>(obj, type, closure)) {
+    return;
   }
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
-  T next_oop  = oopDesc::load_heap_oop(next_addr);
-  // Treat discovered as normal oop, if ref is not "active" (next non-NULL)
-  if (!oopDesc::is_null(next_oop) && contains(disc_addr)) {
-    // i.e. ref is not "active"
-    log_develop_trace(gc, ref)("   Process discovered as normal " PTR_FORMAT, p2i(disc_addr));
-    Devirtualizer<nv>::do_oop(closure, disc_addr);
+
+  // Treat referent as normal oop.
+  do_referent<nv, T>(obj, closure, contains);
+
+  // Treat discovered as normal oop, if ref is not "active" (next non-NULL).
+  T next_oop  = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::next_addr(obj));
+  if (!oopDesc::is_null(next_oop)) {
+    do_discovered<nv, T>(obj, closure, contains);
   }
-  // treat next as normal oop
-  if (contains(next_addr)) {
-    Devirtualizer<nv>::do_oop(closure, next_addr);
+
+  // Treat next as normal oop.
+  do_next<nv, T>(obj, closure, contains);
+}
+
+template <bool nv, typename T, class OopClosureType, class Contains>
+void InstanceRefKlass::oop_oop_iterate_fields(oop obj, OopClosureType* closure, Contains& contains) {
+  do_referent<nv, T>(obj, closure, contains);
+  do_discovered<nv, T>(obj, closure, contains);
+  do_next<nv, T>(obj, closure, contains);
+
+  trace_reference_gc("InstanceRefKlass::oop_oop_iterate_fields()",
+                     obj,
+                     (T*)java_lang_ref_Reference::referent_addr(obj),
+                     (T*)java_lang_ref_Reference::next_addr(obj),
+                     (T*)java_lang_ref_Reference::discovered_addr(obj));
+}
+
+template <bool nv, typename T, class OopClosureType, class Contains>
+void InstanceRefKlass::oop_oop_iterate_ref_processing_specialized(oop obj, OopClosureType* closure, Contains& contains) {
+  switch (closure->reference_iteration_mode()) {
+    case ExtendedOopClosure::DO_DISCOVERY:
+      oop_oop_iterate_discovery<nv, T>(obj, reference_type(), closure, contains);
+      break;
+    case ExtendedOopClosure::DO_FIELDS:
+      oop_oop_iterate_fields<nv, T>(obj, closure, contains);
+      break;
+    default:
+      ShouldNotReachHere();
   }
 }
 
@@ -125,6 +185,19 @@
   oop_oop_iterate_ref_processing_bounded<nv>(obj, closure, mr);
 }
 
+#ifdef ASSERT
+template <typename T>
+void InstanceRefKlass::trace_reference_gc(const char *s, oop obj, T* referent_addr, T* next_addr, T* discovered_addr) {
+  log_develop_trace(gc, ref)("%s obj " PTR_FORMAT, s, p2i(obj));
+  log_develop_trace(gc, ref)("     referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
+      p2i(referent_addr), p2i(referent_addr ? (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL));
+  log_develop_trace(gc, ref)("     next_addr/* " PTR_FORMAT " / " PTR_FORMAT,
+      p2i(next_addr), p2i(next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL));
+  log_develop_trace(gc, ref)("     discovered_addr/* " PTR_FORMAT " / " PTR_FORMAT,
+      p2i(discovered_addr), p2i(discovered_addr ? (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL));
+}
+#endif
+
 // Macro to define InstanceRefKlass::oop_oop_iterate for virtual/nonvirtual for
 // all closures.  Macros calling macros above for each oop size.
 #define ALL_INSTANCE_REF_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)  \
--- a/hotspot/src/share/vm/oops/klass.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/klass.cpp	Wed May 03 02:32:02 2017 +0000
@@ -497,10 +497,12 @@
 
   // Null out class_loader_data because we don't share that yet.
   set_class_loader_data(NULL);
+  set_is_shared();
 }
 
 void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
   assert(is_klass(), "ensure C++ vtable is restored");
+  assert(is_shared(), "must be set");
   TRACE_RESTORE_ID(this);
 
   // If an exception happened during CDS restore, some of these fields may already be
@@ -696,8 +698,8 @@
   guarantee(obj->klass()->is_klass(), "klass field is not a klass");
 }
 
-klassVtable* Klass::vtable() const {
-  return new klassVtable(const_cast<Klass*>(this), start_of_vtable(), vtable_length() / vtableEntry::size());
+klassVtable Klass::vtable() const {
+  return klassVtable(const_cast<Klass*>(this), start_of_vtable(), vtable_length() / vtableEntry::size());
 }
 
 vtableEntry* Klass::start_of_vtable() const {
--- a/hotspot/src/share/vm/oops/klass.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/klass.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -399,7 +399,7 @@
 #endif
 
   // vtables
-  klassVtable* vtable() const;
+  klassVtable vtable() const;
   int vtable_length() const { return _vtable_len; }
 
   // subclass check
@@ -563,6 +563,8 @@
   void set_has_vanilla_constructor()    { _access_flags.set_has_vanilla_constructor(); }
   bool has_miranda_methods () const     { return access_flags().has_miranda_methods(); }
   void set_has_miranda_methods()        { _access_flags.set_has_miranda_methods(); }
+  bool is_shared() const                { return access_flags().is_shared_class(); } // shadows MetaspaceObj::is_shared)()
+  void set_is_shared()                  { _access_flags.set_is_shared_class(); }
 
   bool is_cloneable() const;
   void set_is_cloneable();
@@ -607,8 +609,6 @@
 
   // GC specific object visitors
   //
-  // Mark Sweep
-  virtual int  oop_ms_adjust_pointers(oop obj) = 0;
 #if INCLUDE_ALL_GCS
   // Parallel Scavenge
   virtual void oop_ps_push_contents(  oop obj, PSPromotionManager* pm)   = 0;
--- a/hotspot/src/share/vm/oops/klassVtable.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp	Wed May 03 02:32:02 2017 +0000
@@ -136,22 +136,22 @@
     // methods from super class for shared class, as that was already done
     // during archiving time. However, if Jvmti has redefined a class,
     // copy super class's vtable in case the super class has changed.
-    return super->vtable()->length();
+    return super->vtable().length();
   } else {
     // copy methods from superKlass
-    klassVtable* superVtable = super->vtable();
-    assert(superVtable->length() <= _length, "vtable too short");
+    klassVtable superVtable = super->vtable();
+    assert(superVtable.length() <= _length, "vtable too short");
 #ifdef ASSERT
-    superVtable->verify(tty, true);
+    superVtable.verify(tty, true);
 #endif
-    superVtable->copy_vtable_to(table());
+    superVtable.copy_vtable_to(table());
     if (log_develop_is_enabled(Trace, vtables)) {
       ResourceMark rm;
       log_develop_trace(vtables)("copy vtable from %s to %s size %d",
                                  super->internal_name(), klass()->internal_name(),
                                  _length);
     }
-    return superVtable->length();
+    return superVtable.length();
   }
 }
 
@@ -290,9 +290,9 @@
   InstanceKlass* superk = initialsuper;
   while (superk != NULL && superk->super() != NULL) {
     InstanceKlass* supersuperklass = InstanceKlass::cast(superk->super());
-    klassVtable* ssVtable = supersuperklass->vtable();
-    if (vtable_index < ssVtable->length()) {
-      Method* super_method = ssVtable->method_at(vtable_index);
+    klassVtable ssVtable = supersuperklass->vtable();
+    if (vtable_index < ssVtable.length()) {
+      Method* super_method = ssVtable.method_at(vtable_index);
 #ifndef PRODUCT
       Symbol* name= target_method()->name();
       Symbol* signature = target_method()->signature();
@@ -445,8 +445,8 @@
     if (is_preinitialized_vtable()) {
       // If this is a shared class, the vtable is already in the final state (fully
       // initialized). Need to look at the super's vtable.
-      klassVtable* superVtable = super->vtable();
-      super_method = superVtable->method_at(i);
+      klassVtable superVtable = super->vtable();
+      super_method = superVtable.method_at(i);
     } else {
       super_method = method_at(i);
     }
@@ -1014,15 +1014,16 @@
 void itableMethodEntry::initialize(Method* m) {
   if (m == NULL) return;
 
+#ifdef ASSERT
   if (MetaspaceShared::is_in_shared_space((void*)&_method) &&
      !MetaspaceShared::remapped_readwrite()) {
     // At runtime initialize_itable is rerun as part of link_class_impl()
     // for a shared class loaded by the non-boot loader.
     // The dumptime itable method entry should be the same as the runtime entry.
     assert(_method == m, "sanity");
-  } else {
-    _method = m;
   }
+#endif
+  _method = m;
 }
 
 klassItable::klassItable(InstanceKlass* klass) {
@@ -1249,17 +1250,6 @@
   }
 }
 
-// Update entry for specific Method*
-void klassItable::initialize_with_method(Method* m) {
-  itableMethodEntry* ime = method_entry(0);
-  for(int i = 0; i < _size_method_table; i++) {
-    if (ime->method() == m) {
-      ime->initialize(m);
-    }
-    ime++;
-  }
-}
-
 #if INCLUDE_JVMTI
 // search the itable for uses of either obsolete or EMCP methods
 void klassItable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
@@ -1488,9 +1478,9 @@
   Klass* super = _klass->super();
   if (super != NULL) {
     InstanceKlass* sk = InstanceKlass::cast(super);
-    klassVtable* vt = sk->vtable();
-    for (int i = 0; i < vt->length(); i++) {
-      verify_against(st, vt, i);
+    klassVtable vt = sk->vtable();
+    for (int i = 0; i < vt.length(); i++) {
+      verify_against(st, &vt, i);
     }
   }
 }
@@ -1557,8 +1547,7 @@
 
   static void do_class(Klass* k) {
     Klass* kl = k;
-    klassVtable* vt = kl->vtable();
-    if (vt == NULL) return;
+    klassVtable vt = kl->vtable();
     no_klasses++;
     if (kl->is_instance_klass()) {
       no_instance_klasses++;
@@ -1566,9 +1555,9 @@
     }
     if (kl->is_array_klass()) {
       no_array_klasses++;
-      sum_of_array_vtable_len += vt->length();
+      sum_of_array_vtable_len += vt.length();
     }
-    sum_of_vtable_len += vt->length();
+    sum_of_vtable_len += vt.length();
   }
 
   static void compute() {
--- a/hotspot/src/share/vm/oops/klassVtable.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/klassVtable.hpp	Wed May 03 02:32:02 2017 +0000
@@ -41,7 +41,7 @@
 
 class vtableEntry;
 
-class klassVtable : public ResourceObj {
+class klassVtable VALUE_OBJ_CLASS_SPEC {
   Klass*       _klass;            // my klass
   int          _tableOffset;      // offset of start of vtable data within klass
   int          _length;           // length of vtable (number of entries)
@@ -288,7 +288,7 @@
 //    -- vtable for interface 2 ---
 //    ...
 //
-class klassItable : public ResourceObj {
+class klassItable VALUE_OBJ_CLASS_SPEC {
  private:
   InstanceKlass*       _klass;             // my klass
   int                  _table_offset;      // offset of start of itable data within klass (in words)
@@ -310,9 +310,6 @@
   // Initialization
   void initialize_itable(bool checkconstraints, TRAPS);
 
-  // Updates
-  void initialize_with_method(Method* m);
-
 #if INCLUDE_JVMTI
   // RedefineClasses() API support:
   // if any entry of this itable points to any of old_methods,
--- a/hotspot/src/share/vm/oops/method.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/method.cpp	Wed May 03 02:32:02 2017 +0000
@@ -1191,7 +1191,6 @@
   }
 
   assert(ik->is_subclass_of(method_holder()), "should be subklass");
-  assert(ik->vtable() != NULL, "vtable should exist");
   if (!has_vtable_index()) {
     return false;
   } else {
--- a/hotspot/src/share/vm/oops/objArrayKlass.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/objArrayKlass.hpp	Wed May 03 02:32:02 2017 +0000
@@ -112,8 +112,6 @@
 
   // GC specific object visitors
   //
-  // Mark Sweep
-  int  oop_ms_adjust_pointers(oop obj);
 #if INCLUDE_ALL_GCS
   // Parallel Scavenge
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
--- a/hotspot/src/share/vm/oops/oop.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/oop.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -325,10 +325,6 @@
 
   // Garbage Collection support
 
-  // Mark Sweep
-  // Adjust all pointers in this object to point at it's forwarded location and
-  // return the size of this oop. This is used by the MarkSweep collector.
-  inline int  ms_adjust_pointers();
 #if INCLUDE_ALL_GCS
   // Parallel Compact
   inline void pc_follow_contents(ParCompactionManager* cm);
--- a/hotspot/src/share/vm/oops/oop.inline.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -664,13 +664,6 @@
   }
 }
 
-int oopDesc::ms_adjust_pointers() {
-  debug_only(int check_size = size());
-  int s = klass()->oop_ms_adjust_pointers(this);
-  assert(s == check_size, "should be the same");
-  return s;
-}
-
 #if INCLUDE_ALL_GCS
 void oopDesc::pc_follow_contents(ParCompactionManager* cm) {
   klass()->oop_pc_follow_contents(this, cm);
--- a/hotspot/src/share/vm/oops/typeArrayKlass.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -74,8 +74,6 @@
 
   // GC specific object visitors
   //
-  // Mark Sweep
-  int  oop_ms_adjust_pointers(oop obj);
 #if INCLUDE_ALL_GCS
   // Parallel Scavenge
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Wed May 03 02:32:02 2017 +0000
@@ -3272,7 +3272,7 @@
   // If the class being redefined is java.lang.Object, we need to fix all
   // array class vtables also
   if (k->is_array_klass() && _the_class == SystemDictionary::Object_klass()) {
-    k->vtable()->adjust_method_entries(the_class, &trace_name_printed);
+    k->vtable().adjust_method_entries(the_class, &trace_name_printed);
 
   } else if (k->is_instance_klass()) {
     HandleMark hm(_thread);
@@ -3315,7 +3315,7 @@
       // ik->vtable() creates a wrapper object; rm cleans it up
       ResourceMark rm(_thread);
 
-      ik->vtable()->adjust_method_entries(the_class, &trace_name_printed);
+      ik->vtable().adjust_method_entries(the_class, &trace_name_printed);
       ik->adjust_default_methods(the_class, &trace_name_printed);
     }
 
@@ -3329,10 +3329,8 @@
     if (ik->itable_length() > 0 && (_the_class->is_interface()
         || _the_class == SystemDictionary::internal_Unsafe_klass()
         || ik->is_subclass_of(_the_class))) {
-      // ik->itable() creates a wrapper object; rm cleans it up
       ResourceMark rm(_thread);
-
-      ik->itable()->adjust_method_entries(the_class, &trace_name_printed);
+      ik->itable().adjust_method_entries(the_class, &trace_name_printed);
     }
 
     // The constant pools in other classes (other_cp) can refer to
@@ -3957,8 +3955,8 @@
     // compare_and_normalize_class_versions has already checked:
     //  - classloaders unchanged, signatures unchanged
     //  - all instanceKlasses for redefined classes reused & contents updated
-    the_class->vtable()->initialize_vtable(false, THREAD);
-    the_class->itable()->initialize_itable(false, THREAD);
+    the_class->vtable().initialize_vtable(false, THREAD);
+    the_class->itable().initialize_itable(false, THREAD);
     assert(!HAS_PENDING_EXCEPTION || (THREAD->pending_exception()->is_a(SystemDictionary::ThreadDeath_klass())), "redefine exception");
   }
 
@@ -4093,12 +4091,12 @@
   // a vtable should never contain old or obsolete methods
   ResourceMark rm(_thread);
   if (k->vtable_length() > 0 &&
-      !k->vtable()->check_no_old_or_obsolete_entries()) {
+      !k->vtable().check_no_old_or_obsolete_entries()) {
     if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
       log_trace(redefine, class, obsolete, metadata)
         ("klassVtable::check_no_old_or_obsolete_entries failure -- OLD or OBSOLETE method found -- class: %s",
          k->signature_name());
-      k->vtable()->dump_vtable();
+      k->vtable().dump_vtable();
     }
     no_old_methods = false;
   }
@@ -4109,12 +4107,12 @@
 
     // an itable should never contain old or obsolete methods
     if (ik->itable_length() > 0 &&
-        !ik->itable()->check_no_old_or_obsolete_entries()) {
+        !ik->itable().check_no_old_or_obsolete_entries()) {
       if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
         log_trace(redefine, class, obsolete, metadata)
           ("klassItable::check_no_old_or_obsolete_entries failure -- OLD or OBSOLETE method found -- class: %s",
            ik->signature_name());
-        ik->itable()->dump_itable();
+        ik->itable().dump_itable();
       }
       no_old_methods = false;
     }
--- a/hotspot/src/share/vm/prims/methodHandles.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp	Wed May 03 02:32:02 2017 +0000
@@ -218,7 +218,7 @@
         m_klass_non_interface = SystemDictionary::Object_klass();
 #ifdef ASSERT
         { ResourceMark rm;
-          Method* m2 = m_klass_non_interface->vtable()->method_at(vmindex);
+          Method* m2 = m_klass_non_interface->vtable().method_at(vmindex);
           assert(m->name() == m2->name() && m->signature() == m2->signature(),
                  "at %d, %s != %s", vmindex,
                  m->name_and_sig_as_C_string(), m2->name_and_sig_as_C_string());
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsCompiler.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsCompiler.cpp	Wed May 03 02:32:02 2017 +0000
@@ -289,10 +289,10 @@
 }
 
 Flag::Error ArraycopyDstPrefetchDistanceConstraintFunc(uintx value, bool verbose) {
-  if (value != 0) {
+  if (value >= 4032) {
     CommandLineError::print(verbose,
-                            "ArraycopyDstPrefetchDistance (" UINTX_FORMAT ") must be 0\n",
-                            value);
+                            "ArraycopyDstPrefetchDistance (" UINTX_FORMAT ") must be"
+                            "between 0 and 4031\n", value);
     return Flag::VIOLATES_CONSTRAINT;
   }
 
@@ -300,10 +300,10 @@
 }
 
 Flag::Error ArraycopySrcPrefetchDistanceConstraintFunc(uintx value, bool verbose) {
-  if (value != 0) {
+  if (value >= 4032) {
     CommandLineError::print(verbose,
-                            "ArraycopySrcPrefetchDistance (" UINTX_FORMAT ") must be 0\n",
-                            value);
+                            "ArraycopySrcPrefetchDistance (" UINTX_FORMAT ") must be"
+                            "between 0 and 4031\n", value);
     return Flag::VIOLATES_CONSTRAINT;
   }
 
--- a/hotspot/src/share/vm/runtime/globals.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/runtime/globals.cpp	Wed May 03 02:32:02 2017 +0000
@@ -865,16 +865,15 @@
 Flag* Flag::flags = flagTable;
 size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag));
 
-inline bool str_equal(const char* s, const char* q, size_t len) {
-  // s is null terminated, q is not!
-  if (strlen(s) != (unsigned int) len) return false;
-  return strncmp(s, q, len) == 0;
+inline bool str_equal(const char* s, size_t s_len, const char* q, size_t q_len) {
+  if (s_len != q_len) return false;
+  return memcmp(s, q, q_len) == 0;
 }
 
 // Search the flag table for a named flag
 Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) {
   for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
-    if (str_equal(current->_name, name, length)) {
+    if (str_equal(current->_name, current->get_name_length(), name, length)) {
       // Found a matching entry.
       // Don't report notproduct and develop flags in product builds.
       if (current->is_constant_in_binary()) {
@@ -895,6 +894,14 @@
   return NULL;
 }
 
+// Get or compute the flag name length
+size_t Flag::get_name_length() {
+  if (_name_len == 0) {
+    _name_len = strlen(_name);
+  }
+  return _name_len;
+}
+
 // Compute string similarity based on Dice's coefficient
 static float str_similar(const char* str1, const char* str2, size_t len2) {
   int len1 = (int) strlen(str1);
--- a/hotspot/src/share/vm/runtime/globals.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Wed May 03 02:32:02 2017 +0000
@@ -186,6 +186,7 @@
   void* _addr;
   NOT_PRODUCT(const char* _doc;)
   Flags _flags;
+  size_t _name_len;
 
   // points to all Flags static array
   static Flag* flags;
@@ -247,6 +248,8 @@
   Flags get_origin();
   void set_origin(Flags origin);
 
+  size_t get_name_length();
+
   bool is_default();
   bool is_ergonomic();
   bool is_command_line();
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Wed May 03 02:32:02 2017 +0000
@@ -199,6 +199,7 @@
 typedef HashtableEntry<InstanceKlass*, mtClass>  KlassHashtableEntry;
 typedef TwoOopHashtable<Symbol*, mtClass>     SymbolTwoOopHashtable;
 typedef CompactHashtable<Symbol*, char>       SymbolCompactHashTable;
+typedef RehashableHashtable<Symbol*, mtSymbol>   RehashableSymbolHashtable;
 
 //--------------------------------------------------------------------------------
 // VM_STRUCTS
@@ -584,6 +585,7 @@
                                                                                                                                      \
      static_field(SymbolTable,                 _the_table,                                    SymbolTable*)                          \
      static_field(SymbolTable,                 _shared_table,                                 SymbolCompactHashTable)                \
+     static_field(RehashableSymbolHashtable,   _seed,                                         juint)                                 \
                                                                                                                                      \
   /***************/                                                                                                                  \
   /* StringTable */                                                                                                                  \
@@ -1602,6 +1604,8 @@
                                                                           \
   declare_toplevel_type(BasicHashtable<mtInternal>)                       \
     declare_type(IntptrHashtable, BasicHashtable<mtInternal>)             \
+  declare_toplevel_type(BasicHashtable<mtSymbol>)                         \
+    declare_type(RehashableSymbolHashtable, BasicHashtable<mtSymbol>)     \
   declare_type(SymbolTable, SymbolHashtable)                              \
   declare_type(StringTable, StringHashtable)                              \
     declare_type(LoaderConstraintTable, KlassHashtable)                   \
--- a/hotspot/src/share/vm/utilities/accessFlags.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/utilities/accessFlags.hpp	Wed May 03 02:32:02 2017 +0000
@@ -64,6 +64,7 @@
   JVM_ACC_HAS_FINALIZER           = 0x40000000,     // True if klass has a non-empty finalize() method
   JVM_ACC_IS_CLONEABLE_FAST       = (int)0x80000000,// True if klass implements the Cloneable interface and can be optimized in generated code
   JVM_ACC_HAS_FINAL_METHOD        = 0x01000000,     // True if klass has final method
+  JVM_ACC_IS_SHARED_CLASS         = 0x02000000,     // True if klass is shared
 
   // Klass* and Method* flags
   JVM_ACC_HAS_LOCAL_VARIABLE_TABLE= 0x00200000,
@@ -146,6 +147,8 @@
   bool has_finalizer           () const { return (_flags & JVM_ACC_HAS_FINALIZER          ) != 0; }
   bool has_final_method        () const { return (_flags & JVM_ACC_HAS_FINAL_METHOD       ) != 0; }
   bool is_cloneable_fast       () const { return (_flags & JVM_ACC_IS_CLONEABLE_FAST      ) != 0; }
+  bool is_shared_class         () const { return (_flags & JVM_ACC_IS_SHARED_CLASS        ) != 0; }
+
   // Klass* and Method* flags
   bool has_localvariable_table () const { return (_flags & JVM_ACC_HAS_LOCAL_VARIABLE_TABLE) != 0; }
   void set_has_localvariable_table()    { atomic_set_bits(JVM_ACC_HAS_LOCAL_VARIABLE_TABLE); }
@@ -216,6 +219,7 @@
   void set_has_final_method()          { atomic_set_bits(JVM_ACC_HAS_FINAL_METHOD);        }
   void set_is_cloneable_fast()         { atomic_set_bits(JVM_ACC_IS_CLONEABLE_FAST);       }
   void set_has_miranda_methods()       { atomic_set_bits(JVM_ACC_HAS_MIRANDA_METHODS);     }
+  void set_is_shared_class()           { atomic_set_bits(JVM_ACC_IS_SHARED_CLASS);         }
 
  public:
   // field flags
--- a/hotspot/src/share/vm/utilities/debug.cpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/utilities/debug.cpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -490,7 +490,7 @@
 extern "C" void dump_vtable(address p) {
   Command c("dump_vtable");
   Klass* k = (Klass*)p;
-  k->vtable()->print();
+  k->vtable().print();
 }
 
 
--- a/hotspot/src/share/vm/utilities/hashtable.hpp	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/src/share/vm/utilities/hashtable.hpp	Wed May 03 02:32:02 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -294,6 +294,7 @@
 };
 
 template <class T, MEMFLAGS F> class RehashableHashtable : public Hashtable<T, F> {
+ friend class VMStructs;
  protected:
 
   enum {
--- a/hotspot/test/ProblemList.txt	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/ProblemList.txt	Wed May 03 02:32:02 2017 +0000
@@ -113,6 +113,7 @@
 gc/g1/humongousObjects/objectGraphTest/TestObjectGraphAfterGC.java 8156755 generic-all
 gc/survivorAlignment/TestPromotionToSurvivor.java 8129886 generic-all
 gc/g1/logging/TestG1LoggingFailure.java 8169634 generic-all
+gc/g1/humongousObjects/TestHeapCounters.java 8178918 generic-all
 
 #############################################################################
 
@@ -121,7 +122,6 @@
 runtime/CompressedOops/UseCompressedOops.java 8079353 generic-all
 # This test is disabled since it will stress NMT and timeout during normal testing
 runtime/NMT/MallocStressTest.java 8166548 generic-all
-runtime/SharedArchiveFile/BootAppendTests.java 8150683 generic-all
 runtime/SharedArchiveFile/DefaultUseWithClient.java 8154204 generic-all
 
 #############################################################################
--- a/hotspot/test/runtime/SharedArchiveFile/ArchiveDoesNotExist.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/ArchiveDoesNotExist.java	Wed May 03 02:32:02 2017 +0000
@@ -27,6 +27,7 @@
  *          attempting to use CDS archive. JVM should exit gracefully
  *          when sharing mode is ON, and continue w/o sharing if sharing
  *          mode is AUTO.
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/runtime/SharedArchiveFile/BootAppendTests.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/BootAppendTests.java	Wed May 03 02:32:02 2017 +0000
@@ -24,6 +24,7 @@
 /**
  * @test
  * @summary Testing -Xbootclasspath/a support for CDS
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
@@ -73,7 +74,7 @@
         logTestCase("1");
         testBootAppendModuleClass();
 
-        log("TESTCASE: 2");
+        logTestCase("2");
         testBootAppendDuplicateModuleClass();
 
         logTestCase("3");
@@ -123,11 +124,11 @@
         for (String mode : modes) {
             CDSOptions opts = (new CDSOptions())
                 .setXShareMode(mode).setUseVersion(false)
-                .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar)
+                .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar, "-showversion")
                 .addSuffix(APP_CLASS, BOOT_APPEND_MODULE_CLASS_NAME);
 
-            CDSTestUtils.runWithArchive(opts)
-                .shouldContain("java.lang.ClassNotFoundException: javax.sound.sampled.MyClass");
+            OutputAnalyzer out = CDSTestUtils.runWithArchive(opts);
+            CDSTestUtils.checkExec(out, opts, "java.lang.ClassNotFoundException: javax.sound.sampled.MyClass");
         }
     }
 
@@ -144,11 +145,13 @@
         for (String mode : modes) {
             CDSOptions opts = (new CDSOptions())
                 .setXShareMode(mode).setUseVersion(false)
-                .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar)
-                .addSuffix(APP_CLASS, BOOT_APPEND_DUPLICATE_MODULE_CLASS_NAME);
+                .addPrefix("--add-modules", "java.corba", "-showversion",
+                           "-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar)
+                .addSuffix("-Xlog:class+load=info",
+                           APP_CLASS, BOOT_APPEND_DUPLICATE_MODULE_CLASS_NAME);
 
-            CDSTestUtils.runWithArchive(opts)
-                .shouldContain("[class,load] org.omg.CORBA.Context source: jrt:/java.corba");
+            OutputAnalyzer out = CDSTestUtils.runWithArchive(opts);
+            CDSTestUtils.checkExec(out, opts, "[class,load] org.omg.CORBA.Context source: jrt:/java.corba");
         }
     }
 
@@ -164,17 +167,17 @@
         for (String mode : modes) {
             CDSOptions opts = (new CDSOptions())
                 .setXShareMode(mode).setUseVersion(false)
-                .addPrefix("-Xbootclasspath/a:" + bootAppendJar,
+                .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-showversion",
                            "--limit-modules=java.base", "-cp", appJar)
                 .addSuffix("-Xlog:class+load=info",
                            APP_CLASS, BOOT_APPEND_MODULE_CLASS_NAME);
 
-            OutputAnalyzer out = CDSTestUtils.runWithArchive(opts)
-                .shouldContain("[class,load] javax.sound.sampled.MyClass");
+            OutputAnalyzer out = CDSTestUtils.runWithArchive(opts);
+            CDSTestUtils.checkExec(out, opts, "[class,load] javax.sound.sampled.MyClass");
 
             // When CDS is enabled, the shared class should be loaded from the archive.
             if (mode.equals("on")) {
-                out.shouldContain("[class,load] javax.sound.sampled.MyClass source: shared objects file");
+                CDSTestUtils.checkExec(out, opts, "[class,load] javax.sound.sampled.MyClass source: shared objects file");
             }
         }
     }
@@ -193,14 +196,16 @@
         for (String mode : modes) {
             CDSOptions opts = (new CDSOptions())
                 .setXShareMode(mode).setUseVersion(false)
-                .addPrefix("-Xbootclasspath/a:" + bootAppendJar,
+                .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-showversion",
                            "--limit-modules=java.base", "-cp", appJar)
                 .addSuffix("-Xlog:class+load=info",
                            APP_CLASS, BOOT_APPEND_DUPLICATE_MODULE_CLASS_NAME);
 
-            CDSTestUtils.runWithArchive(opts)
-                .shouldContain("[class,load] org.omg.CORBA.Context")
-                .shouldMatch(".*\\[class,load\\] org.omg.CORBA.Context source:.*bootAppend.jar");
+            OutputAnalyzer out = CDSTestUtils.runWithArchive(opts);
+            CDSTestUtils.checkExec(out, opts, "[class,load] org.omg.CORBA.Context");
+            if (!CDSTestUtils.isUnableToMap(out)) {
+                out.shouldMatch(".*\\[class,load\\] org.omg.CORBA.Context source:.*bootAppend.jar");
+            }
         }
     }
 
@@ -215,18 +220,18 @@
         for (String mode : modes) {
             CDSOptions opts = (new CDSOptions())
                 .setXShareMode(mode).setUseVersion(false)
-                .addPrefix("-Xbootclasspath/a:" + bootAppendJar,
+                .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-showversion",
                            "--limit-modules=java.base", "-cp", appJar)
                 .addSuffix("-Xlog:class+load=info",
                            APP_CLASS, BOOT_APPEND_CLASS_NAME);
 
-            OutputAnalyzer out = CDSTestUtils.runWithArchive(opts)
-                .shouldContain("[class,load] nonjdk.myPackage.MyClass");
+            OutputAnalyzer out = CDSTestUtils.runWithArchive(opts);
+            CDSTestUtils.checkExec(out, opts, "[class,load] nonjdk.myPackage.MyClass");
 
             // If CDS is enabled, the nonjdk.myPackage.MyClass should be loaded
             // from the shared archive.
             if (mode.equals("on")) {
-                out.shouldContain(
+                CDSTestUtils.checkExec(out, opts,
                     "[class,load] nonjdk.myPackage.MyClass source: shared objects file");
             }
         }
--- a/hotspot/test/runtime/SharedArchiveFile/CdsDifferentCompactStrings.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/CdsDifferentCompactStrings.java	Wed May 03 02:32:02 2017 +0000
@@ -25,6 +25,7 @@
  * @test CdsDifferentCompactStrings
  * @summary CDS (class data sharing) requires the same -XX:[+-]CompactStrings
  *          setting between archive creation time and load time.
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java	Wed May 03 02:32:02 2017 +0000
@@ -28,6 +28,7 @@
  *          This is a negative test; using  object alignment for loading that
  *          is different from object alignment for creating a CDS file
  *          should fail when loading.
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
  * @library /test/lib
  * @bug 8025642
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java	Wed May 03 02:32:02 2017 +0000
@@ -25,6 +25,7 @@
  * @test CdsSameObjectAlignment
  * @summary Testing CDS (class data sharing) using varying object alignment.
  *          Using same object alignment for each dump/load pair
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/runtime/SharedArchiveFile/DefaultUseWithClient.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/DefaultUseWithClient.java	Wed May 03 02:32:02 2017 +0000
@@ -24,6 +24,7 @@
 /*
  * @test DefaultUseWithClient
  * @summary Test default behavior of sharing with -client
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/runtime/SharedArchiveFile/LargeSharedSpace.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/LargeSharedSpace.java	Wed May 03 02:32:02 2017 +0000
@@ -26,6 +26,7 @@
  * @bug 8168790 8169870
  * @summary Test CDS dumping using specific space size without crashing.
  * The space size used in the test might not be suitable on windows.
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
  * @requires (os.family != "windows")
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java	Wed May 03 02:32:02 2017 +0000
@@ -23,6 +23,7 @@
 
 /* @test LimitSharedSizes
  * @summary Test handling of limits on shared space size
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
  * @library /test/lib /runtime/CommandLine/OptionsValidation/common
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/runtime/SharedArchiveFile/PrintSharedArchiveAndExit.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/PrintSharedArchiveAndExit.java	Wed May 03 02:32:02 2017 +0000
@@ -25,6 +25,7 @@
  * @test
  * @bug 8066670
  * @summary Testing -XX:+PrintSharedArchiveAndExit option
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTest.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTest.java	Wed May 03 02:32:02 2017 +0000
@@ -24,6 +24,7 @@
 /*
  * @test SASymbolTableTest
  * @summary Walk symbol table using SA, with and without CDS.
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          jdk.hotspot.agent/sun.jvm.hotspot.oops
--- a/hotspot/test/runtime/SharedArchiveFile/SharedArchiveFile.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/SharedArchiveFile.java	Wed May 03 02:32:02 2017 +0000
@@ -25,6 +25,7 @@
  * @test
  * @bug 8014138
  * @summary Testing new -XX:SharedArchiveFile=<file-name> option
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
@@ -40,14 +41,14 @@
 // methods to form command line to create/use shared archive.
 public class SharedArchiveFile {
     public static void main(String[] args) throws Exception {
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true,
                                 "-XX:+UnlockDiagnosticVMOptions",
                                 "-XX:SharedArchiveFile=./SharedArchiveFile.jsa",
                                 "-Xshare:dump");
         OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "SharedArchiveFile");
         CDSTestUtils.checkDump(out);
 
-        pb = ProcessTools.createJavaProcessBuilder(
+        pb = ProcessTools.createJavaProcessBuilder(true,
                               "-XX:+UnlockDiagnosticVMOptions",
                               "-XX:SharedArchiveFile=./SharedArchiveFile.jsa",
                               "-Xshare:on", "-version");
--- a/hotspot/test/runtime/SharedArchiveFile/SharedBaseAddress.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/SharedBaseAddress.java	Wed May 03 02:32:02 2017 +0000
@@ -25,6 +25,7 @@
  * @test SharedBaseAddress
  * @summary Test variety of values for SharedBaseAddress, making sure
  *          VM handles normal values as well as edge values w/o a crash.
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java	Wed May 03 02:32:02 2017 +0000
@@ -25,6 +25,7 @@
  * @test
  * @bug 8059510
  * @summary Test SharedSymbolTableBucketSize option
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/runtime/SharedArchiveFile/SpaceUtilizationCheck.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/SpaceUtilizationCheck.java	Wed May 03 02:32:02 2017 +0000
@@ -24,6 +24,7 @@
 /*
  * @test SpaceUtilizationCheck
  * @summary Check if the space utilization for shared spaces is adequate
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/runtime/SharedArchiveFile/TestInterpreterMethodEntries.java	Tue May 02 19:27:26 2017 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/TestInterpreterMethodEntries.java	Wed May 03 02:32:02 2017 +0000
@@ -26,6 +26,7 @@
  * @bug 8169711
  * @summary Test interpreter method entries for intrinsics with CDS (class data sharing)
  *          and different settings of the intrinsic flag during dump/use of the archive.
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management