Merge
authoramurillo
Thu, 01 Sep 2016 15:20:56 -0700
changeset 40908 65befc5d3ed1
parent 40906 bd1ac56ce258 (diff)
parent 40907 af3969007060 (current diff)
child 40910 5411aa046af7
Merge
--- a/hotspot/make/symbols/symbols-unix	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/make/symbols/symbols-unix	Thu Sep 01 15:20:56 2016 -0700
@@ -67,6 +67,7 @@
 JVM_FreeMemory
 JVM_GC
 JVM_GetAllThreads
+JVM_GetAndClearReferencePendingList
 JVM_GetArrayElement
 JVM_GetArrayLength
 JVM_GetCallerClass
@@ -130,6 +131,7 @@
 JVM_GetTemporaryDirectory
 JVM_GetVmArguments
 JVM_Halt
+JVM_HasReferencePendingList
 JVM_HoldsLock
 JVM_IHashCode
 JVM_InitProperties
@@ -179,6 +181,7 @@
 JVM_ToStackTraceElement
 JVM_TotalMemory
 JVM_UnloadLibrary
+JVM_WaitForReferencePendingList
 JVM_Yield
 
 # Module related API's
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/MethodData.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/MethodData.java	Thu Sep 01 15:20:56 2016 -0700
@@ -36,6 +36,7 @@
 public class MethodData extends Metadata implements MethodDataInterface<Klass,Method> {
   static int TypeProfileWidth = 2;
   static int BciProfileWidth = 2;
+  static int MethodProfileWidth = 0;
   static int CompileThreshold;
 
   static int Reason_many;                 // indicates presence of several reasons
@@ -142,6 +143,8 @@
         TypeProfileWidth = (int)flag.getIntx();
       } else if (flag.getName().equals("BciProfileWidth")) {
         BciProfileWidth = (int)flag.getIntx();
+      } else if (flag.getName().equals("MethodProfileWidth")) {
+        MethodProfileWidth = (int)flag.getIntx();
       } else if (flag.getName().equals("CompileThreshold")) {
         CompileThreshold = (int)flag.getIntx();
       }
@@ -154,7 +157,7 @@
 
     parametersTypeDataDi = new CIntField(type.getCIntegerField("_parameters_type_data_di"), 0);
 
-    sizeofMethodDataOopDesc = (int)type.getSize();;
+    sizeofMethodDataOopDesc = (int)type.getSize();
 
     Reason_many            = db.lookupIntConstant("Deoptimization::Reason_many").intValue();
     Reason_none            = db.lookupIntConstant("Deoptimization::Reason_none").intValue();
@@ -257,7 +260,7 @@
 
   ParametersTypeData<Klass,Method> parametersTypeData() {
     int di = (int)parametersTypeDataDi.getValue(getAddress());
-    if (di == -1) {
+    if (di == -1 || di == -2) {
       return null;
     }
     DataLayout dataLayout = new DataLayout(this, di + (int)data.getOffset());
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java	Thu Sep 01 15:20:56 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,9 +38,21 @@
 // that the check is reached, and a series of (Klass, count) pairs
 // which are used to store a type profile for the receiver of the check.
 public class ReceiverTypeData<K,M> extends CounterData {
-  static final int   receiver0Offset = counterCellCount;
-  static final int     count0Offset = receiver0Offset + 1;
-  static final int     receiverTypeRowCellCount = (count0Offset + 1) - receiver0Offset;
+  static final int INCLUDE_JVMCI;
+  static final int nonProfiledCountOffset = counterCellCount;
+  static final int receiver0Offset;
+  static final int count0Offset;
+  static final int receiverTypeRowCellCount;
+  static {
+    INCLUDE_JVMCI = VM.getVM().getTypeDataBase().lookupIntConstant("INCLUDE_JVMCI");
+    if (INCLUDE_JVMCI == 1) {
+        receiver0Offset = nonProfiledCountOffset + 1;
+    } else {
+        receiver0Offset = counterCellCount;
+    }
+    count0Offset = receiver0Offset + 1;
+    receiverTypeRowCellCount = (count0Offset + 1) - receiver0Offset;
+  }
   final MethodDataInterface<K,M> methodData;
 
   public ReceiverTypeData(MethodDataInterface<K,M> methodData, DataLayout layout) {
@@ -53,7 +65,11 @@
   boolean isReceivertypedata() { return true; }
 
   static int staticCellCount() {
-    return counterCellCount + MethodData.TypeProfileWidth * receiverTypeRowCellCount;
+    int cellCount = counterCellCount + MethodData.TypeProfileWidth * receiverTypeRowCellCount;
+    if (INCLUDE_JVMCI == 1) {
+      cellCount += 1;
+    }
+    return cellCount;
   }
 
   public int cellCount() {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java	Thu Sep 01 15:20:56 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,7 +44,11 @@
   static int staticCellCount() {
     // At this point we could add more profile state, e.g., for arguments.
     // But for now it's the same size as the base record type.
-    return ReceiverTypeData.staticCellCount();
+    int cellCount = ReceiverTypeData.staticCellCount();
+    if (INCLUDE_JVMCI == 1) {
+      cellCount += MethodData.MethodProfileWidth * receiverTypeRowCellCount;
+    }
+    return cellCount;
   }
 
   public int cellCount() {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java	Thu Sep 01 15:20:56 2016 -0700
@@ -129,8 +129,6 @@
             virtualConstructor.addMapping("CompilerThread", CompilerThread.class);
             virtualConstructor.addMapping("CodeCacheSweeperThread", CodeCacheSweeperThread.class);
         }
-        // for now, use JavaThread itself. fix it later with appropriate class if needed
-        virtualConstructor.addMapping("ReferencePendingListLockerThread", JavaThread.class);
         virtualConstructor.addMapping("JvmtiAgentThread", JvmtiAgentThread.class);
         virtualConstructor.addMapping("ServiceThread", ServiceThread.class);
     }
@@ -172,7 +170,7 @@
             return thread;
         } catch (Exception e) {
             throw new RuntimeException("Unable to deduce type of thread from address " + threadAddr +
-            " (expected type JavaThread, CompilerThread, ServiceThread, JvmtiAgentThread, ReferencePendingListLockerThread, or CodeCacheSweeperThread)", e);
+            " (expected type JavaThread, CompilerThread, ServiceThread, JvmtiAgentThread or CodeCacheSweeperThread)", e);
         }
     }
 
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/sa.js	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/sa.js	Thu Sep 01 15:20:56 2016 -0700
@@ -837,7 +837,6 @@
 vmType2Class["JavaThread"] = sapkg.runtime.JavaThread;
 vmType2Class["CompilerThread"] = sapkg.runtime.CompilerThread;
 vmType2Class["CodeCacheSweeperThread"] = sapkg.runtime.CodeCacheSweeperThread;
-vmType2Class["ReferencePendingListLockerThread"] = sapkg.runtime.JavaThread;
 vmType2Class["DebuggerThread"] = sapkg.runtime.DebuggerThread;
 
 // gc
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Thu Sep 01 15:20:56 2016 -0700
@@ -244,17 +244,21 @@
     native void resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int cpi);
 
     /**
-     * Ensures that the type referenced by the entry for a
+     * If {@code cpi} denotes an entry representing a
      * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">signature
-     * polymorphic</a> method at index {@code cpi} in {@code constantPool} is loaded and
-     * initialized.
-     *
-     * The behavior of this method is undefined if {@code cpi} does not denote an entry representing
-     * a signature polymorphic method.
+     * polymorphic</a> method, this method ensures that the type referenced by the entry is loaded
+     * and initialized. It {@code cpi} does not denote a signature polymorphic method, this method
+     * does nothing.
      */
     native void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi);
 
     /**
+     * Gets the list of type names (in the format of {@link JavaType#getName()}) denoting the
+     * classes that define signature polymorphic methods.
+     */
+    native String[] getSignaturePolymorphicHolders();
+
+    /**
      * Gets the resolved type denoted by the entry at index {@code cpi} in {@code constantPool}.
      *
      * The behavior of this method is undefined if {@code cpi} does not denote an entry representing
@@ -348,6 +352,7 @@
      *         [String name, Long value, ...] vmConstants,
      *         [String name, Long value, ...] vmAddresses,
      *         VMFlag[] vmFlags
+     *         VMIntrinsicMethod[] vmIntrinsics
      *     ]
      * </pre>
      *
@@ -610,4 +615,5 @@
      * @return the number of bytes required for deoptimization of this frame state
      */
     native int interpreterFrameSize(BytecodeFrame frame);
+
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java	Thu Sep 01 15:20:56 2016 -0700
@@ -282,7 +282,7 @@
      * @return constant pool tag
      */
     private JVM_CONSTANT getTagAt(int index) {
-        assertBounds(index);
+        assert checkBounds(index);
         HotSpotVMConfig config = config();
         final long metaspaceConstantPoolTags = UNSAFE.getAddress(getMetaspaceConstantPool() + config.constantPoolTagsOffset);
         final int tag = UNSAFE.getByteVolatile(null, metaspaceConstantPoolTags + config.arrayU1DataOffset + index);
@@ -299,7 +299,7 @@
      * @return constant pool entry
      */
     private long getEntryAt(int index) {
-        assertBounds(index);
+        assert checkBounds(index);
         int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
         return UNSAFE.getAddress(getMetaspaceConstantPool() + config().constantPoolSize + offset);
     }
@@ -311,7 +311,7 @@
      * @return integer constant pool entry at index
      */
     private int getIntAt(int index) {
-        assertTag(index, JVM_CONSTANT.Integer);
+        assert checkTag(index, JVM_CONSTANT.Integer);
         int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
         return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + offset);
     }
@@ -323,7 +323,7 @@
      * @return long constant pool entry
      */
     private long getLongAt(int index) {
-        assertTag(index, JVM_CONSTANT.Long);
+        assert checkTag(index, JVM_CONSTANT.Long);
         int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
         return UNSAFE.getLong(getMetaspaceConstantPool() + config().constantPoolSize + offset);
     }
@@ -335,7 +335,7 @@
      * @return float constant pool entry
      */
     private float getFloatAt(int index) {
-        assertTag(index, JVM_CONSTANT.Float);
+        assert checkTag(index, JVM_CONSTANT.Float);
         int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
         return UNSAFE.getFloat(getMetaspaceConstantPool() + config().constantPoolSize + offset);
     }
@@ -347,7 +347,7 @@
      * @return float constant pool entry
      */
     private double getDoubleAt(int index) {
-        assertTag(index, JVM_CONSTANT.Double);
+        assert checkTag(index, JVM_CONSTANT.Double);
         int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
         return UNSAFE.getDouble(getMetaspaceConstantPool() + config().constantPoolSize + offset);
     }
@@ -359,7 +359,7 @@
      * @return {@code JVM_CONSTANT_NameAndType} constant pool entry
      */
     private int getNameAndTypeAt(int index) {
-        assertTag(index, JVM_CONSTANT.NameAndType);
+        assert checkTag(index, JVM_CONSTANT.NameAndType);
         int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
         return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + offset);
     }
@@ -441,7 +441,7 @@
      * @return klass reference index
      */
     private int getUncachedKlassRefIndexAt(int index) {
-        assertTagIsFieldOrMethod(index);
+        assert checkTagIsFieldOrMethod(index);
         int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
         final int refIndex = UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + offset);
         // klass ref index is in the low 16-bits.
@@ -449,23 +449,27 @@
     }
 
     /**
-     * Asserts that the constant pool index {@code index} is in the bounds of the constant pool.
+     * Checks that the constant pool index {@code index} is in the bounds of the constant pool.
      *
      * @param index constant pool index
+     * @throws AssertionError if the check fails
      */
-    private void assertBounds(int index) {
+    private boolean checkBounds(int index) {
         assert 0 <= index && index < length() : "index " + index + " not between 0 and " + length();
+        return true;
     }
 
     /**
-     * Asserts that the constant pool tag at index {@code index} is equal to {@code tag}.
+     * Checks that the constant pool tag at index {@code index} is equal to {@code tag}.
      *
      * @param index constant pool index
      * @param tag expected tag
+     * @throws AssertionError if the check fails
      */
-    private void assertTag(int index, JVM_CONSTANT tag) {
+    private boolean checkTag(int index, JVM_CONSTANT tag) {
         final JVM_CONSTANT tagAt = getTagAt(index);
         assert tagAt == tag : "constant pool tag at index " + index + " is " + tagAt + " but expected " + tag;
+        return true;
     }
 
     /**
@@ -473,10 +477,12 @@
      * or a {@link JVM_CONSTANT#MethodRef}, or a {@link JVM_CONSTANT#InterfaceMethodref}.
      *
      * @param index constant pool index
+     * @throws AssertionError if the check fails
      */
-    private void assertTagIsFieldOrMethod(int index) {
+    private boolean checkTagIsFieldOrMethod(int index) {
         final JVM_CONSTANT tagAt = getTagAt(index);
         assert tagAt == JVM_CONSTANT.Fieldref || tagAt == JVM_CONSTANT.MethodRef || tagAt == JVM_CONSTANT.InterfaceMethodref : tagAt;
+        return true;
     }
 
     @Override
@@ -523,7 +529,7 @@
 
     @Override
     public String lookupUtf8(int cpi) {
-        assertTag(cpi, JVM_CONSTANT.Utf8);
+        assert checkTag(cpi, JVM_CONSTANT.Utf8);
         return compilerToVM().getSymbol(getEntryAt(cpi));
     }
 
@@ -690,11 +696,10 @@
                     UNSAFE.ensureClassInitialized(klass);
                 }
                 if (tag == JVM_CONSTANT.MethodRef) {
-                    if (Bytecodes.isInvokeHandleAlias(opcode)) {
+                    if (Bytecodes.isInvokeHandleAlias(opcode) && isSignaturePolymorphicHolder(type)) {
                         final int methodRefCacheIndex = rawIndexToConstantPoolIndex(cpi, opcode);
-                        if (isInvokeHandle(methodRefCacheIndex, type)) {
-                            compilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex);
-                        }
+                        assert checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), JVM_CONSTANT.MethodRef);
+                        compilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex);
                     }
                 }
 
@@ -708,11 +713,26 @@
                 // nothing
                 break;
         }
+
     }
 
-    private boolean isInvokeHandle(int methodRefCacheIndex, HotSpotResolvedObjectTypeImpl klass) {
-        assertTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), JVM_CONSTANT.MethodRef);
-        return ResolvedJavaMethod.isSignaturePolymorphic(klass, getNameOf(methodRefCacheIndex), runtime().getHostJVMCIBackend().getMetaAccess());
+    // Lazily initialized.
+    private static String[] signaturePolymorphicHolders;
+
+    /**
+     * Determines if {@code type} contains signature polymorphic methods.
+     */
+    private static boolean isSignaturePolymorphicHolder(final HotSpotResolvedObjectTypeImpl type) {
+        String name = type.getName();
+        if (signaturePolymorphicHolders == null) {
+            signaturePolymorphicHolders = compilerToVM().getSignaturePolymorphicHolders();
+        }
+        for (String holder : signaturePolymorphicHolders) {
+            if (name.equals(holder)) {
+                return true;
+            }
+        }
+        return false;
     }
 
     @Override
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java	Thu Sep 01 15:20:56 2016 -0700
@@ -497,6 +497,9 @@
         for (Map.Entry<String, Long> e : typeSizes.entrySet()) {
             printConfigLine(vm, "[vmconfig:type size] %s = %d%n", e.getKey(), e.getValue());
         }
+        for (VMIntrinsicMethod e : store.getIntrinsics()) {
+            printConfigLine(vm, "[vmconfig:intrinsic] %d = %s.%s %s%n", e.id, e.declaringClass, e.name, e.descriptor);
+        }
     }
 
     public OutputStream getLogStream() {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java	Thu Sep 01 15:20:56 2016 -0700
@@ -112,6 +112,15 @@
     int intrinsicId();
 
     /**
+     * Determines if this method denotes itself as a candidate for intrinsification. As of JDK 9,
+     * this is denoted by the {@code HotSpotIntrinsicCandidate} annotation. In earlier JDK versions,
+     * this method returns true.
+     *
+     * @see <a href="https://bugs.openjdk.java.net/browse/JDK-8076112">JDK-8076112</a>
+     */
+    boolean isIntrinsicCandidate();
+
+    /**
      * Allocates a compile id for this method by asking the VM for one.
      *
      * @param entryBCI entry bci
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Thu Sep 01 15:20:56 2016 -0700
@@ -693,6 +693,10 @@
         return UNSAFE.getChar(metaspaceMethod + config.methodIntrinsicIdOffset);
     }
 
+    public boolean isIntrinsicCandidate() {
+        return (getFlags() & config().methodFlagsIntrinsicCandidate) != 0;
+    }
+
     @Override
     public JavaConstant invoke(JavaConstant receiver, JavaConstant[] arguments) {
         assert !isConstructor();
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Thu Sep 01 15:20:56 2016 -0700
@@ -144,6 +144,7 @@
 
     final int methodFlagsCallerSensitive = getConstant("Method::_caller_sensitive", Integer.class);
     final int methodFlagsForceInline = getConstant("Method::_force_inline", Integer.class);
+    final int methodFlagsIntrinsicCandidate = getConstant("Method::_intrinsic_candidate", Integer.class);
     final int methodFlagsDontInline = getConstant("Method::_dont_inline", Integer.class);
     final int methodFlagsReservedStackAccess = getConstant("Method::_reserved_stack_access", Integer.class);
     final int nonvirtualVtableIndex = getConstant("Method::nonvirtual_vtable_index", Integer.class);
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java	Thu Sep 01 15:20:56 2016 -0700
@@ -30,6 +30,13 @@
 public class HotSpotVMConfigAccess {
 
     /**
+     * Gets the available configuration data.
+     */
+    public HotSpotVMConfigStore getStore() {
+        return store;
+    }
+
+    /**
      * Gets the address of a C++ symbol.
      *
      * @param name name of C++ symbol
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java	Thu Sep 01 15:20:56 2016 -0700
@@ -24,8 +24,10 @@
 
 import static jdk.vm.ci.common.InitTimer.timer;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import jdk.vm.ci.common.InitTimer;
@@ -80,11 +82,19 @@
         return Collections.unmodifiableMap(vmFields);
     }
 
+    /**
+     * Gets the VM intrinsic descriptions exposed by this object.
+     */
+    public List<VMIntrinsicMethod> getIntrinsics() {
+        return Collections.unmodifiableList(vmIntrinsics);
+    }
+
     final HashMap<String, VMField> vmFields;
     final HashMap<String, Long> vmTypeSizes;
     final HashMap<String, Long> vmConstants;
     final HashMap<String, Long> vmAddresses;
     final HashMap<String, VMFlag> vmFlags;
+    final List<VMIntrinsicMethod> vmIntrinsics;
 
     /**
      * Reads the database of VM info. The return value encodes the info in a nested object array
@@ -97,6 +107,7 @@
      *         [String name, Long value, ...] vmConstants,
      *         [String name, Long value, ...] vmAddresses,
      *         VMFlag[] vmFlags
+     *         VMIntrinsicMethod[] vmIntrinsics
      *     ]
      * </pre>
      */
@@ -106,7 +117,7 @@
         try (InitTimer t = timer("CompilerToVm readConfiguration")) {
             data = compilerToVm.readConfiguration();
         }
-        assert data.length == 5 : data.length;
+        assert data.length == 6 : data.length;
 
         // @formatter:off
         VMField[] vmFieldsInfo    = (VMField[]) data[0];
@@ -115,11 +126,12 @@
         Object[] vmAddressesInfo  = (Object[])  data[3];
         VMFlag[] vmFlagsInfo      = (VMFlag[])  data[4];
 
-        vmFields    = new HashMap<>(vmFieldsInfo.length);
-        vmTypeSizes = new HashMap<>(vmTypesSizesInfo.length);
-        vmConstants = new HashMap<>(vmConstantsInfo.length);
-        vmAddresses = new HashMap<>(vmAddressesInfo.length);
-        vmFlags     = new HashMap<>(vmFlagsInfo.length);
+        vmFields     = new HashMap<>(vmFieldsInfo.length);
+        vmTypeSizes  = new HashMap<>(vmTypesSizesInfo.length);
+        vmConstants  = new HashMap<>(vmConstantsInfo.length);
+        vmAddresses  = new HashMap<>(vmAddressesInfo.length);
+        vmFlags      = new HashMap<>(vmFlagsInfo.length);
+        vmIntrinsics = Arrays.asList((VMIntrinsicMethod[]) data[5]);
         // @formatter:on
 
         try (InitTimer t = timer("HotSpotVMConfigStore<init> fill maps")) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMIntrinsicMethod.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.meta.Signature;
+
+/**
+ * Describes a method for which the VM has an intrinsic implementation.
+ */
+public final class VMIntrinsicMethod {
+
+    /**
+     * The name of the class declaring the intrinsified method. The name is in
+     * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.2.1">class
+     * file format</a> (e.g., {@code "java/lang/Thread"} instead of {@code "java.lang.Thread"}).
+     */
+    public final String declaringClass;
+
+    /**
+     * The name of the intrinsified method. This is not guaranteed to be a legal method name (e.g.,
+     * there is a HotSpot intrinsic with the name {@code "<compiledLambdaForm>"}).
+     */
+    public final String name;
+
+    /**
+     * The {@link Signature#toMethodDescriptor() descriptor} of the intrinsified method. This is not
+     * guaranteed to be a legal method descriptor (e.g., intrinsics for signature polymorphic
+     * methods have a descriptor of {@code "*"}).
+     */
+    public final String descriptor;
+
+    /**
+     * The unique VM identifier for the intrinsic.
+     */
+    public final int id;
+
+    VMIntrinsicMethod(String declaringClass, String name, String descriptor, int id) {
+        this.declaringClass = declaringClass;
+        this.name = name;
+        this.descriptor = descriptor;
+        this.id = id;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof VMIntrinsicMethod) {
+            VMIntrinsicMethod that = (VMIntrinsicMethod) obj;
+            if (that.id == this.id) {
+                assert that.name.equals(this.name) &&
+                                that.declaringClass.equals(this.declaringClass) &&
+                                that.descriptor.equals(this.descriptor);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return id;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("IntrinsicMethod[declaringClass=%s, name=%s, descriptor=%s, id=%d]", declaringClass, name, descriptor, id);
+    }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java	Thu Sep 01 15:20:56 2016 -0700
@@ -23,7 +23,6 @@
 package jdk.vm.ci.meta;
 
 import java.lang.annotation.Annotation;
-import java.lang.invoke.MethodHandle;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Array;
 import java.lang.reflect.Method;
@@ -330,22 +329,4 @@
     }
 
     SpeculationLog getSpeculationLog();
-
-    /**
-     * Determines if the method identified by its holder and name is a
-     * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">signature
-     * polymorphic</a> method.
-     */
-    static boolean isSignaturePolymorphic(JavaType holder, String name, MetaAccessProvider metaAccess) {
-        if (!holder.getName().equals("Ljava/lang/invoke/MethodHandle;")) {
-            return false;
-        }
-        ResolvedJavaType methodHandleType = metaAccess.lookupJavaType(MethodHandle.class);
-        Signature signature = metaAccess.parseMethodDescriptor("([Ljava/lang/Object;)Ljava/lang/Object;");
-        ResolvedJavaMethod method = methodHandleType.findMethod(name, signature);
-        if (method == null) {
-            return false;
-        }
-        return method.isNative() && method.isVarArgs();
-    }
 }
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -444,7 +444,7 @@
 
 
     if (thread->thread_state() == _thread_in_vm) {
-      if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
+      if (sig == SIGBUS && thread->doing_unsafe_access()) {
         stub = SharedRuntime::handle_unsafe_access(thread, npc);
       }
     }
--- a/hotspot/src/share/vm/c1/c1_Compiler.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -221,6 +221,9 @@
   case vmIntrinsics::_putCharStringU:
 #ifdef TRACE_HAVE_INTRINSICS
   case vmIntrinsics::_counterTime:
+#if defined(_LP64) || !defined(TRACE_ID_CLASS_SHIFT)
+  case vmIntrinsics::_getClassId:
+#endif
 #endif
     break;
   default:
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -683,6 +683,7 @@
   , _cleanup_block(NULL)
   , _cleanup_return_prev(NULL)
   , _cleanup_state(NULL)
+  , _ignore_return(false)
 {
   if (parent != NULL) {
     _max_inline_size = (intx) ((float) NestedInliningSizeRatio * (float) parent->max_inline_size() / 100.0f);
@@ -1445,7 +1446,7 @@
 }
 
 
-void GraphBuilder::method_return(Value x) {
+void GraphBuilder::method_return(Value x, bool ignore_return) {
   if (RegisterFinalizersAtInit &&
       method()->intrinsic_id() == vmIntrinsics::_Object_init) {
     call_register_finalizer();
@@ -1518,7 +1519,9 @@
     int invoke_bci = state()->caller_state()->bci();
     set_state(state()->caller_state()->copy_for_parsing());
     if (x != NULL) {
-      state()->push(x->type(), x);
+      if (!ignore_return) {
+        state()->push(x->type(), x);
+      }
       if (profile_return() && x->type()->is_object_kind()) {
         ciMethod* caller = state()->scope()->method();
         ciMethodData* md = caller->method_data_or_null();
@@ -1563,6 +1566,7 @@
       append(new MemBar(lir_membar_storestore));
   }
 
+  assert(!ignore_return, "Ignoring return value works only for inlining");
   append(new Return(x));
 }
 
@@ -1981,7 +1985,7 @@
         code == Bytecodes::_invokedynamic) {
       ciMethod* inline_target = (cha_monomorphic_target != NULL) ? cha_monomorphic_target : target;
       // static binding => check if callee is ok
-      bool success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL), code, better_receiver);
+      bool success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL), false, code, better_receiver);
 
       CHECK_BAILOUT();
       clear_inline_bailout();
@@ -2611,6 +2615,8 @@
     push_exception = true;
   }
 
+  bool ignore_return = scope_data()->ignore_return();
+
   while (!bailed_out() && last()->as_BlockEnd() == NULL &&
          (code = stream()->next()) != ciBytecodeStream::EOBC() &&
          (block_at(s.cur_bci()) == NULL || block_at(s.cur_bci()) == block())) {
@@ -2806,12 +2812,12 @@
       case Bytecodes::_ret            : ret(s.get_index()); break;
       case Bytecodes::_tableswitch    : table_switch(); break;
       case Bytecodes::_lookupswitch   : lookup_switch(); break;
-      case Bytecodes::_ireturn        : method_return(ipop()); break;
-      case Bytecodes::_lreturn        : method_return(lpop()); break;
-      case Bytecodes::_freturn        : method_return(fpop()); break;
-      case Bytecodes::_dreturn        : method_return(dpop()); break;
-      case Bytecodes::_areturn        : method_return(apop()); break;
-      case Bytecodes::_return         : method_return(NULL  ); break;
+      case Bytecodes::_ireturn        : method_return(ipop(), ignore_return); break;
+      case Bytecodes::_lreturn        : method_return(lpop(), ignore_return); break;
+      case Bytecodes::_freturn        : method_return(fpop(), ignore_return); break;
+      case Bytecodes::_dreturn        : method_return(dpop(), ignore_return); break;
+      case Bytecodes::_areturn        : method_return(apop(), ignore_return); break;
+      case Bytecodes::_return         : method_return(NULL  , ignore_return); break;
       case Bytecodes::_getstatic      : // fall through
       case Bytecodes::_putstatic      : // fall through
       case Bytecodes::_getfield       : // fall through
@@ -3336,7 +3342,7 @@
 }
 
 
-bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, Bytecodes::Code bc, Value receiver) {
+bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, bool ignore_return, Bytecodes::Code bc, Value receiver) {
   const char* msg = NULL;
 
   // clear out any existing inline bailout condition
@@ -3351,7 +3357,7 @@
 
   // method handle invokes
   if (callee->is_method_handle_intrinsic()) {
-    if (try_method_handle_inline(callee)) {
+    if (try_method_handle_inline(callee, ignore_return)) {
       if (callee->has_reserved_stack_access()) {
         compilation()->set_has_reserved_stack_access(true);
       }
@@ -3363,7 +3369,7 @@
   // handle intrinsics
   if (callee->intrinsic_id() != vmIntrinsics::_none &&
       (CheckIntrinsics ? callee->intrinsic_candidate() : true)) {
-    if (try_inline_intrinsics(callee)) {
+    if (try_inline_intrinsics(callee, ignore_return)) {
       print_inlining(callee, "intrinsic");
       if (callee->has_reserved_stack_access()) {
         compilation()->set_has_reserved_stack_access(true);
@@ -3384,7 +3390,7 @@
   if (bc == Bytecodes::_illegal) {
     bc = code();
   }
-  if (try_inline_full(callee, holder_known, bc, receiver)) {
+  if (try_inline_full(callee, holder_known, ignore_return, bc, receiver)) {
     if (callee->has_reserved_stack_access()) {
       compilation()->set_has_reserved_stack_access(true);
     }
@@ -3415,7 +3421,7 @@
   return NULL;
 }
 
-void GraphBuilder::build_graph_for_intrinsic(ciMethod* callee) {
+void GraphBuilder::build_graph_for_intrinsic(ciMethod* callee, bool ignore_return) {
   vmIntrinsics::ID id = callee->intrinsic_id();
   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
 
@@ -3509,14 +3515,16 @@
                                     vmIntrinsics::can_trap(id));
   // append instruction & push result
   Value value = append_split(result);
-  if (result_type != voidType) push(result_type, value);
+  if (result_type != voidType && !ignore_return) {
+    push(result_type, value);
+  }
 
   if (callee != method() && profile_return() && result_type->is_object_kind()) {
     profile_return_type(result, callee);
   }
 }
 
-bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) {
+bool GraphBuilder::try_inline_intrinsics(ciMethod* callee, bool ignore_return) {
   // For calling is_intrinsic_available we need to transition to
   // the '_thread_in_vm' state because is_intrinsic_available()
   // accesses critical VM-internal data.
@@ -3536,7 +3544,7 @@
       return false;
     }
   }
-  build_graph_for_intrinsic(callee);
+  build_graph_for_intrinsic(callee, ignore_return);
   return true;
 }
 
@@ -3691,7 +3699,7 @@
 }
 
 
-bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecodes::Code bc, Value receiver) {
+bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, bool ignore_return, Bytecodes::Code bc, Value receiver) {
   assert(!callee->is_native(), "callee must not be native");
   if (CompilationPolicy::policy()->should_not_inline(compilation()->env(), callee)) {
     INLINE_BAILOUT("inlining prohibited by policy");
@@ -3889,6 +3897,7 @@
 
   // Clear out bytecode stream
   scope_data()->set_stream(NULL);
+  scope_data()->set_ignore_return(ignore_return);
 
   CompileLog* log = compilation()->log();
   if (log != NULL) log->head("parse method='%d'", log->identify(callee));
@@ -3958,7 +3967,7 @@
 }
 
 
-bool GraphBuilder::try_method_handle_inline(ciMethod* callee) {
+bool GraphBuilder::try_method_handle_inline(ciMethod* callee, bool ignore_return) {
   ValueStack* state_before = copy_state_before();
   vmIntrinsics::ID iid = callee->intrinsic_id();
   switch (iid) {
@@ -3972,7 +3981,8 @@
         // We don't do CHA here so only inline static and statically bindable methods.
         if (target->is_static() || target->can_be_statically_bound()) {
           Bytecodes::Code bc = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual;
-          if (try_inline(target, /*holder_known*/ true, bc)) {
+          ignore_return = ignore_return || (callee->return_type()->is_void() && !target->return_type()->is_void());
+          if (try_inline(target, /*holder_known*/ true, ignore_return, bc)) {
             return true;
           }
         } else {
@@ -3994,10 +4004,11 @@
       ValueType* type = apop()->type();
       if (type->is_constant()) {
         ciMethod* target = type->as_ObjectType()->constant_value()->as_member_name()->get_vmtarget();
+        ignore_return = ignore_return || (callee->return_type()->is_void() && !target->return_type()->is_void());
         // If the target is another method handle invoke, try to recursively get
         // a better target.
         if (target->is_method_handle_intrinsic()) {
-          if (try_method_handle_inline(target)) {
+          if (try_method_handle_inline(target, ignore_return)) {
             return true;
           }
         } else {
@@ -4032,7 +4043,7 @@
           // We don't do CHA here so only inline static and statically bindable methods.
           if (target->is_static() || target->can_be_statically_bound()) {
             Bytecodes::Code bc = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual;
-            if (try_inline(target, /*holder_known*/ true, bc)) {
+            if (try_inline(target, /*holder_known*/ true, ignore_return, bc)) {
               return true;
             }
           } else {
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -100,6 +100,9 @@
     Instruction* _cleanup_return_prev; // Instruction before return instruction
     ValueStack*  _cleanup_state;       // State of that block (not yet pinned)
 
+    // When inlining do not push the result on the stack
+    bool         _ignore_return;
+
    public:
     ScopeData(ScopeData* parent);
 
@@ -163,6 +166,9 @@
     BlockBegin*  inline_cleanup_block() const      { return _cleanup_block; }
     Instruction* inline_cleanup_return_prev() const{ return _cleanup_return_prev; }
     ValueStack*  inline_cleanup_state() const      { return _cleanup_state; }
+
+    bool ignore_return() const                     { return _ignore_return;          }
+    void set_ignore_return(bool ignore_return)     { _ignore_return = ignore_return; }
   };
 
   // for all GraphBuilders
@@ -246,7 +252,7 @@
   void ret(int local_index);
   void table_switch();
   void lookup_switch();
-  void method_return(Value x);
+  void method_return(Value x, bool ignore_return = false);
   void call_register_finalizer();
   void access_field(Bytecodes::Code code);
   void invoke(Bytecodes::Code code);
@@ -340,19 +346,19 @@
   void inline_sync_entry(Value lock, BlockBegin* sync_handler);
   void fill_sync_handler(Value lock, BlockBegin* sync_handler, bool default_handler = false);
 
-  void build_graph_for_intrinsic(ciMethod* callee);
+  void build_graph_for_intrinsic(ciMethod* callee, bool ignore_return);
 
   // inliners
-  bool try_inline(           ciMethod* callee, bool holder_known, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
-  bool try_inline_intrinsics(ciMethod* callee);
-  bool try_inline_full(      ciMethod* callee, bool holder_known, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
+  bool try_inline(           ciMethod* callee, bool holder_known, bool ignore_return, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
+  bool try_inline_intrinsics(ciMethod* callee, bool ignore_return = false);
+  bool try_inline_full(      ciMethod* callee, bool holder_known, bool ignore_return, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
   bool try_inline_jsr(int jsr_dest_bci);
 
   const char* check_can_parse(ciMethod* callee) const;
   const char* should_not_inline(ciMethod* callee) const;
 
   // JSR 292 support
-  bool try_method_handle_inline(ciMethod* callee);
+  bool try_method_handle_inline(ciMethod* callee, bool ignore_return);
 
   // helpers
   void inline_bailout(const char* msg);
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -3083,6 +3083,37 @@
   __ cmove(lir_cond(x->cond()), t_val.result(), f_val.result(), reg, as_BasicType(x->x()->type()));
 }
 
+#ifdef TRACE_HAVE_INTRINSICS
+void LIRGenerator::do_ClassIDIntrinsic(Intrinsic* x) {
+  CodeEmitInfo* info = state_for(x);
+  CodeEmitInfo* info2 = new CodeEmitInfo(info); // Clone for the second null check
+
+  assert(info != NULL, "must have info");
+  LIRItem arg(x->argument_at(0), this);
+
+  arg.load_item();
+  LIR_Opr klass = new_register(T_METADATA);
+  __ move(new LIR_Address(arg.result(), java_lang_Class::klass_offset_in_bytes(), T_ADDRESS), klass, info);
+  LIR_Opr id = new_register(T_LONG);
+  ByteSize offset = TRACE_KLASS_TRACE_ID_OFFSET;
+  LIR_Address* trace_id_addr = new LIR_Address(klass, in_bytes(offset), T_LONG);
+
+  __ move(trace_id_addr, id);
+  __ logical_or(id, LIR_OprFact::longConst(0x01l), id);
+  __ store(id, trace_id_addr);
+
+#ifdef TRACE_ID_META_BITS
+  __ logical_and(id, LIR_OprFact::longConst(~TRACE_ID_META_BITS), id);
+#endif
+#ifdef TRACE_ID_CLASS_SHIFT
+  __ unsigned_shift_right(id, TRACE_ID_CLASS_SHIFT, id);
+#endif
+
+  __ move(id, rlock_result(x));
+}
+#endif
+
+
 void LIRGenerator::do_RuntimeCall(address routine, Intrinsic* x) {
   assert(x->number_of_arguments() == 0, "wrong type");
   // Enforce computation of _reserved_argument_area_size which is required on some platforms.
@@ -3108,6 +3139,9 @@
   }
 
 #ifdef TRACE_HAVE_INTRINSICS
+  case vmIntrinsics::_getClassId:
+    do_ClassIDIntrinsic(x);
+    break;
   case vmIntrinsics::_counterTime:
     do_RuntimeCall(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), x);
     break;
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -438,6 +438,10 @@
   SwitchRangeArray* create_lookup_ranges(LookupSwitch* x);
   void do_SwitchRanges(SwitchRangeArray* x, LIR_Opr value, BlockBegin* default_sux);
 
+#ifdef TRACE_HAVE_INTRINSICS
+  void do_ClassIDIntrinsic(Intrinsic* x);
+#endif
+
   void do_RuntimeCall(address routine, Intrinsic* x);
 
   ciKlass* profile_type(ciMethodData* md, int md_first_offset, int md_offset, intptr_t profiled_k,
--- a/hotspot/src/share/vm/ci/ciReplay.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -29,7 +29,6 @@
 #include "ci/ciKlass.hpp"
 #include "ci/ciUtilities.hpp"
 #include "compiler/compileBroker.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
@@ -577,9 +576,7 @@
     Method* method = parse_method(CHECK);
     if (had_error()) return;
     /* just copied from Method, to build interpret data*/
-    if (ReferencePendingListLocker::is_locked_by_self()) {
-      return;
-    }
+
     // To be properly initialized, some profiling in the MDO needs the
     // method to be rewritten (number of arguments at a call for
     // instance)
--- a/hotspot/src/share/vm/classfile/altHashing.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/classfile/altHashing.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -205,103 +205,3 @@
 juint AltHashing::murmur3_32(const int* data, int len) {
   return murmur3_32(0, data, len);
 }
-
-#ifndef PRODUCT
-// Overloaded versions for internal test.
-juint AltHashing::murmur3_32(const jbyte* data, int len) {
-  return murmur3_32(0, data, len);
-}
-
-juint AltHashing::murmur3_32(const jchar* data, int len) {
-  return murmur3_32(0, data, len);
-}
-
-// Internal test for alternate hashing.  Translated from JDK version
-// test/sun/misc/Hashing.java
-static const jbyte ONE_BYTE[] = { (jbyte) 0x80};
-static const jbyte TWO_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81};
-static const jchar ONE_CHAR[] = { (jchar) 0x8180};
-static const jbyte THREE_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82};
-static const jbyte FOUR_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83};
-static const jchar TWO_CHAR[] = { (jchar) 0x8180, (jchar) 0x8382};
-static const jint ONE_INT[] = { (jint)0x83828180};
-static const jbyte SIX_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85};
-static const jchar THREE_CHAR[] = { (jchar) 0x8180, (jchar) 0x8382, (jchar) 0x8584};
-static const jbyte EIGHT_BYTE[] = {
-  (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82,
-  (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85,
-  (jbyte) 0x86, (jbyte) 0x87};
-static const jchar FOUR_CHAR[] = {
-  (jchar) 0x8180, (jchar) 0x8382,
-  (jchar) 0x8584, (jchar) 0x8786};
-
-static const jint TWO_INT[] = { (jint)0x83828180, (jint)0x87868584};
-
-static const juint MURMUR3_32_X86_CHECK_VALUE = 0xB0F57EE3;
-
-void AltHashing::testMurmur3_32_ByteArray() {
-  // printf("testMurmur3_32_ByteArray\n");
-
-  jbyte vector[256];
-  jbyte hashes[4 * 256];
-
-  for (int i = 0; i < 256; i++) {
-    vector[i] = (jbyte) i;
-  }
-
-  // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255}
-  for (int i = 0; i < 256; i++) {
-    juint hash = murmur3_32(256 - i, vector, i);
-    hashes[i * 4] = (jbyte) hash;
-    hashes[i * 4 + 1] = (jbyte)(hash >> 8);
-    hashes[i * 4 + 2] = (jbyte)(hash >> 16);
-    hashes[i * 4 + 3] = (jbyte)(hash >> 24);
-  }
-
-  // hash to get const result.
-  juint final_hash = murmur3_32(hashes, 4*256);
-
-  assert (MURMUR3_32_X86_CHECK_VALUE == final_hash,
-          "Calculated hash result not as expected. Expected %08X got %08X\n",
-          MURMUR3_32_X86_CHECK_VALUE,
-          final_hash);
-}
-
-void AltHashing::testEquivalentHashes() {
-  juint jbytes, jchars, ints;
-
-  // printf("testEquivalentHashes\n");
-
-  jbytes = murmur3_32(TWO_BYTE, 2);
-  jchars = murmur3_32(ONE_CHAR, 1);
-  assert (jbytes == jchars,
-          "Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars);
-
-  jbytes = murmur3_32(FOUR_BYTE, 4);
-  jchars = murmur3_32(TWO_CHAR, 2);
-  ints = murmur3_32(ONE_INT, 1);
-  assert ((jbytes == jchars) && (jbytes == ints),
-          "Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints);
-
-  jbytes = murmur3_32(SIX_BYTE, 6);
-  jchars = murmur3_32(THREE_CHAR, 3);
-  assert (jbytes == jchars,
-         "Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars);
-
-  jbytes = murmur3_32(EIGHT_BYTE, 8);
-  jchars = murmur3_32(FOUR_CHAR, 4);
-  ints = murmur3_32(TWO_INT, 2);
-  assert ((jbytes == jchars) && (jbytes == ints),
-          "Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints);
-}
-
-// Returns true if the alternate hashcode is correct
-void AltHashing::test_alt_hash() {
-  testMurmur3_32_ByteArray();
-  testEquivalentHashes();
-}
-
-void AltHashing_test() {
-  AltHashing::test_alt_hash();
-}
-#endif // PRODUCT
--- a/hotspot/src/share/vm/classfile/altHashing.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/classfile/altHashing.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,26 +37,18 @@
  */
 
 class AltHashing : AllStatic {
+  friend class AltHashingTest;
 
   // utility function copied from java/lang/Integer
   static juint Integer_rotateLeft(juint i, int distance) {
-    return (i << distance) | (i >> (32-distance));
+    return (i << distance) | (i >> (32 - distance));
   }
   static juint murmur3_32(const int* data, int len);
   static juint murmur3_32(juint seed, const int* data, int len);
 
-#ifndef PRODUCT
-  // Hashing functions used for internal testing
-  static juint murmur3_32(const jbyte* data, int len);
-  static juint murmur3_32(const jchar* data, int len);
-  static void testMurmur3_32_ByteArray();
-  static void testEquivalentHashes();
-#endif // PRODUCT
-
  public:
   static juint compute_seed();
   static juint murmur3_32(juint seed, const jbyte* data, int len);
   static juint murmur3_32(juint seed, const jchar* data, int len);
-  NOT_PRODUCT(static void test_alt_hash();)
 };
 #endif // SHARE_VM_CLASSFILE_ALTHASHING_HPP
--- a/hotspot/src/share/vm/classfile/classLoader.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -50,12 +50,14 @@
 
 class ClassPathEntry : public CHeapObj<mtClass> {
 private:
-  ClassPathEntry* _next;
+  ClassPathEntry* volatile _next;
 public:
   // Next entry in class path
-  ClassPathEntry* next() const { return _next; }
+  ClassPathEntry* next() const {
+    return (ClassPathEntry*) OrderAccess::load_ptr_acquire(&_next);
+  }
   void set_next(ClassPathEntry* next) {
-    // may have unlocked readers, so write atomically.
+    // may have unlocked readers, so ensure visibility.
     OrderAccess::release_store_ptr(&_next, next);
   }
   virtual bool is_jrt() = 0;
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -962,7 +962,7 @@
 
   // Mark metadata seen on the stack only so we can delete unneeded entries.
   // Only walk all metadata, including the expensive code cache walk, for Full GC
-  // and only if class redefinition and if there's previous versions of
+  // and only if class redefinition occurred and if there are previous versions of
   // Klasses to delete.
   bool walk_all_metadata = clean_previous_versions &&
                            JvmtiExport::has_redefined_a_class() &&
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -3015,41 +3015,6 @@
   }
 }
 
-
-// Support for java_lang_ref_Reference
-HeapWord *java_lang_ref_Reference::pending_list_lock_addr() {
-  InstanceKlass* ik = SystemDictionary::Reference_klass();
-  address addr = ik->static_field_addr(static_lock_offset);
-  return (HeapWord*) addr;
-}
-
-oop java_lang_ref_Reference::pending_list_lock() {
-  InstanceKlass* ik = SystemDictionary::Reference_klass();
-  address addr = ik->static_field_addr(static_lock_offset);
-  if (UseCompressedOops) {
-    return oopDesc::load_decode_heap_oop((narrowOop *)addr);
-  } else {
-    return oopDesc::load_decode_heap_oop((oop*)addr);
-  }
-}
-
-HeapWord *java_lang_ref_Reference::pending_list_addr() {
-  InstanceKlass* ik = SystemDictionary::Reference_klass();
-  address addr = ik->static_field_addr(static_pending_offset);
-  // XXX This might not be HeapWord aligned, almost rather be char *.
-  return (HeapWord*)addr;
-}
-
-oop java_lang_ref_Reference::pending_list() {
-  char *addr = (char *)pending_list_addr();
-  if (UseCompressedOops) {
-    return oopDesc::load_decode_heap_oop((narrowOop *)addr);
-  } else {
-    return oopDesc::load_decode_heap_oop((oop*)addr);
-  }
-}
-
-
 // Support for java_lang_ref_SoftReference
 
 jlong java_lang_ref_SoftReference::timestamp(oop ref) {
@@ -3616,8 +3581,6 @@
 int java_lang_ref_Reference::queue_offset;
 int java_lang_ref_Reference::next_offset;
 int java_lang_ref_Reference::discovered_offset;
-int java_lang_ref_Reference::static_lock_offset;
-int java_lang_ref_Reference::static_pending_offset;
 int java_lang_ref_Reference::number_of_fake_oop_fields;
 int java_lang_ref_SoftReference::timestamp_offset;
 int java_lang_ref_SoftReference::static_clock_offset;
@@ -3772,8 +3735,6 @@
   java_lang_ref_Reference::queue_offset = java_lang_ref_Reference::hc_queue_offset * x + header;
   java_lang_ref_Reference::next_offset  = java_lang_ref_Reference::hc_next_offset * x + header;
   java_lang_ref_Reference::discovered_offset  = java_lang_ref_Reference::hc_discovered_offset * x + header;
-  java_lang_ref_Reference::static_lock_offset = java_lang_ref_Reference::hc_static_lock_offset *  x;
-  java_lang_ref_Reference::static_pending_offset = java_lang_ref_Reference::hc_static_pending_offset * x;
   // Artificial fields for java_lang_ref_Reference
   // The first field is for the discovered field added in 1.4
   java_lang_ref_Reference::number_of_fake_oop_fields = 1;
@@ -4006,8 +3967,6 @@
   CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, next, "Ljava/lang/ref/Reference;");
   // Fake field
   //CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, discovered, "Ljava/lang/ref/Reference;");
-  CHECK_STATIC_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, lock, "Ljava/lang/ref/Reference$Lock;");
-  CHECK_STATIC_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, pending, "Ljava/lang/ref/Reference;");
 
   // java.lang.ref.SoftReference
 
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -886,17 +886,11 @@
    hc_next_offset       = 2,
    hc_discovered_offset = 3  // Is not last, see SoftRefs.
   };
-  enum {
-   hc_static_lock_offset    = 0,
-   hc_static_pending_offset = 1
-  };
 
   static int referent_offset;
   static int queue_offset;
   static int next_offset;
   static int discovered_offset;
-  static int static_lock_offset;
-  static int static_pending_offset;
   static int number_of_fake_oop_fields;
 
   // Accessors
@@ -912,13 +906,6 @@
   static inline void set_discovered(oop ref, oop value);
   static inline void set_discovered_raw(oop ref, oop value);
   static inline HeapWord* discovered_addr(oop ref);
-
-  // Accessors for statics
-  static oop  pending_list_lock();
-  static oop  pending_list();
-
-  static HeapWord*  pending_list_lock_addr();
-  static HeapWord*  pending_list_addr();
 };
 
 
--- a/hotspot/src/share/vm/classfile/verifier.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/classfile/verifier.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -67,12 +67,12 @@
 static volatile jint _is_new_verify_byte_codes_fn = (jint) true;
 
 static void* verify_byte_codes_fn() {
-  if (_verify_byte_codes_fn == NULL) {
+  if (OrderAccess::load_ptr_acquire(&_verify_byte_codes_fn) == NULL) {
     void *lib_handle = os::native_java_library();
     void *func = os::dll_lookup(lib_handle, "VerifyClassCodesForMajorVersion");
     OrderAccess::release_store_ptr(&_verify_byte_codes_fn, func);
     if (func == NULL) {
-      OrderAccess::release_store(&_is_new_verify_byte_codes_fn, false);
+      _is_new_verify_byte_codes_fn = false;
       func = os::dll_lookup(lib_handle, "VerifyClassCodes");
       OrderAccess::release_store_ptr(&_verify_byte_codes_fn, func);
     }
--- a/hotspot/src/share/vm/classfile/vmSymbols.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -366,6 +366,7 @@
   switch(id) {
 #ifdef TRACE_HAVE_INTRINSICS
   case vmIntrinsics::_counterTime:
+  case vmIntrinsics::_getClassId:
 #endif
   case vmIntrinsics::_currentTimeMillis:
   case vmIntrinsics::_nanoTime:
--- a/hotspot/src/share/vm/code/codeCache.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -437,7 +437,7 @@
  * run the constructor for the CodeBlob subclass he is busy
  * instantiating.
  */
-CodeBlob* CodeCache::allocate(int size, int code_blob_type, bool strict) {
+CodeBlob* CodeCache::allocate(int size, int code_blob_type, int orig_code_blob_type) {
   // Possibly wakes up the sweeper thread.
   NMethodSweeper::notify(code_blob_type);
   assert_locked_or_safepoint(CodeCache_lock);
@@ -455,32 +455,41 @@
     cb = (CodeBlob*)heap->allocate(size);
     if (cb != NULL) break;
     if (!heap->expand_by(CodeCacheExpansionSize)) {
+      // Save original type for error reporting
+      if (orig_code_blob_type == CodeBlobType::All) {
+        orig_code_blob_type = code_blob_type;
+      }
       // Expansion failed
-      if (SegmentedCodeCache && !strict) {
+      if (SegmentedCodeCache) {
         // Fallback solution: Try to store code in another code heap.
+        // NonNMethod -> MethodNonProfiled -> MethodProfiled (-> MethodNonProfiled)
         // Note that in the sweeper, we check the reverse_free_ratio of the code heap
         // and force stack scanning if less than 10% of the code heap are free.
         int type = code_blob_type;
         switch (type) {
         case CodeBlobType::NonNMethod:
           type = CodeBlobType::MethodNonProfiled;
-          strict = false;   // Allow recursive search for other heaps
-          break;
-        case CodeBlobType::MethodProfiled:
-          type = CodeBlobType::MethodNonProfiled;
-          strict = true;
           break;
         case CodeBlobType::MethodNonProfiled:
           type = CodeBlobType::MethodProfiled;
-          strict = true;
+          break;
+        case CodeBlobType::MethodProfiled:
+          // Avoid loop if we already tried that code heap
+          if (type == orig_code_blob_type) {
+            type = CodeBlobType::MethodNonProfiled;
+          }
           break;
         }
-        if (heap_available(type)) {
-          return allocate(size, type, strict);
+        if (type != code_blob_type && type != orig_code_blob_type && heap_available(type)) {
+          if (PrintCodeCacheExtension) {
+            tty->print_cr("Extension of %s failed. Trying to allocate in %s.",
+                          heap->name(), get_code_heap(type)->name());
+          }
+          return allocate(size, type, orig_code_blob_type);
         }
       }
       MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-      CompileBroker::handle_full_code_cache(code_blob_type);
+      CompileBroker::handle_full_code_cache(orig_code_blob_type);
       return NULL;
     }
     if (PrintCodeCacheExtension) {
--- a/hotspot/src/share/vm/code/codeCache.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/code/codeCache.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -126,7 +126,7 @@
   static void initialize();
 
   // Allocation/administration
-  static CodeBlob* allocate(int size, int code_blob_type, bool strict = false); // allocates a new CodeBlob
+  static CodeBlob* allocate(int size, int code_blob_type, int orig_code_blob_type = CodeBlobType::All); // allocates a new CodeBlob
   static void commit(CodeBlob* cb);                        // called when the allocated CodeBlob has been filled
   static int  alignment_unit();                            // guaranteed alignment of all CodeBlobs
   static int  alignment_offset();                          // guaranteed offset of first CodeBlob byte within alignment unit (i.e., allocation header)
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -32,7 +32,6 @@
 #include "compiler/compileLog.hpp"
 #include "compiler/compilerOracle.hpp"
 #include "compiler/directivesParser.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
 #include "interpreter/linkResolver.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
@@ -893,15 +892,6 @@
     return;
   }
 
-  // If the requesting thread is holding the pending list lock
-  // then we just return. We can't risk blocking while holding
-  // the pending list lock or a 3-way deadlock may occur
-  // between the reference handler thread, a GC (instigated
-  // by a compiler thread), and compiled method registration.
-  if (ReferencePendingListLocker::is_locked_by_self()) {
-    return;
-  }
-
   if (TieredCompilation) {
     // Tiered policy requires MethodCounters to exist before adding a method to
     // the queue. Create if we don't have them yet.
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepThread.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepThread.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -28,7 +28,6 @@
 #include "gc/cms/concurrentMarkSweepThread.hpp"
 #include "gc/shared/gcId.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/init.hpp"
 #include "runtime/interfaceSupport.hpp"
@@ -77,23 +76,6 @@
     log_warning(gc)("Couldn't bind CMS thread to processor " UINTX_FORMAT, CPUForCMSThread);
   }
 
-  {
-    MutexLockerEx x(CGC_lock, true);
-    set_CMS_flag(CMS_cms_wants_token);
-    assert(is_init_completed() && Universe::is_fully_initialized(), "ConcurrentGCThread::run() should have waited for this.");
-
-    // Wait until the surrogate locker thread that will do
-    // pending list locking on our behalf has been created.
-    // We cannot start the SLT thread ourselves since we need
-    // to be a JavaThread to do so.
-    CMSLoopCountWarn loopY("CMS::run", "waiting for SLT installation", 2);
-    while (!ReferencePendingListLocker::is_initialized() && !should_terminate()) {
-      CGC_lock->wait(true, 200);
-      loopY.tick();
-    }
-    clear_CMS_flag(CMS_cms_wants_token);
-  }
-
   while (!should_terminate()) {
     sleepBeforeNextCycle();
     if (should_terminate()) break;
--- a/hotspot/src/share/vm/gc/cms/vmCMSOperations.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/vmCMSOperations.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -37,14 +37,6 @@
 //////////////////////////////////////////////////////////
 // Methods in abstract class VM_CMS_Operation
 //////////////////////////////////////////////////////////
-void VM_CMS_Operation::acquire_pending_list_lock() {
-  _pending_list_locker.lock();
-}
-
-void VM_CMS_Operation::release_and_notify_pending_list_lock() {
-  _pending_list_locker.unlock();
-}
-
 void VM_CMS_Operation::verify_before_gc() {
   if (VerifyBeforeGC &&
       GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
@@ -85,17 +77,10 @@
   assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
          "Possible deadlock");
 
-  if (needs_pending_list_lock()) {
-    acquire_pending_list_lock();
-  }
-  // Get the Heap_lock after the pending_list_lock.
   Heap_lock->lock();
   if (lost_race()) {
     assert(_prologue_succeeded == false, "Initialized in c'tor");
     Heap_lock->unlock();
-    if (needs_pending_list_lock()) {
-      release_and_notify_pending_list_lock();
-    }
   } else {
     _prologue_succeeded = true;
   }
@@ -108,11 +93,10 @@
   assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
          "Possible deadlock");
 
-  // Release the Heap_lock first.
+  if (Universe::has_reference_pending_list()) {
+    Heap_lock->notify_all();
+  }
   Heap_lock->unlock();
-  if (needs_pending_list_lock()) {
-    release_and_notify_pending_list_lock();
-  }
 }
 
 //////////////////////////////////////////////////////////
@@ -230,9 +214,11 @@
   Thread* thr = Thread::current();
   assert(thr->is_Java_thread(), "just checking");
   JavaThread* jt = (JavaThread*)thr;
-  // Release the Heap_lock first.
+
+  if (Universe::has_reference_pending_list()) {
+    Heap_lock->notify_all();
+  }
   Heap_lock->unlock();
-  release_and_notify_pending_list_lock();
 
   // It is fine to test whether completed collections has
   // exceeded our request count without locking because
--- a/hotspot/src/share/vm/gc/cms/vmCMSOperations.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/vmCMSOperations.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -28,7 +28,6 @@
 #include "gc/cms/concurrentMarkSweepGeneration.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/gcId.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
 #include "gc/shared/vmGCOperations.hpp"
 #include "runtime/vm_operations.hpp"
 
@@ -52,9 +51,6 @@
 class CMSCollector;
 
 class VM_CMS_Operation: public VM_Operation {
- private:
-  ReferencePendingListLocker _pending_list_locker;
-
  protected:
   CMSCollector*  _collector;                 // associated collector
   bool           _prologue_succeeded;     // whether doit_prologue succeeded
@@ -62,10 +58,6 @@
 
   bool lost_race() const;
 
-  // java.lang.ref.Reference support
-  void acquire_pending_list_lock();
-  void release_and_notify_pending_list_lock();
-
  public:
   VM_CMS_Operation(CMSCollector* collector):
     _collector(collector),
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -175,7 +175,7 @@
                                 TimeHelper::counter_to_millis(mark_end - mark_start));
 
           CMCheckpointRootsFinalClosure final_cl(_cm);
-          VM_CGC_Operation op(&final_cl, "Pause Remark", true /* needs_pll */);
+          VM_CGC_Operation op(&final_cl, "Pause Remark");
           VMThread::execute(&op);
         }
         if (cm()->restart_for_overflow()) {
@@ -199,7 +199,7 @@
         delay_to_keep_mmu(g1_policy, false /* cleanup */);
 
         CMCleanUp cl_cl(_cm);
-        VM_CGC_Operation op(&cl_cl, "Pause Cleanup", false /* needs_pll */);
+        VM_CGC_Operation op(&cl_cl, "Pause Cleanup");
         VMThread::execute(&op);
       } else {
         // We don't want to update the marking status if a GC pause
--- a/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "code/codeCache.hpp"
 #include "code/nmethod.hpp"
+#include "gc/g1/g1CodeRootSetTable.hpp"
 #include "gc/g1/g1CodeCacheRemSet.hpp"
 #include "gc/g1/heapRegion.hpp"
 #include "memory/heap.hpp"
@@ -33,58 +34,13 @@
 #include "utilities/hashtable.inline.hpp"
 #include "utilities/stack.inline.hpp"
 
-class CodeRootSetTable : public Hashtable<nmethod*, mtGC> {
-  friend class G1CodeRootSetTest;
-  typedef HashtableEntry<nmethod*, mtGC> Entry;
-
-  static CodeRootSetTable* volatile _purge_list;
-
-  CodeRootSetTable* _purge_next;
-
-  unsigned int compute_hash(nmethod* nm) {
-    uintptr_t hash = (uintptr_t)nm;
-    return hash ^ (hash >> 7); // code heap blocks are 128byte aligned
-  }
-
-  void remove_entry(Entry* e, Entry* previous);
-  Entry* new_entry(nmethod* nm);
-
- public:
-  CodeRootSetTable(int size) : Hashtable<nmethod*, mtGC>(size, sizeof(Entry)), _purge_next(NULL) {}
-  ~CodeRootSetTable();
-
-  // Needs to be protected locks
-  bool add(nmethod* nm);
-  bool remove(nmethod* nm);
+G1CodeRootSetTable* volatile G1CodeRootSetTable::_purge_list = NULL;
 
-  // Can be called without locking
-  bool contains(nmethod* nm);
-
-  int entry_size() const { return BasicHashtable<mtGC>::entry_size(); }
-
-  void copy_to(CodeRootSetTable* new_table);
-  void nmethods_do(CodeBlobClosure* blk);
-
-  template<typename CB>
-  int remove_if(CB& should_remove);
-
-  static void purge_list_append(CodeRootSetTable* tbl);
-  static void purge();
-
-  static size_t static_mem_size() {
-    return sizeof(_purge_list);
-  }
-
-  size_t mem_size();
-};
-
-CodeRootSetTable* volatile CodeRootSetTable::_purge_list = NULL;
-
-size_t CodeRootSetTable::mem_size() {
-  return sizeof(CodeRootSetTable) + (entry_size() * number_of_entries()) + (sizeof(HashtableBucket<mtGC>) * table_size());
+size_t G1CodeRootSetTable::mem_size() {
+  return sizeof(G1CodeRootSetTable) + (entry_size() * number_of_entries()) + (sizeof(HashtableBucket<mtGC>) * table_size());
 }
 
-CodeRootSetTable::Entry* CodeRootSetTable::new_entry(nmethod* nm) {
+G1CodeRootSetTable::Entry* G1CodeRootSetTable::new_entry(nmethod* nm) {
   unsigned int hash = compute_hash(nm);
   Entry* entry = (Entry*) new_entry_free_list();
   if (entry == NULL) {
@@ -96,7 +52,7 @@
   return entry;
 }
 
-void CodeRootSetTable::remove_entry(Entry* e, Entry* previous) {
+void G1CodeRootSetTable::remove_entry(Entry* e, Entry* previous) {
   int index = hash_to_index(e->hash());
   assert((e == bucket(index)) == (previous == NULL), "if e is the first entry then previous should be null");
 
@@ -108,7 +64,7 @@
   free_entry(e);
 }
 
-CodeRootSetTable::~CodeRootSetTable() {
+G1CodeRootSetTable::~G1CodeRootSetTable() {
   for (int index = 0; index < table_size(); ++index) {
     for (Entry* e = bucket(index); e != NULL; ) {
       Entry* to_remove = e;
@@ -125,7 +81,7 @@
   }
 }
 
-bool CodeRootSetTable::add(nmethod* nm) {
+bool G1CodeRootSetTable::add(nmethod* nm) {
   if (!contains(nm)) {
     Entry* e = new_entry(nm);
     int index = hash_to_index(e->hash());
@@ -135,7 +91,7 @@
   return false;
 }
 
-bool CodeRootSetTable::contains(nmethod* nm) {
+bool G1CodeRootSetTable::contains(nmethod* nm) {
   int index = hash_to_index(compute_hash(nm));
   for (Entry* e = bucket(index); e != NULL; e = e->next()) {
     if (e->literal() == nm) {
@@ -145,7 +101,7 @@
   return false;
 }
 
-bool CodeRootSetTable::remove(nmethod* nm) {
+bool G1CodeRootSetTable::remove(nmethod* nm) {
   int index = hash_to_index(compute_hash(nm));
   Entry* previous = NULL;
   for (Entry* e = bucket(index); e != NULL; previous = e, e = e->next()) {
@@ -157,7 +113,7 @@
   return false;
 }
 
-void CodeRootSetTable::copy_to(CodeRootSetTable* new_table) {
+void G1CodeRootSetTable::copy_to(G1CodeRootSetTable* new_table) {
   for (int index = 0; index < table_size(); ++index) {
     for (Entry* e = bucket(index); e != NULL; e = e->next()) {
       new_table->add(e->literal());
@@ -166,7 +122,7 @@
   new_table->copy_freelist(this);
 }
 
-void CodeRootSetTable::nmethods_do(CodeBlobClosure* blk) {
+void G1CodeRootSetTable::nmethods_do(CodeBlobClosure* blk) {
   for (int index = 0; index < table_size(); ++index) {
     for (Entry* e = bucket(index); e != NULL; e = e->next()) {
       blk->do_code_blob(e->literal());
@@ -175,7 +131,7 @@
 }
 
 template<typename CB>
-int CodeRootSetTable::remove_if(CB& should_remove) {
+int G1CodeRootSetTable::remove_if(CB& should_remove) {
   int num_removed = 0;
   for (int index = 0; index < table_size(); ++index) {
     Entry* previous = NULL;
@@ -198,52 +154,52 @@
   delete _table;
 }
 
-CodeRootSetTable* G1CodeRootSet::load_acquire_table() {
-  return (CodeRootSetTable*) OrderAccess::load_ptr_acquire(&_table);
+G1CodeRootSetTable* G1CodeRootSet::load_acquire_table() {
+  return (G1CodeRootSetTable*) OrderAccess::load_ptr_acquire(&_table);
 }
 
 void G1CodeRootSet::allocate_small_table() {
-  CodeRootSetTable* temp = new CodeRootSetTable(SmallSize);
+  G1CodeRootSetTable* temp = new G1CodeRootSetTable(SmallSize);
 
   OrderAccess::release_store_ptr(&_table, temp);
 }
 
-void CodeRootSetTable::purge_list_append(CodeRootSetTable* table) {
+void G1CodeRootSetTable::purge_list_append(G1CodeRootSetTable* table) {
   for (;;) {
     table->_purge_next = _purge_list;
-    CodeRootSetTable* old = (CodeRootSetTable*) Atomic::cmpxchg_ptr(table, &_purge_list, table->_purge_next);
+    G1CodeRootSetTable* old = (G1CodeRootSetTable*) Atomic::cmpxchg_ptr(table, &_purge_list, table->_purge_next);
     if (old == table->_purge_next) {
       break;
     }
   }
 }
 
-void CodeRootSetTable::purge() {
-  CodeRootSetTable* table = _purge_list;
+void G1CodeRootSetTable::purge() {
+  G1CodeRootSetTable* table = _purge_list;
   _purge_list = NULL;
   while (table != NULL) {
-    CodeRootSetTable* to_purge = table;
+    G1CodeRootSetTable* to_purge = table;
     table = table->_purge_next;
     delete to_purge;
   }
 }
 
 void G1CodeRootSet::move_to_large() {
-  CodeRootSetTable* temp = new CodeRootSetTable(LargeSize);
+  G1CodeRootSetTable* temp = new G1CodeRootSetTable(LargeSize);
 
   _table->copy_to(temp);
 
-  CodeRootSetTable::purge_list_append(_table);
+  G1CodeRootSetTable::purge_list_append(_table);
 
   OrderAccess::release_store_ptr(&_table, temp);
 }
 
 void G1CodeRootSet::purge() {
-  CodeRootSetTable::purge();
+  G1CodeRootSetTable::purge();
 }
 
 size_t G1CodeRootSet::static_mem_size() {
-  return CodeRootSetTable::static_mem_size();
+  return G1CodeRootSetTable::static_mem_size();
 }
 
 void G1CodeRootSet::add(nmethod* method) {
@@ -278,7 +234,7 @@
 }
 
 bool G1CodeRootSet::contains(nmethod* method) {
-  CodeRootSetTable* table = load_acquire_table(); // contains() may be called outside of lock, so ensure mem sync.
+  G1CodeRootSetTable* table = load_acquire_table(); // contains() may be called outside of lock, so ensure mem sync.
   if (table != NULL) {
     return table->contains(method);
   }
@@ -348,67 +304,3 @@
     clear();
   }
 }
-
-#ifndef PRODUCT
-
-class G1CodeRootSetTest {
- public:
-  static void test() {
-    {
-      G1CodeRootSet set1;
-      assert(set1.is_empty(), "Code root set must be initially empty but is not.");
-
-      assert(G1CodeRootSet::static_mem_size() == sizeof(void*),
-             "The code root set's static memory usage is incorrect, " SIZE_FORMAT " bytes", G1CodeRootSet::static_mem_size());
-
-      set1.add((nmethod*)1);
-      assert(set1.length() == 1, "Added exactly one element, but set contains "
-             SIZE_FORMAT " elements", set1.length());
-
-      const size_t num_to_add = (size_t)G1CodeRootSet::Threshold + 1;
-
-      for (size_t i = 1; i <= num_to_add; i++) {
-        set1.add((nmethod*)1);
-      }
-      assert(set1.length() == 1,
-             "Duplicate detection should not have increased the set size but "
-             "is " SIZE_FORMAT, set1.length());
-
-      for (size_t i = 2; i <= num_to_add; i++) {
-        set1.add((nmethod*)(uintptr_t)(i));
-      }
-      assert(set1.length() == num_to_add,
-             "After adding in total " SIZE_FORMAT " distinct code roots, they "
-             "need to be in the set, but there are only " SIZE_FORMAT,
-             num_to_add, set1.length());
-
-      assert(CodeRootSetTable::_purge_list != NULL, "should have grown to large hashtable");
-
-      size_t num_popped = 0;
-      for (size_t i = 1; i <= num_to_add; i++) {
-        bool removed = set1.remove((nmethod*)i);
-        if (removed) {
-          num_popped += 1;
-        } else {
-          break;
-        }
-      }
-      assert(num_popped == num_to_add,
-             "Managed to pop " SIZE_FORMAT " code roots, but only " SIZE_FORMAT " "
-             "were added", num_popped, num_to_add);
-      assert(CodeRootSetTable::_purge_list != NULL, "should have grown to large hashtable");
-
-      G1CodeRootSet::purge();
-
-      assert(CodeRootSetTable::_purge_list == NULL, "should have purged old small tables");
-
-    }
-
-  }
-};
-
-void TestCodeCacheRemSet_test() {
-  G1CodeRootSetTest::test();
-}
-
-#endif
--- a/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
 #include "memory/allocation.hpp"
 
 class CodeBlobClosure;
-class CodeRootSetTable;
+class G1CodeRootSetTable;
 class HeapRegion;
 class nmethod;
 
@@ -42,8 +42,8 @@
   const static size_t Threshold = 24;
   const static size_t LargeSize = 512;
 
-  CodeRootSetTable* _table;
-  CodeRootSetTable* load_acquire_table();
+  G1CodeRootSetTable* _table;
+  G1CodeRootSetTable* load_acquire_table();
 
   size_t _length;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CodeRootSetTable.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef SHARE_VM_GC_G1_G1CODEROOTSETTABLE_HPP
+#define SHARE_VM_GC_G1_G1CODEROOTSETTABLE_HPP
+
+#include "utilities/hashtable.hpp"
+
+class nmethod;
+
+class G1CodeRootSetTable : public Hashtable<nmethod*, mtGC> {
+  friend class G1CodeRootSetTest;
+  typedef HashtableEntry<nmethod*, mtGC> Entry;
+
+  static G1CodeRootSetTable* volatile _purge_list;
+
+  G1CodeRootSetTable* _purge_next;
+
+  unsigned int compute_hash(nmethod* nm) {
+    uintptr_t hash = (uintptr_t)nm;
+    return hash ^ (hash >> 7); // code heap blocks are 128byte aligned
+  }
+
+  void remove_entry(Entry* e, Entry* previous);
+  Entry* new_entry(nmethod* nm);
+
+ public:
+  G1CodeRootSetTable(int size) : Hashtable<nmethod*, mtGC>(size, sizeof(Entry)), _purge_next(NULL) {}
+  ~G1CodeRootSetTable();
+
+  // Needs to be protected by locks
+  bool add(nmethod* nm);
+  bool remove(nmethod* nm);
+
+  // Can be called without locking
+  bool contains(nmethod* nm);
+
+  int entry_size() const { return BasicHashtable<mtGC>::entry_size(); }
+
+  void copy_to(G1CodeRootSetTable* new_table);
+  void nmethods_do(CodeBlobClosure* blk);
+
+  template<typename CB>
+  int remove_if(CB& should_remove);
+
+  static void purge_list_append(G1CodeRootSetTable* tbl);
+  static void purge();
+
+  static size_t static_mem_size() {
+    return sizeof(_purge_list);
+  }
+
+  size_t mem_size();
+};
+
+#endif /* SHARE_VM_GC_G1_G1CODEROOTSETTABLE_HPP */
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -1273,12 +1273,6 @@
     return true;
   }
 
-  // The reference pending list lock is acquired from from the
-  // ConcurrentMarkThread.
-  virtual bool needs_reference_pending_list_locker_thread() const {
-    return true;
-  }
-
   inline bool is_in_young(const oop obj);
 
   virtual bool is_scavengable(const void* addr);
--- a/hotspot/src/share/vm/gc/g1/g1Predictions.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc/g1/g1Predictions.hpp"
-
-#ifndef PRODUCT
-
-void G1Predictions::test() {
-  double const epsilon = 1e-6;
-  {
-    // Some basic formula tests with confidence = 0.0
-    G1Predictions predictor(0.0);
-    TruncatedSeq s;
-
-    double p0 = predictor.get_new_prediction(&s);
-    assert(p0 < epsilon, "Initial prediction of empty sequence must be 0.0 but is %f", p0);
-
-    s.add(5.0);
-    double p1 = predictor.get_new_prediction(&s);
-    assert(fabs(p1 - 5.0) < epsilon, "Prediction should be 5.0 but is %f", p1);
-    for (int i = 0; i < 40; i++) {
-      s.add(5.0);
-    }
-    double p2 = predictor.get_new_prediction(&s);
-    assert(fabs(p2 - 5.0) < epsilon, "Prediction should be 5.0 but is %f", p1);
-  }
-
-  {
-    // The following tests checks that the initial predictions are based on the
-    // average of the sequence and not on the stddev (which is 0).
-    G1Predictions predictor(0.5);
-    TruncatedSeq s;
-
-    s.add(1.0);
-    double p1 = predictor.get_new_prediction(&s);
-    assert(p1 > 1.0, "First prediction must be larger than average, but avg is %f and prediction %f", s.davg(), p1);
-    s.add(1.0);
-    double p2 = predictor.get_new_prediction(&s);
-    assert(p2 < p1, "First prediction must be larger than second, but they are %f %f", p1, p2);
-    s.add(1.0);
-    double p3 = predictor.get_new_prediction(&s);
-    assert(p3 < p2, "Second prediction must be larger than third, but they are %f %f", p2, p3);
-    s.add(1.0);
-    s.add(1.0); // Five elements are now in the sequence.
-    double p5 = predictor.get_new_prediction(&s);
-    assert(p5 < p3, "Fifth prediction must be smaller than third, but they are %f %f", p3, p5);
-    assert(fabs(p5 - 1.0) < epsilon, "Prediction must be 1.0+epsilon, but is %f", p5);
-  }
-
-  {
-    // The following tests checks that initially prediction based on the average is
-    // used, that gets overridden by the stddev prediction at the end.
-    G1Predictions predictor(0.5);
-    TruncatedSeq s;
-
-    s.add(0.5);
-    double p1 = predictor.get_new_prediction(&s);
-    assert(p1 > 0.5, "First prediction must be larger than average, but avg is %f and prediction %f", s.davg(), p1);
-    s.add(0.2);
-    double p2 = predictor.get_new_prediction(&s);
-    assert(p2 < p1, "First prediction must be larger than second, but they are %f %f", p1, p2);
-    s.add(0.5);
-    double p3 = predictor.get_new_prediction(&s);
-    assert(p3 < p2, "Second prediction must be larger than third, but they are %f %f", p2, p3);
-    s.add(0.2);
-    s.add(2.0);
-    double p5 = predictor.get_new_prediction(&s);
-    assert(p5 > p3, "Fifth prediction must be bigger than third, but they are %f %f", p3, p5);
-  }
-}
-
-void TestPredictions_test() {
-  G1Predictions::test();
-}
-
-#endif
--- a/hotspot/src/share/vm/gc/g1/g1Predictions.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1Predictions.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -57,10 +57,6 @@
   double get_new_prediction(TruncatedSeq const* seq) const {
     return seq->davg() + _sigma * stddev_estimate(seq);
   }
-
-#ifndef PRODUCT
-  static void test();
-#endif
 };
 
 #endif // SHARE_VM_GC_G1_G1PREDICTIONS_HPP
--- a/hotspot/src/share/vm/gc/g1/vm_operations_g1.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/vm_operations_g1.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -204,14 +204,6 @@
   }
 }
 
-void VM_CGC_Operation::acquire_pending_list_lock() {
-  _pending_list_locker.lock();
-}
-
-void VM_CGC_Operation::release_and_notify_pending_list_lock() {
-  _pending_list_locker.unlock();
-}
-
 void VM_CGC_Operation::doit() {
   GCIdMark gc_id_mark(_gc_id);
   GCTraceCPUTime tcpu;
@@ -222,20 +214,13 @@
 }
 
 bool VM_CGC_Operation::doit_prologue() {
-  // Note the relative order of the locks must match that in
-  // VM_GC_Operation::doit_prologue() or deadlocks can occur
-  if (_needs_pending_list_lock) {
-    acquire_pending_list_lock();
-  }
   Heap_lock->lock();
   return true;
 }
 
 void VM_CGC_Operation::doit_epilogue() {
-  // Note the relative order of the unlocks must match that in
-  // VM_GC_Operation::doit_epilogue()
+  if (Universe::has_reference_pending_list()) {
+    Heap_lock->notify_all();
+  }
   Heap_lock->unlock();
-  if (_needs_pending_list_lock) {
-    release_and_notify_pending_list_lock();
-  }
 }
--- a/hotspot/src/share/vm/gc/g1/vm_operations_g1.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/vm_operations_g1.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -27,7 +27,6 @@
 
 #include "gc/g1/g1AllocationContext.hpp"
 #include "gc/shared/gcId.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
 #include "gc/shared/vmGCOperations.hpp"
 
 // VM_operations for the G1 collector.
@@ -103,20 +102,13 @@
 // Concurrent GC stop-the-world operations such as remark and cleanup;
 // consider sharing these with CMS's counterparts.
 class VM_CGC_Operation: public VM_Operation {
-  VoidClosure*               _cl;
-  const char*                _printGCMessage;
-  bool                       _needs_pending_list_lock;
-  ReferencePendingListLocker _pending_list_locker;
-  uint                       _gc_id;
-
-protected:
-  // java.lang.ref.Reference support
-  void acquire_pending_list_lock();
-  void release_and_notify_pending_list_lock();
+  VoidClosure* _cl;
+  const char*  _printGCMessage;
+  uint         _gc_id;
 
 public:
-  VM_CGC_Operation(VoidClosure* cl, const char *printGCMsg, bool needs_pending_list_lock)
-    : _cl(cl), _printGCMessage(printGCMsg), _needs_pending_list_lock(needs_pending_list_lock), _gc_id(GCId::current()) {}
+  VM_CGC_Operation(VoidClosure* cl, const char *printGCMsg)
+    : _cl(cl), _printGCMessage(printGCMsg), _gc_id(GCId::current()) {}
   virtual VMOp_Type type() const { return VMOp_CGC_Operation; }
   virtual void doit();
   virtual bool doit_prologue();
--- a/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1133,18 +1133,3 @@
 
   return false;
 }
-
-#ifndef PRODUCT
-
-void TestOldFreeSpaceCalculation_test() {
-  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 20) == 25, "Calculation of free memory failed");
-  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 50) == 100, "Calculation of free memory failed");
-  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 60) == 150, "Calculation of free memory failed");
-  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 75) == 300, "Calculation of free memory failed");
-  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 20) == 100, "Calculation of free memory failed");
-  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 50) == 400, "Calculation of free memory failed");
-  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 60) == 600, "Calculation of free memory failed");
-  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 75) == 1200, "Calculation of free memory failed");
-}
-
-#endif /* !PRODUCT */
--- a/hotspot/src/share/vm/gc/shared/collectedHeap.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/collectedHeap.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -441,12 +441,6 @@
   // remembered set.
   virtual void flush_deferred_store_barrier(JavaThread* thread);
 
-  // Should return true if the reference pending list lock is
-  // acquired from non-Java threads, such as a concurrent GC thread.
-  virtual bool needs_reference_pending_list_locker_thread() const {
-    return false;
-  }
-
   // Perform a collection of the heap; intended for use in implementing
   // "System.gc".  This probably implies as full a collection as the
   // "CollectedHeap" supports.
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -281,10 +281,6 @@
     return UseConcMarkSweepGC;
   }
 
-  virtual bool needs_reference_pending_list_locker_thread() const {
-    return UseConcMarkSweepGC;
-  }
-
   // We don't need barriers for stores to objects in the
   // young gen and, a fortiori, for initializing stores to
   // objects therein. This applies to DefNew+Tenured and ParNew+CMS
--- a/hotspot/src/share/vm/gc/shared/referencePendingListLocker.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "classfile/javaClasses.hpp"
-#include "classfile/systemDictionary.hpp"
-#include "gc/shared/collectedHeap.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
-#include "memory/universe.hpp"
-#include "runtime/javaCalls.hpp"
-#include "utilities/preserveException.hpp"
-
-ReferencePendingListLockerThread::ReferencePendingListLockerThread() :
-  JavaThread(&start),
-  _monitor(Monitor::nonleaf, "ReferencePendingListLocker", false, Monitor::_safepoint_check_sometimes),
-  _message(NONE) {}
-
-ReferencePendingListLockerThread* ReferencePendingListLockerThread::create(TRAPS) {
-  // Create Java thread objects
-  instanceKlassHandle thread_klass = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_NULL);
-  instanceHandle thread_object = thread_klass->allocate_instance_handle(CHECK_NULL);
-  Handle thread_name = java_lang_String::create_from_str("Reference Pending List Locker", CHECK_NULL);
-  Handle thread_group = Universe::system_thread_group();
-  JavaValue result(T_VOID);
-  JavaCalls::call_special(&result,
-                          thread_object,
-                          thread_klass,
-                          vmSymbols::object_initializer_name(),
-                          vmSymbols::threadgroup_string_void_signature(),
-                          thread_group,
-                          thread_name,
-                          CHECK_NULL);
-
-  {
-    MutexLocker ml(Threads_lock);
-
-    // Allocate thread
-    ReferencePendingListLockerThread* thread = new ReferencePendingListLockerThread();
-    if (thread == NULL || thread->osthread() == NULL) {
-      vm_exit_during_initialization("java.lang.OutOfMemoryError",
-                                    os::native_thread_creation_failed_msg());
-    }
-
-    // Initialize thread
-    java_lang_Thread::set_thread(thread_object(), thread);
-    java_lang_Thread::set_priority(thread_object(), NearMaxPriority);
-    java_lang_Thread::set_daemon(thread_object());
-    thread->set_threadObj(thread_object());
-
-    // Start thread
-    Threads::add(thread);
-    Thread::start(thread);
-
-    return thread;
-  }
-}
-
-void ReferencePendingListLockerThread::start(JavaThread* thread, TRAPS) {
-  ReferencePendingListLockerThread* locker_thread = static_cast<ReferencePendingListLockerThread*>(thread);
-  locker_thread->receive_and_handle_messages();
-}
-
-bool ReferencePendingListLockerThread::is_hidden_from_external_view() const {
-  return true;
-}
-
-void ReferencePendingListLockerThread::send_message(Message message) {
-  assert(message != NONE, "Should not be none");
-  MonitorLockerEx ml(&_monitor, Monitor::_no_safepoint_check_flag);
-
-  // Wait for completion of current message
-  while (_message != NONE) {
-    ml.wait(Monitor::_no_safepoint_check_flag);
-  }
-
-  // Send new message
-  _message = message;
-  ml.notify_all();
-
-  // Wait for completion of new message
-  while (_message != NONE) {
-    ml.wait(Monitor::_no_safepoint_check_flag);
-  }
-}
-
-void ReferencePendingListLockerThread::receive_and_handle_messages() {
-  ReferencePendingListLocker pending_list_locker;
-  MonitorLockerEx ml(&_monitor);
-
-  // Main loop, never terminates
-  for (;;) {
-    // Wait for message
-    while (_message == NONE) {
-      ml.wait();
-    }
-
-    // Handle message
-    if (_message == LOCK) {
-      pending_list_locker.lock();
-    } else if (_message == UNLOCK) {
-      pending_list_locker.unlock();
-    } else {
-      ShouldNotReachHere();
-    }
-
-    // Clear message
-    _message = NONE;
-    ml.notify_all();
-  }
-}
-
-void ReferencePendingListLockerThread::lock() {
-  send_message(LOCK);
-}
-
-void ReferencePendingListLockerThread::unlock() {
-  send_message(UNLOCK);
-}
-
-bool ReferencePendingListLocker::_is_initialized = false;
-ReferencePendingListLockerThread* ReferencePendingListLocker::_locker_thread = NULL;
-
-void ReferencePendingListLocker::initialize(bool needs_locker_thread, TRAPS) {
-  if (needs_locker_thread) {
-    _locker_thread = ReferencePendingListLockerThread::create(CHECK);
-  }
-
-  _is_initialized = true;
-}
-
-bool ReferencePendingListLocker::is_initialized() {
-  return _is_initialized;
-}
-
-bool ReferencePendingListLocker::is_locked_by_self() {
-  oop pending_list_lock = java_lang_ref_Reference::pending_list_lock();
-  if (pending_list_lock == NULL) {
-    return false;
-  }
-
-  JavaThread* thread = JavaThread::current();
-  Handle handle(thread, pending_list_lock);
-  return ObjectSynchronizer::current_thread_holds_lock(thread, handle);
-}
-
-void ReferencePendingListLocker::lock() {
-  assert(!Heap_lock->owned_by_self(), "Heap_lock must not be owned by requesting thread");
-
-  if (Thread::current()->is_Java_thread()) {
-    assert(java_lang_ref_Reference::pending_list_lock() != NULL, "Not initialized");
-
-    // We may enter this with a pending exception
-    PRESERVE_EXCEPTION_MARK;
-
-    HandleMark hm;
-    Handle handle(THREAD, java_lang_ref_Reference::pending_list_lock());
-
-    // Lock
-    ObjectSynchronizer::fast_enter(handle, &_basic_lock, false, THREAD);
-
-    assert(is_locked_by_self(), "Locking failed");
-
-    if (HAS_PENDING_EXCEPTION) {
-      CLEAR_PENDING_EXCEPTION;
-    }
-  } else {
-    // Delegate operation to locker thread
-    assert(_locker_thread != NULL, "Locker thread not created");
-    _locker_thread->lock();
-  }
-}
-
-void ReferencePendingListLocker::unlock() {
-  if (Thread::current()->is_Java_thread()) {
-    assert(java_lang_ref_Reference::pending_list_lock() != NULL, "Not initialized");
-
-    // We may enter this with a pending exception
-    PRESERVE_EXCEPTION_MARK;
-
-    HandleMark hm;
-    Handle handle(THREAD, java_lang_ref_Reference::pending_list_lock());
-
-    assert(is_locked_by_self(), "Should be locked by self");
-
-    // Notify waiters if the pending list is non-empty
-    if (java_lang_ref_Reference::pending_list() != NULL) {
-      ObjectSynchronizer::notifyall(handle, THREAD);
-    }
-
-    // Unlock
-    ObjectSynchronizer::fast_exit(handle(), &_basic_lock, THREAD);
-
-    if (HAS_PENDING_EXCEPTION) {
-      CLEAR_PENDING_EXCEPTION;
-    }
-  } else {
-    // Delegate operation to locker thread
-    assert(_locker_thread != NULL, "Locker thread not created");
-    _locker_thread->unlock();
-  }
-}
--- a/hotspot/src/share/vm/gc/shared/referencePendingListLocker.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_GC_SHARED_REFERENCEPENDINGLISTLOCKER_HPP
-#define SHARE_VM_GC_SHARED_REFERENCEPENDINGLISTLOCKER_HPP
-
-#include "memory/allocation.hpp"
-#include "runtime/basicLock.hpp"
-#include "runtime/mutex.hpp"
-#include "runtime/thread.hpp"
-#include "utilities/exceptions.hpp"
-
-//
-// The ReferencePendingListLockerThread locks and unlocks the reference
-// pending list lock on behalf a non-Java thread, typically a concurrent
-// GC thread. This interface should not be directly accessed. All uses
-// should instead go through the ReferencePendingListLocker, which calls
-// this thread if needed.
-//
-class ReferencePendingListLockerThread : public JavaThread {
-private:
-  enum Message {
-    NONE,
-    LOCK,
-    UNLOCK
-  };
-
-  Monitor _monitor;
-  Message _message;
-
-  ReferencePendingListLockerThread();
-
-  static void start(JavaThread* thread, TRAPS);
-
-  void send_message(Message message);
-  void receive_and_handle_messages();
-
-public:
-  static ReferencePendingListLockerThread* create(TRAPS);
-
-  virtual bool is_hidden_from_external_view() const;
-
-  void lock();
-  void unlock();
-};
-
-//
-// The ReferencePendingListLocker is the main interface for locking and
-// unlocking the reference pending list lock, which needs to be held by
-// the GC when adding references to the pending list. Since this is a
-// Java-level monitor it can only be locked/unlocked by a Java thread.
-// For this reason there is an option to spawn a helper thread, the
-// ReferencePendingListLockerThread, during initialization. If a helper
-// thread is spawned all lock operations from non-Java threads will be
-// delegated to the helper thread. The helper thread is typically needed
-// by concurrent GCs.
-//
-class ReferencePendingListLocker VALUE_OBJ_CLASS_SPEC {
-private:
-  static bool                              _is_initialized;
-  static ReferencePendingListLockerThread* _locker_thread;
-  BasicLock                                _basic_lock;
-
-public:
-  static void initialize(bool needs_locker_thread, TRAPS);
-  static bool is_initialized();
-
-  static bool is_locked_by_self();
-
-  void lock();
-  void unlock();
-};
-
-#endif // SHARE_VM_GC_SHARED_REFERENCEPENDINGLISTLOCKER_HPP
--- a/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -289,39 +289,16 @@
   complete_gc->do_void();
 }
 
-
-template <class T>
-bool enqueue_discovered_ref_helper(ReferenceProcessor* ref,
-                                   AbstractRefProcTaskExecutor* task_executor) {
-
-  // Remember old value of pending references list
-  T* pending_list_addr = (T*)java_lang_ref_Reference::pending_list_addr();
-  T old_pending_list_value = *pending_list_addr;
-
+void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) {
   // Enqueue references that are not made active again, and
   // clear the decks for the next collection (cycle).
-  ref->enqueue_discovered_reflists((HeapWord*)pending_list_addr, task_executor);
-  // Do the post-barrier on pending_list_addr missed in
-  // enqueue_discovered_reflist.
-  oopDesc::bs()->write_ref_field(pending_list_addr, oopDesc::load_decode_heap_oop(pending_list_addr));
+  enqueue_discovered_reflists(task_executor);
 
   // Stop treating discovered references specially.
-  ref->disable_discovery();
-
-  // Return true if new pending references were added
-  return old_pending_list_value != *pending_list_addr;
+  disable_discovery();
 }
 
-bool ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) {
-  if (UseCompressedOops) {
-    return enqueue_discovered_ref_helper<narrowOop>(this, task_executor);
-  } else {
-    return enqueue_discovered_ref_helper<oop>(this, task_executor);
-  }
-}
-
-void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list,
-                                                    HeapWord* pending_list_addr) {
+void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list) {
   // Given a list of refs linked through the "discovered" field
   // (java.lang.ref.Reference.discovered), self-loop their "next" field
   // thus distinguishing them from active References, then
@@ -354,10 +331,9 @@
       oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), next_d);
     } else {
       // This is the last object.
-      // Swap refs_list into pending_list_addr and
-      // set obj's discovered to what we read from pending_list_addr.
-      oop old = oopDesc::atomic_exchange_oop(refs_list.head(), pending_list_addr);
-      // Need post-barrier on pending_list_addr. See enqueue_discovered_ref_helper() above.
+      // Swap refs_list into pending list and set obj's
+      // discovered to what we read from the pending list.
+      oop old = Universe::swap_reference_pending_list(refs_list.head());
       java_lang_ref_Reference::set_discovered_raw(obj, old); // old may be NULL
       oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), old);
     }
@@ -369,10 +345,8 @@
 public:
   RefProcEnqueueTask(ReferenceProcessor& ref_processor,
                      DiscoveredList      discovered_refs[],
-                     HeapWord*           pending_list_addr,
                      int                 n_queues)
-    : EnqueueTask(ref_processor, discovered_refs,
-                  pending_list_addr, n_queues)
+    : EnqueueTask(ref_processor, discovered_refs, n_queues)
   { }
 
   virtual void work(unsigned int work_id) {
@@ -387,8 +361,7 @@
     for (int j = 0;
          j < ReferenceProcessor::number_of_subclasses_of_ref();
          j++, index += _n_queues) {
-      _ref_processor.enqueue_discovered_reflist(
-        _refs_lists[index], _pending_list_addr);
+      _ref_processor.enqueue_discovered_reflist(_refs_lists[index]);
       _refs_lists[index].set_head(NULL);
       _refs_lists[index].set_length(0);
     }
@@ -396,17 +369,15 @@
 };
 
 // Enqueue references that are not made active again
-void ReferenceProcessor::enqueue_discovered_reflists(HeapWord* pending_list_addr,
-  AbstractRefProcTaskExecutor* task_executor) {
+void ReferenceProcessor::enqueue_discovered_reflists(AbstractRefProcTaskExecutor* task_executor) {
   if (_processing_is_mt && task_executor != NULL) {
     // Parallel code
-    RefProcEnqueueTask tsk(*this, _discovered_refs,
-                           pending_list_addr, _max_num_q);
+    RefProcEnqueueTask tsk(*this, _discovered_refs, _max_num_q);
     task_executor->execute(tsk);
   } else {
     // Serial code: call the parent class's implementation
     for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
-      enqueue_discovered_reflist(_discovered_refs[i], pending_list_addr);
+      enqueue_discovered_reflist(_discovered_refs[i]);
       _discovered_refs[i].set_head(NULL);
       _discovered_refs[i].set_length(0);
     }
--- a/hotspot/src/share/vm/gc/shared/referenceProcessor.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -290,7 +290,7 @@
                       VoidClosure*       complete_gc);
 
   // Enqueue references with a certain reachability level
-  void enqueue_discovered_reflist(DiscoveredList& refs_list, HeapWord* pending_list_addr);
+  void enqueue_discovered_reflist(DiscoveredList& refs_list);
 
   // "Preclean" all the discovered reference lists
   // by removing references with strongly reachable referents.
@@ -311,7 +311,7 @@
   // occupying the i / _num_q slot.
   const char* list_name(uint i);
 
-  void enqueue_discovered_reflists(HeapWord* pending_list_addr, AbstractRefProcTaskExecutor* task_executor);
+  void enqueue_discovered_reflists(AbstractRefProcTaskExecutor* task_executor);
 
  protected:
   // "Preclean" the given discovered reference list
@@ -424,7 +424,7 @@
                                 GCTimer *gc_timer);
 
   // Enqueue references at end of GC (called by the garbage collector)
-  bool enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor = NULL);
+  void enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor = NULL);
 
   // If a discovery is in process that is being superceded, abandon it: all
   // the discovered lists will be empty, and all the objects on them will
@@ -613,11 +613,9 @@
 protected:
   EnqueueTask(ReferenceProcessor& ref_processor,
               DiscoveredList      refs_lists[],
-              HeapWord*           pending_list_addr,
               int                 n_queues)
     : _ref_processor(ref_processor),
       _refs_lists(refs_lists),
-      _pending_list_addr(pending_list_addr),
       _n_queues(n_queues)
   { }
 
@@ -627,7 +625,6 @@
 protected:
   ReferenceProcessor& _ref_processor;
   DiscoveredList*     _refs_lists;
-  HeapWord*           _pending_list_addr;
   int                 _n_queues;
 };
 
--- a/hotspot/src/share/vm/gc/shared/space.inline.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/space.inline.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -293,10 +293,11 @@
 
   verify_up_to_first_dead(space);
 
+  HeapWord* const bottom = space->bottom();
   HeapWord* const end_of_live = space->_end_of_live;
 
   assert(space->_first_dead <= end_of_live, "Invariant. _first_dead: " PTR_FORMAT " <= end_of_live: " PTR_FORMAT, p2i(space->_first_dead), p2i(end_of_live));
-  if (space->_first_dead == end_of_live && !oop(space->bottom())->is_gc_marked()) {
+  if (space->_first_dead == end_of_live && (bottom == end_of_live || !oop(bottom)->is_gc_marked())) {
     // Nothing to compact. The space is either empty or all live object should be left in place.
     clear_empty_region(space);
     return;
@@ -305,8 +306,8 @@
   const intx scan_interval = PrefetchScanIntervalInBytes;
   const intx copy_interval = PrefetchCopyIntervalInBytes;
 
-  assert(space->bottom() < end_of_live, "bottom: " PTR_FORMAT " should be < end_of_live: " PTR_FORMAT, p2i(space->bottom()), p2i(end_of_live));
-  HeapWord* cur_obj = space->bottom();
+  assert(bottom < end_of_live, "bottom: " PTR_FORMAT " should be < end_of_live: " PTR_FORMAT, p2i(bottom), p2i(end_of_live));
+  HeapWord* cur_obj = bottom;
   if (space->_first_dead > cur_obj && !oop(cur_obj)->is_gc_marked()) {
     // All object before _first_dead can be skipped. They should not be moved.
     // A pointer to the first live object is stored at the memory location for _first_dead.
--- a/hotspot/src/share/vm/gc/shared/vmGCOperations.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/vmGCOperations.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -62,14 +62,6 @@
   HS_DTRACE_WORKAROUND_TAIL_CALL_BUG();
 }
 
-void VM_GC_Operation::acquire_pending_list_lock() {
-  _pending_list_locker.lock();
-}
-
-void VM_GC_Operation::release_and_notify_pending_list_lock() {
-  _pending_list_locker.unlock();
-}
-
 // Allocations may fail in several threads at about the same time,
 // resulting in multiple gc requests.  We only want to do one of them.
 // In case a GC locker is active and the need for a GC is already signaled,
@@ -102,16 +94,13 @@
               proper_unit_for_byte_size(NewSize)));
   }
 
-  acquire_pending_list_lock();
   // If the GC count has changed someone beat us to the collection
-  // Get the Heap_lock after the pending_list_lock.
   Heap_lock->lock();
 
   // Check invocations
   if (skip_operation()) {
     // skip collection
     Heap_lock->unlock();
-    release_and_notify_pending_list_lock();
     _prologue_succeeded = false;
   } else {
     _prologue_succeeded = true;
@@ -122,9 +111,10 @@
 
 void VM_GC_Operation::doit_epilogue() {
   assert(Thread::current()->is_Java_thread(), "just checking");
-  // Release the Heap_lock first.
+  if (Universe::has_reference_pending_list()) {
+    Heap_lock->notify_all();
+  }
   Heap_lock->unlock();
-  release_and_notify_pending_list_lock();
 }
 
 bool VM_GC_HeapInspection::skip_operation() const {
--- a/hotspot/src/share/vm/gc/shared/vmGCOperations.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/vmGCOperations.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -27,7 +27,6 @@
 
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
 #include "memory/heapInspection.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/handles.hpp"
@@ -70,9 +69,6 @@
 //
 
 class VM_GC_Operation: public VM_Operation {
- private:
-  ReferencePendingListLocker _pending_list_locker;
-
  protected:
   uint           _gc_count_before;         // gc count before acquiring PLL
   uint           _full_gc_count_before;    // full gc count before acquiring PLL
@@ -83,10 +79,6 @@
 
   virtual bool skip_operation() const;
 
-  // java.lang.ref.Reference support
-  void acquire_pending_list_lock();
-  void release_and_notify_pending_list_lock();
-
  public:
   VM_GC_Operation(uint gc_count_before,
                   GCCause::Cause _cause,
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -203,6 +203,40 @@
 #undef SET_TRIGFUNC
 }
 
+objArrayHandle CompilerToVM::initialize_intrinsics(TRAPS) {
+  objArrayHandle vmIntrinsics = oopFactory::new_objArray(VMIntrinsicMethod::klass(), (vmIntrinsics::ID_LIMIT - 1), CHECK_(objArrayHandle()));
+  int index = 0;
+  // The intrinsics for a class are usually adjacent to each other.
+  // When they are, the string for the class name can be reused.
+  vmSymbols::SID kls_sid = vmSymbols::NO_SID;
+  Handle kls_str;
+#define SID_ENUM(n) vmSymbols::VM_SYMBOL_ENUM_NAME(n)
+#define VM_SYMBOL_TO_STRING(s) \
+  java_lang_String::create_from_symbol(vmSymbols::symbol_at(SID_ENUM(s)), CHECK_(objArrayHandle()))
+#define VM_INTRINSIC_INFO(id, kls, name, sig, ignore_fcode) {             \
+    instanceHandle vmIntrinsicMethod = InstanceKlass::cast(VMIntrinsicMethod::klass())->allocate_instance_handle(CHECK_(objArrayHandle())); \
+    if (kls_sid != SID_ENUM(kls)) {                                       \
+      kls_str = VM_SYMBOL_TO_STRING(kls);                                 \
+      kls_sid = SID_ENUM(kls);                                            \
+    }                                                                     \
+    Handle name_str = VM_SYMBOL_TO_STRING(name);                          \
+    Handle sig_str = VM_SYMBOL_TO_STRING(sig);                            \
+    VMIntrinsicMethod::set_declaringClass(vmIntrinsicMethod, kls_str());  \
+    VMIntrinsicMethod::set_name(vmIntrinsicMethod, name_str());           \
+    VMIntrinsicMethod::set_descriptor(vmIntrinsicMethod, sig_str());      \
+    VMIntrinsicMethod::set_id(vmIntrinsicMethod, vmIntrinsics::id);       \
+      vmIntrinsics->obj_at_put(index++, vmIntrinsicMethod());             \
+  }
+
+  VM_INTRINSICS_DO(VM_INTRINSIC_INFO, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE)
+#undef SID_ENUM
+#undef VM_SYMBOL_TO_STRING
+#undef VM_INTRINSIC_INFO
+  assert(index == vmIntrinsics::ID_LIMIT - 1, "must be");
+
+  return vmIntrinsics;
+}
+
 C2V_VMENTRY(jobjectArray, readConfiguration, (JNIEnv *env))
 #define BOXED_LONG(name, value) oop name; do { jvalue p; p.j = (jlong) (value); name = java_lang_boxing_object::create(T_LONG, &p, CHECK_NULL);} while(0)
 #define BOXED_DOUBLE(name, value) oop name; do { jvalue p; p.d = (jdouble) (value); name = java_lang_boxing_object::create(T_DOUBLE, &p, CHECK_NULL);} while(0)
@@ -211,8 +245,9 @@
 
   CompilerToVM::Data::initialize();
 
-  VMField::klass()->initialize(thread);
-  VMFlag::klass()->initialize(thread);
+  VMField::klass()->initialize(CHECK_NULL);
+  VMFlag::klass()->initialize(CHECK_NULL);
+  VMIntrinsicMethod::klass()->initialize(CHECK_NULL);
 
   int len = JVMCIVMStructs::localHotSpotVMStructs_count();
   objArrayHandle vmFields = oopFactory::new_objArray(VMField::klass(), len, CHECK_NULL);
@@ -220,7 +255,7 @@
     VMStructEntry vmField = JVMCIVMStructs::localHotSpotVMStructs[i];
     instanceHandle vmFieldObj = InstanceKlass::cast(VMField::klass())->allocate_instance_handle(CHECK_NULL);
     size_t name_buf_len = strlen(vmField.typeName) + strlen(vmField.fieldName) + 2 /* "::" */;
-    char* name_buf = NEW_RESOURCE_ARRAY(char, name_buf_len + 1);
+    char* name_buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, name_buf_len + 1);
     sprintf(name_buf, "%s::%s", vmField.typeName, vmField.fieldName);
     Handle name = java_lang_String::create_from_str(name_buf, CHECK_NULL);
     Handle type = java_lang_String::create_from_str(vmField.typeString, CHECK_NULL);
@@ -338,12 +373,15 @@
     vmFlags->obj_at_put(i, vmFlagObj());
   }
 
-  objArrayOop data = oopFactory::new_objArray(SystemDictionary::Object_klass(), 5, CHECK_NULL);
+  objArrayHandle vmIntrinsics = CompilerToVM::initialize_intrinsics(CHECK_NULL);
+
+  objArrayOop data = oopFactory::new_objArray(SystemDictionary::Object_klass(), 6, CHECK_NULL);
   data->obj_at_put(0, vmFields());
   data->obj_at_put(1, vmTypes());
   data->obj_at_put(2, vmConstants());
   data->obj_at_put(3, vmAddresses());
   data->obj_at_put(4, vmFlags());
+  data->obj_at_put(5, vmIntrinsics());
 
   return (jobjectArray) JNIHandles::make_local(THREAD, data);
 #undef BOXED_LONG
@@ -1266,10 +1304,23 @@
 
 C2V_VMENTRY(void, resolveInvokeHandleInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
   constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
-  CallInfo callInfo;
-  LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokehandle, CHECK);
-  ConstantPoolCacheEntry* cp_cache_entry = cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));
-  cp_cache_entry->set_method_handle(cp, callInfo);
+  KlassHandle holder = cp->klass_ref_at(index, CHECK);
+  Symbol* name = cp->name_ref_at(index);
+  if (MethodHandles::is_signature_polymorphic_name(holder(), name)) {
+    CallInfo callInfo;
+    LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokehandle, CHECK);
+    ConstantPoolCacheEntry* cp_cache_entry = cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));
+    cp_cache_entry->set_method_handle(cp, callInfo);
+  }
+C2V_END
+
+C2V_VMENTRY(jobject, getSignaturePolymorphicHolders, (JNIEnv*, jobject))
+  objArrayHandle holders = oopFactory::new_objArray(SystemDictionary::String_klass(), 2, CHECK_NULL);
+  Handle mh = java_lang_String::create_from_str("Ljava/lang/invoke/MethodHandle;", CHECK_NULL);
+  Handle vh = java_lang_String::create_from_str("Ljava/lang/invoke/VarHandle;", CHECK_NULL);
+  holders->obj_at_put(0, mh());
+  holders->obj_at_put(1, vh());
+  return JNIHandles::make_local(THREAD, holders());
 C2V_END
 
 C2V_VMENTRY(jboolean, shouldDebugNonSafepoints, (JNIEnv*, jobject))
@@ -1511,6 +1562,7 @@
   {CC "resolveInvokeDynamicInPool",                   CC "(" HS_CONSTANT_POOL "I)V",                                                        FN_PTR(resolveInvokeDynamicInPool)},
   {CC "resolveInvokeHandleInPool",                    CC "(" HS_CONSTANT_POOL "I)V",                                                        FN_PTR(resolveInvokeHandleInPool)},
   {CC "resolveMethod",                                CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD HS_RESOLVED_KLASS ")" HS_RESOLVED_METHOD, FN_PTR(resolveMethod)},
+  {CC "getSignaturePolymorphicHolders",               CC "()[" STRING,                                                                      FN_PTR(getSignaturePolymorphicHolders)},
   {CC "getVtableIndexForInterfaceMethod",             CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD ")I",                                     FN_PTR(getVtableIndexForInterfaceMethod)},
   {CC "getClassInitializer",                          CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_METHOD,                                      FN_PTR(getClassInitializer)},
   {CC "hasFinalizableSubclass",                       CC "(" HS_RESOLVED_KLASS ")Z",                                                        FN_PTR(hasFinalizableSubclass)},
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -83,8 +83,10 @@
     }
   };
 
+  static JNINativeMethod methods[];
+
+  static objArrayHandle initialize_intrinsics(TRAPS);
  public:
-  static JNINativeMethod methods[];
   static int methods_count();
 
   static inline Method* asMethod(jobject jvmci_method) {
--- a/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -124,6 +124,12 @@
     oop_field(VMFlag, type, "Ljava/lang/String;")                                                                                                              \
     oop_field(VMFlag, value, "Ljava/lang/Object;")                                                                                                             \
   end_class                                                                                                                                                    \
+  start_class(VMIntrinsicMethod)                                                                                                                               \
+    oop_field(VMIntrinsicMethod, declaringClass, "Ljava/lang/String;")                                                                                         \
+    oop_field(VMIntrinsicMethod, name, "Ljava/lang/String;")                                                                                                   \
+    oop_field(VMIntrinsicMethod, descriptor, "Ljava/lang/String;")                                                                                             \
+    int_field(VMIntrinsicMethod, id)                                                                                                                           \
+  end_class                                                                                                                                                    \
   start_class(Assumptions_NoFinalizableSubclass)                                                                                                               \
     oop_field(Assumptions_NoFinalizableSubclass, receiverType, "Ljdk/vm/ci/meta/ResolvedJavaType;")                                                            \
   end_class                                                                                                                                                    \
--- a/hotspot/src/share/vm/jvmci/jvmci_globals.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmci_globals.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -84,6 +84,7 @@
   CHECK_NOT_SET(JVMCICountersExcludeCompiler, EnableJVMCI)
   CHECK_NOT_SET(JVMCIUseFastLocking,          EnableJVMCI)
   CHECK_NOT_SET(JVMCINMethodSizeLimit,        EnableJVMCI)
+  CHECK_NOT_SET(MethodProfileWidth,           EnableJVMCI)
   CHECK_NOT_SET(TraceUncollectedSpeculations, EnableJVMCI)
 
 #ifndef PRODUCT
--- a/hotspot/src/share/vm/jvmci/jvmci_globals.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmci_globals.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -88,6 +88,9 @@
   experimental(intx, JVMCINMethodSizeLimit, (80*K)*wordSize,                \
           "Maximum size of a compiled method.")                             \
                                                                             \
+  experimental(intx, MethodProfileWidth, 0,                                 \
+          "Number of methods to record in call profile")                    \
+                                                                            \
   develop(bool, TraceUncollectedSpeculations, false,                        \
           "Print message when a failed speculation was not collected")
 
--- a/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -51,6 +51,7 @@
   do_klass(HotSpotCompilationRequestResult_klass,        jdk_vm_ci_hotspot_HotSpotCompilationRequestResult,     Jvmci) \
   do_klass(VMField_klass,                                jdk_vm_ci_hotspot_VMField,                             Jvmci) \
   do_klass(VMFlag_klass,                                 jdk_vm_ci_hotspot_VMFlag,                              Jvmci) \
+  do_klass(VMIntrinsicMethod_klass,                      jdk_vm_ci_hotspot_VMIntrinsicMethod,                   Jvmci) \
   do_klass(Assumptions_ConcreteMethod_klass,             jdk_vm_ci_meta_Assumptions_ConcreteMethod,             Jvmci) \
   do_klass(Assumptions_NoFinalizableSubclass_klass,      jdk_vm_ci_meta_Assumptions_NoFinalizableSubclass,      Jvmci) \
   do_klass(Assumptions_ConcreteSubtype_klass,            jdk_vm_ci_meta_Assumptions_ConcreteSubtype,            Jvmci) \
--- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -493,6 +493,7 @@
   declare_constant(Method::_force_inline)                                 \
   declare_constant(Method::_dont_inline)                                  \
   declare_constant(Method::_hidden)                                       \
+  declare_constant(Method::_intrinsic_candidate)                          \
   declare_constant(Method::_reserved_stack_access)                        \
                                                                           \
   declare_constant(Method::nonvirtual_vtable_index)                       \
--- a/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -52,6 +52,7 @@
   template(jdk_vm_ci_hotspot_HotSpotCompilationRequestResult,     "jdk/vm/ci/hotspot/HotSpotCompilationRequestResult")     \
   template(jdk_vm_ci_hotspot_VMField,                             "jdk/vm/ci/hotspot/VMField")                             \
   template(jdk_vm_ci_hotspot_VMFlag,                              "jdk/vm/ci/hotspot/VMFlag")                              \
+  template(jdk_vm_ci_hotspot_VMIntrinsicMethod,                   "jdk/vm/ci/hotspot/VMIntrinsicMethod")                   \
   template(jdk_vm_ci_meta_JavaConstant,                           "jdk/vm/ci/meta/JavaConstant")                           \
   template(jdk_vm_ci_meta_PrimitiveConstant,                      "jdk/vm/ci/meta/PrimitiveConstant")                      \
   template(jdk_vm_ci_meta_RawConstant,                            "jdk/vm/ci/meta/RawConstant")                            \
--- a/hotspot/src/share/vm/logging/log.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/logging/log.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -1161,7 +1161,7 @@
 
   // Attempt to log to a directory (existing log not a regular file)
   create_directory(target_name);
-  LogFileOutput bad_file("tmplogdir");
+  LogFileOutput bad_file("file=tmplogdir");
   assert(bad_file.initialize("", &ss) == false, "file was initialized "
          "when there was an existing directory with the same name");
   assert(strstr(ss.as_string(), "tmplogdir is not a regular file") != NULL,
--- a/hotspot/src/share/vm/logging/logConfiguration.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/logging/logConfiguration.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -44,6 +44,9 @@
 LogConfiguration::UpdateListenerFunction* LogConfiguration::_listener_callbacks = NULL;
 size_t      LogConfiguration::_n_listener_callbacks = 0;
 
+// LogFileOutput is the default type of output, its type prefix should be used if no type was specified
+static const char* implicit_output_prefix = LogFileOutput::Prefix;
+
 // Stack object to take the lock for configuring the logging.
 // Should only be held during the critical parts of the configuration
 // (when calling configure_output or reading/modifying the outputs array).
@@ -107,6 +110,55 @@
   FREE_C_HEAP_ARRAY(LogOutput*, _outputs);
 }
 
+// Normalizes the given LogOutput name to type=name form.
+// For example, foo, "foo", file="foo", will all be normalized to file=foo (no quotes, prefixed).
+static bool normalize_output_name(const char* full_name, char* buffer, size_t len, outputStream* errstream) {
+  const char* start_quote = strchr(full_name, '"');
+  const char* equals = strchr(full_name, '=');
+  const bool quoted = start_quote != NULL;
+  const bool is_stdout_or_stderr = (strcmp(full_name, "stdout") == 0 || strcmp(full_name, "stderr") == 0);
+
+  // ignore equals sign within quotes
+  if (quoted && equals > start_quote) {
+    equals = NULL;
+  }
+
+  const char* prefix = "";
+  size_t prefix_len = 0;
+  const char* name = full_name;
+  if (equals != NULL) {
+    // split on equals sign
+    name = equals + 1;
+    prefix = full_name;
+    prefix_len = equals - full_name + 1;
+  } else if (!is_stdout_or_stderr) {
+    prefix = implicit_output_prefix;
+    prefix_len = strlen(prefix);
+  }
+  size_t name_len = strlen(name);
+
+  if (quoted) {
+    const char* end_quote = strchr(start_quote + 1, '"');
+    if (end_quote == NULL) {
+      errstream->print_cr("Output name has opening quote but is missing a terminating quote.");
+      return false;
+    }
+    if (start_quote != name || end_quote[1] != '\0') {
+      errstream->print_cr("Output name can not be partially quoted."
+                          " Either surround the whole name with quotation marks,"
+                          " or do not use quotation marks at all.");
+      return false;
+    }
+    // strip start and end quote
+    name++;
+    name_len -= 2;
+  }
+
+  int ret = jio_snprintf(buffer, len, "%.*s%.*s", prefix_len, prefix, name_len, name);
+  assert(ret > 0, "buffer issue");
+  return true;
+}
+
 size_t LogConfiguration::find_output(const char* name) {
   for (size_t i = 0; i < _n_outputs; i++) {
     if (strcmp(_outputs[i]->name(), name) == 0) {
@@ -116,39 +168,14 @@
   return SIZE_MAX;
 }
 
-LogOutput* LogConfiguration::new_output(char* name, const char* options, outputStream* errstream) {
-  const char* type;
-  char* equals_pos = strchr(name, '=');
-  if (equals_pos == NULL) {
-    type = "file";
-  } else {
-    *equals_pos = '\0';
-    type = name;
-    name = equals_pos + 1;
-  }
-
-  // Check if name is quoted, and if so, strip the quotes
-  char* quote = strchr(name, '"');
-  if (quote != NULL) {
-    char* end_quote = strchr(name + 1, '"');
-    if (end_quote == NULL) {
-      errstream->print_cr("Output name has opening quote but is missing a terminating quote.");
-      return NULL;
-    } else if (quote != name || end_quote[1] != '\0') {
-      errstream->print_cr("Output name can not be partially quoted."
-                          " Either surround the whole name with quotation marks,"
-                          " or do not use quotation marks at all.");
-      return NULL;
-    }
-    name++;
-    *end_quote = '\0';
-  }
-
+LogOutput* LogConfiguration::new_output(const char* name,
+                                        const char* options,
+                                        outputStream* errstream) {
   LogOutput* output;
-  if (strcmp(type, "file") == 0) {
+  if (strncmp(name, LogFileOutput::Prefix, strlen(LogFileOutput::Prefix)) == 0) {
     output = new LogFileOutput(name);
   } else {
-    errstream->print_cr("Unsupported log output type.");
+    errstream->print_cr("Unsupported log output type: %s", name);
     return NULL;
   }
 
@@ -243,6 +270,7 @@
 }
 
 void LogConfiguration::disable_output(size_t idx) {
+  assert(idx < _n_outputs, "invalid index: " SIZE_FORMAT " (_n_outputs: " SIZE_FORMAT ")", idx, _n_outputs);
   LogOutput* out = _outputs[idx];
 
   // Remove the output from all tagsets.
@@ -253,7 +281,7 @@
 
   // Delete the output unless stdout/stderr
   if (out != LogOutput::Stderr && out != LogOutput::Stdout) {
-    delete_output(find_output(out->name()));
+    delete_output(idx);
   } else {
     out->set_config_string("all=off");
   }
@@ -261,8 +289,8 @@
 
 void LogConfiguration::disable_logging() {
   ConfigurationLock cl;
-  for (size_t i = 0; i < _n_outputs; i++) {
-    disable_output(i);
+  for (size_t i = _n_outputs; i > 0; i--) {
+    disable_output(i - 1);
   }
   notify_update_listeners();
 }
@@ -289,6 +317,8 @@
   }
   expr.set_level(level);
   expr.new_combination();
+  assert(expr.verify_tagsets(),
+         "configure_stdout() called with invalid/non-existing tag set");
 
   // Apply configuration to stdout (output #0), with the same decorators as before.
   ConfigurationLock cl;
@@ -334,9 +364,16 @@
   char errbuf[512];
   stringStream ss(errbuf, sizeof(errbuf));
   bool success = parse_log_arguments(output, what, decorators, output_options, &ss);
-  if (!success) {
-    errbuf[strlen(errbuf) - 1] = '\0'; // Strip trailing newline.
-    log_error(logging)("%s", errbuf);
+
+  if (ss.size() > 0) {
+    errbuf[strlen(errbuf) - 1] = '\0'; // Strip trailing newline
+    // If it failed, log the error. If it didn't fail, but something was written
+    // to the stream, log it as a warning.
+    if (!success) {
+      log_error(logging)("%s", ss.base());
+    } else {
+      log_warning(logging)("%s", ss.base());
+    }
   }
 
   os::free(copy);
@@ -364,28 +401,39 @@
 
   ConfigurationLock cl;
   size_t idx;
-  if (outputstr[0] == '#') {
-    int ret = sscanf(outputstr+1, SIZE_FORMAT, &idx);
+  if (outputstr[0] == '#') { // Output specified using index
+    int ret = sscanf(outputstr + 1, SIZE_FORMAT, &idx);
     if (ret != 1 || idx >= _n_outputs) {
       errstream->print_cr("Invalid output index '%s'", outputstr);
       return false;
     }
-  } else {
-    idx = find_output(outputstr);
+  } else { // Output specified using name
+    // Normalize the name, stripping quotes and ensures it includes type prefix
+    size_t len = strlen(outputstr) + strlen(implicit_output_prefix) + 1;
+    char* normalized = NEW_C_HEAP_ARRAY(char, len, mtLogging);
+    if (!normalize_output_name(outputstr, normalized, len, errstream)) {
+      return false;
+    }
+
+    idx = find_output(normalized);
     if (idx == SIZE_MAX) {
-      char* tmp = os::strdup_check_oom(outputstr, mtLogging);
-      LogOutput* output = new_output(tmp, output_options, errstream);
-      os::free(tmp);
-      if (output == NULL) {
-        return false;
+      // Attempt to create and add the output
+      LogOutput* output = new_output(normalized, output_options, errstream);
+      if (output != NULL) {
+        idx = add_output(output);
       }
-      idx = add_output(output);
     } else if (output_options != NULL && strlen(output_options) > 0) {
       errstream->print_cr("Output options for existing outputs are ignored.");
     }
+
+    FREE_C_HEAP_ARRAY(char, normalized);
+    if (idx == SIZE_MAX) {
+      return false;
+    }
   }
   configure_output(idx, expr, decorators);
   notify_update_listeners();
+  expr.verify_tagsets(errstream);
   return true;
 }
 
--- a/hotspot/src/share/vm/logging/logConfiguration.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/logging/logConfiguration.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -59,7 +59,7 @@
   static size_t                     _n_listener_callbacks;
 
   // Create a new output. Returns NULL if failed.
-  static LogOutput* new_output(char* name, const char* options, outputStream* errstream);
+  static LogOutput* new_output(const char* name, const char* options, outputStream* errstream);
 
   // Add an output to the list of configured outputs. Returns the assigned index.
   static size_t add_output(LogOutput* out);
--- a/hotspot/src/share/vm/logging/logFileOutput.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/logging/logFileOutput.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -31,6 +31,7 @@
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/defaultStream.hpp"
 
+const char* LogFileOutput::Prefix = "file=";
 const char* LogFileOutput::FileOpenMode = "a";
 const char* LogFileOutput::PidFilenamePlaceholder = "%p";
 const char* LogFileOutput::TimestampFilenamePlaceholder = "%t";
@@ -45,7 +46,8 @@
       _file_name(NULL), _archive_name(NULL), _archive_name_len(0),
       _rotate_size(DefaultFileSize), _file_count(DefaultFileCount),
       _current_size(0), _current_file(0), _rotation_semaphore(1) {
-  _file_name = make_file_name(name, _pid_str, _vm_start_time_str);
+  assert(strstr(name, Prefix) == name, "invalid output name '%s': missing prefix: %s", name, Prefix);
+  _file_name = make_file_name(name + strlen(Prefix), _pid_str, _vm_start_time_str);
 }
 
 void LogFileOutput::set_file_name_parameters(jlong vm_start_time) {
--- a/hotspot/src/share/vm/logging/logFileOutput.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/logging/logFileOutput.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -91,6 +91,7 @@
     return _name;
   }
 
+  static const char* Prefix;
   static void set_file_name_parameters(jlong start_time);
 };
 
--- a/hotspot/src/share/vm/logging/logTagLevelExpression.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagLevelExpression.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -29,6 +29,65 @@
 
 const char* LogTagLevelExpression::DefaultExpressionString = "all";
 
+static bool matches_tagset(const LogTagType tags[],
+                           bool allow_other_tags,
+                           const LogTagSet& ts) {
+  bool contains_all = true;
+  size_t tag_idx;
+  for (tag_idx = 0; tag_idx < LogTag::MaxTags && tags[tag_idx] != LogTag::__NO_TAG; tag_idx++) {
+    if (!ts.contains(tags[tag_idx])) {
+      contains_all = false;
+      break;
+    }
+  }
+  // All tags in the expression must be part of the tagset,
+  // and either the expression allows other tags (has a wildcard),
+  // or the number of tags in the expression and tagset must match.
+  return contains_all && (allow_other_tags || tag_idx == ts.ntags());
+}
+
+bool LogTagLevelExpression::verify_tagsets(outputStream* out) const {
+  bool valid = true;
+
+  for (size_t i = 0; i < _ncombinations; i++) {
+    bool matched = false;
+    for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+      if (matches_tagset(_tags[i], _allow_other_tags[i], *ts)) {
+        matched = true;
+        break;
+      }
+    }
+
+    if (!matched) {
+      // If this was the first invalid combination, write the message header
+      if (valid && out != NULL) {
+        out->print("No tag set matches selection(s): ");
+      }
+      valid = false;
+
+      // Break as soon as possible unless listing all invalid combinations
+      if (out == NULL) {
+        break;
+      }
+
+      // List the combination on the outputStream
+      for (size_t t = 0; t < LogTag::MaxTags && _tags[i][t] != LogTag::__NO_TAG; t++) {
+        out->print("%s%s", (t == 0 ? "" : "+"), LogTag::name(_tags[i][t]));
+      }
+      if (_allow_other_tags[i]) {
+        out->print("*");
+      }
+      out->print(" ");
+    }
+  }
+
+  if (!valid && out != NULL) {
+    out->cr();
+  }
+
+  return valid;
+}
+
 bool LogTagLevelExpression::parse(const char* str, outputStream* errstream) {
   bool success = true;
   if (str == NULL || strcmp(str, "") == 0) {
@@ -120,20 +179,10 @@
   // Return NotMentioned if the given tagset isn't covered by this expression.
   LogLevelType level = LogLevel::NotMentioned;
   for (size_t combination = 0; combination < _ncombinations; combination++) {
-    bool contains_all = true;
-    size_t tag_idx;
-    for (tag_idx = 0; tag_idx < LogTag::MaxTags && _tags[combination][tag_idx] != LogTag::__NO_TAG; tag_idx++) {
-      if (!ts.contains(_tags[combination][tag_idx])) {
-        contains_all = false;
-        break;
-      }
-    }
-    // All tags in the expression must be part of the tagset,
-    // and either the expression allows other tags (has a wildcard),
-    // or the number of tags in the expression and tagset must match.
-    if (contains_all && (_allow_other_tags[combination] || tag_idx == ts.ntags())) {
+    if (matches_tagset(_tags[combination], _allow_other_tags[combination], ts)) {
       level = _level[combination];
     }
   }
   return level;
 }
+
--- a/hotspot/src/share/vm/logging/logTagLevelExpression.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagLevelExpression.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -83,6 +83,11 @@
 
   bool parse(const char* str, outputStream* errstream = NULL);
   LogLevelType level_for(const LogTagSet& ts) const;
+
+  // Verify the tagsets/selections mentioned in this expression.
+  // Returns false if some invalid tagset was found. If given an outputstream,
+  // this function will list all the invalid selections on the stream.
+  bool verify_tagsets(outputStream* out = NULL) const;
 };
 
 #endif // SHARE_VM_LOGGING_LOGTAGLEVELEXPRESSION_HPP
--- a/hotspot/src/share/vm/logging/logTagSet.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagSet.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -86,7 +86,7 @@
   }
 
   bool contains(LogTagType tag) const {
-    for (size_t i = 0; _tag[i] != LogTag::__NO_TAG; i++) {
+    for (size_t i = 0; i < LogTag::MaxTags && _tag[i] != LogTag::__NO_TAG; i++) {
       if (tag == _tag[i]) {
         return true;
       }
--- a/hotspot/src/share/vm/memory/universe.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/memory/universe.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -135,6 +135,7 @@
 oop Universe::_virtual_machine_error_instance         = NULL;
 oop Universe::_vm_exception                           = NULL;
 oop Universe::_allocation_context_notification_obj    = NULL;
+oop Universe::_reference_pending_list                 = NULL;
 
 Array<int>* Universe::_the_empty_int_array            = NULL;
 Array<u2>* Universe::_the_empty_short_array           = NULL;
@@ -212,6 +213,7 @@
   f->do_oop((oop*)&_system_thread_group);
   f->do_oop((oop*)&_vm_exception);
   f->do_oop((oop*)&_allocation_context_notification_obj);
+  f->do_oop((oop*)&_reference_pending_list);
   debug_only(f->do_oop((oop*)&_fullgc_alot_dummy_array);)
 }
 
@@ -488,6 +490,35 @@
   java_lang_Class::set_fixup_mirror_list(NULL);
 }
 
+#define assert_pll_locked(test) \
+  assert(Heap_lock->test(), "Reference pending list access requires lock")
+
+#define assert_pll_ownership() assert_pll_locked(owned_by_self)
+
+oop Universe::reference_pending_list() {
+  assert_pll_ownership();
+  return _reference_pending_list;
+}
+
+void Universe::set_reference_pending_list(oop list) {
+  assert_pll_ownership();
+  _reference_pending_list = list;
+}
+
+bool Universe::has_reference_pending_list() {
+  assert_pll_ownership();
+  return _reference_pending_list != NULL;
+}
+
+oop Universe::swap_reference_pending_list(oop list) {
+  assert_pll_locked(is_locked);
+  return (oop)Atomic::xchg_ptr(list, &_reference_pending_list);
+}
+
+#undef assert_pll_locked
+#undef assert_pll_ownership
+
+
 static bool has_run_finalizers_on_exit = false;
 
 void Universe::run_finalizers_on_exit() {
@@ -565,12 +596,14 @@
 
 oop Universe::gen_out_of_memory_error(oop default_err) {
   // generate an out of memory error:
-  // - if there is a preallocated error with backtrace available then return it wth
-  //   a filled in stack trace.
-  // - if there are no preallocated errors with backtrace available then return
-  //   an error without backtrace.
+  // - if there is a preallocated error and stack traces are available
+  //   (j.l.Throwable is initialized), then return the preallocated
+  //   error with a filled in stack trace, and with the message
+  //   provided by the default error.
+  // - otherwise, return the default error, without a stack trace.
   int next;
-  if (_preallocated_out_of_memory_error_avail_count > 0) {
+  if ((_preallocated_out_of_memory_error_avail_count > 0) &&
+      SystemDictionary::Throwable_klass()->is_initialized()) {
     next = (int)Atomic::add(-1, &_preallocated_out_of_memory_error_avail_count);
     assert(next < (int)PreallocatedOutOfMemoryErrorCount, "avail count is corrupt");
   } else {
--- a/hotspot/src/share/vm/memory/universe.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/memory/universe.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -185,6 +185,9 @@
 
   static oop          _allocation_context_notification_obj;
 
+  // References waiting to be transferred to the ReferenceHandler
+  static oop          _reference_pending_list;
+
   // The particular choice of collected heap.
   static CollectedHeap* _collectedHeap;
 
@@ -334,6 +337,17 @@
   static inline oop   allocation_context_notification_obj();
   static inline void  set_allocation_context_notification_obj(oop obj);
 
+  // Reference pending list manipulation.  Access is protected by
+  // Heap_lock.  The getter, setter and predicate require the caller
+  // owns the lock.  Swap is used by parallel non-concurrent reference
+  // processing threads, where some higher level controller owns
+  // Heap_lock, so requires the lock is locked, but not necessarily by
+  // the current thread.
+  static oop          reference_pending_list();
+  static void         set_reference_pending_list(oop list);
+  static bool         has_reference_pending_list();
+  static oop          swap_reference_pending_list(oop list);
+
   static Array<int>*       the_empty_int_array()    { return _the_empty_int_array; }
   static Array<u2>*        the_empty_short_array()  { return _the_empty_short_array; }
   static Array<Method*>* the_empty_method_array() { return _the_empty_method_array; }
--- a/hotspot/src/share/vm/oops/arrayKlass.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/oops/arrayKlass.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -56,7 +56,9 @@
   void set_dimension(int dimension)     { _dimension = dimension; }
 
   Klass* higher_dimension() const     { return _higher_dimension; }
+  inline Klass* higher_dimension_acquire() const; // load with acquire semantics
   void set_higher_dimension(Klass* k) { _higher_dimension = k; }
+  inline void release_set_higher_dimension(Klass* k); // store with release semantics
   Klass** adr_higher_dimension()      { return (Klass**)&this->_higher_dimension;}
 
   Klass* lower_dimension() const      { return _lower_dimension; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/oops/arrayKlass.inline.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_ARRAYKLASS_INLINE_HPP
+#define SHARE_VM_OOPS_ARRAYKLASS_INLINE_HPP
+
+#include "runtime/orderAccess.inline.hpp"
+#include "oops/arrayKlass.hpp"
+
+inline Klass* ArrayKlass::higher_dimension_acquire() const {
+  return (Klass*) OrderAccess::load_ptr_acquire(&_higher_dimension);
+}
+
+inline void ArrayKlass::release_set_higher_dimension(Klass* k) {
+  OrderAccess::release_store_ptr(&_higher_dimension, k);
+}
+
+#endif // SHARE_VM_OOPS_ARRAYKLASS_INLINE_HPP
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -1041,7 +1041,8 @@
 }
 
 Klass* InstanceKlass::array_klass_impl(instanceKlassHandle this_k, bool or_null, int n, TRAPS) {
-  if (this_k->array_klasses() == NULL) {
+  // Need load-acquire for lock-free read
+  if (this_k->array_klasses_acquire() == NULL) {
     if (or_null) return NULL;
 
     ResourceMark rm;
@@ -1054,7 +1055,8 @@
       // Check if update has already taken place
       if (this_k->array_klasses() == NULL) {
         Klass*    k = ObjArrayKlass::allocate_objArray_klass(this_k->class_loader_data(), 1, this_k, CHECK_NULL);
-        this_k->set_array_klasses(k);
+        // use 'release' to pair with lock-free load
+        this_k->release_set_array_klasses(k);
       }
     }
   }
@@ -3368,6 +3370,7 @@
 
 // Purge previous versions before adding new previous versions of the class.
 void InstanceKlass::purge_previous_versions(InstanceKlass* ik) {
+  assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
   if (ik->previous_versions() != NULL) {
     // This klass has previous versions so see what we can cleanup
     // while it is safe to do so.
@@ -3396,7 +3399,12 @@
         // are executing.  Unlink this previous_version.
         // The previous version InstanceKlass is on the ClassLoaderData deallocate list
         // so will be deallocated during the next phase of class unloading.
-        log_trace(redefine, class, iklass, purge)("previous version " INTPTR_FORMAT " is dead", p2i(pv_node));
+        //
+        // Update count for class unloading.
+        _previous_version_count--;
+        log_trace(redefine, class, iklass, purge)
+          ("previous version " INTPTR_FORMAT " is dead.  previous_version_count = %d",
+           p2i(pv_node), _previous_version_count);
         // For debugging purposes.
         pv_node->set_is_scratch_class();
         pv_node->class_loader_data()->add_to_deallocate_list(pv_node);
@@ -3511,6 +3519,7 @@
                                          int emcp_method_count) {
   assert(Thread::current()->is_VM_thread(),
          "only VMThread can add previous versions");
+  assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
 
   ResourceMark rm;
   log_trace(redefine, class, iklass, add)
@@ -3534,8 +3543,6 @@
     // For debugging purposes.
     scratch_class->set_is_scratch_class();
     scratch_class->class_loader_data()->add_to_deallocate_list(scratch_class());
-    // Update count for class unloading.
-    _previous_version_count--;
     return;
   }
 
@@ -3563,12 +3570,14 @@
   }
 
   // Add previous version if any methods are still running.
-  log_trace(redefine, class, iklass, add)("scratch class added; one of its methods is on_stack");
+  // Update count for class unloading.
+  _previous_version_count++;
+  log_trace(redefine, class, iklass, add)
+    ("scratch class added; one of its methods is on_stack.  previous_version_count = %d",
+      _previous_version_count);
   assert(scratch_class->previous_versions() == NULL, "shouldn't have a previous version");
   scratch_class->link_previous_versions(previous_versions());
   link_previous_versions(scratch_class());
-  // Update count for class unloading.
-  _previous_version_count++;
 } // end add_previous_version()
 
 #endif // INCLUDE_JVMTI
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -148,7 +148,7 @@
   // Package this class is defined in
   PackageEntry*   _package_entry;
   // Array classes holding elements of this class.
-  Klass*          _array_klasses;
+  Klass* volatile _array_klasses;
   // Constant pool for this class.
   ConstantPool* _constants;
   // The InnerClasses attribute and EnclosingMethod attribute. The
@@ -230,7 +230,7 @@
   OopMapCache*    volatile _oop_map_cache;   // OopMapCache for all methods in the klass (allocated lazily)
   MemberNameTable* _member_names;        // Member names
   JNIid*          _jni_ids;              // First JNI identifier for static fields in this class
-  jmethodID*      _methods_jmethod_ids;  // jmethodIDs corresponding to method_idnum, or NULL if none
+  jmethodID*      volatile _methods_jmethod_ids;  // jmethodIDs corresponding to method_idnum, or NULL if none
   intptr_t        _dep_context;          // packed DependencyContext structure
   nmethod*        _osr_nmethods_head;    // Head of list of on-stack replacement nmethods for this class
 #if INCLUDE_JVMTI
@@ -368,7 +368,9 @@
 
   // array klasses
   Klass* array_klasses() const             { return _array_klasses; }
+  inline Klass* array_klasses_acquire() const; // load with acquire semantics
   void set_array_klasses(Klass* k)         { _array_klasses = k; }
+  inline void release_set_array_klasses(Klass* k); // store with release semantics
 
   // methods
   Array<Method*>* methods() const          { return _methods; }
@@ -769,7 +771,10 @@
   static int  _previous_version_count;
  public:
   static void purge_previous_versions(InstanceKlass* ik);
-  static bool has_previous_versions() { return _previous_version_count > 0; }
+  static bool has_previous_versions() {
+    assert(_previous_version_count >= 0, "count should never be negative");
+    return _previous_version_count > 0;
+  }
 
   // JVMTI: Support for caching a class file before it is modified by an agent that can do retransformation
   void set_cached_class_file(JvmtiCachedClassFileData *data) {
@@ -1238,10 +1243,8 @@
   // cache management logic if the caches can grow instead of just
   // going from NULL to non-NULL.
   bool idnum_can_increment() const      { return has_been_redefined(); }
-  jmethodID* methods_jmethod_ids_acquire() const
-         { return (jmethodID*)OrderAccess::load_ptr_acquire(&_methods_jmethod_ids); }
-  void release_set_methods_jmethod_ids(jmethodID* jmeths)
-         { OrderAccess::release_store_ptr(&_methods_jmethod_ids, jmeths); }
+  inline jmethodID* methods_jmethod_ids_acquire() const;
+  inline void release_set_methods_jmethod_ids(jmethodID* jmeths);
 
   // Lock during initialization
 public:
--- a/hotspot/src/share/vm/oops/instanceKlass.inline.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.inline.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -29,10 +29,27 @@
 #include "oops/instanceKlass.hpp"
 #include "oops/klass.hpp"
 #include "oops/oop.inline.hpp"
+#include "runtime/orderAccess.inline.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/macros.hpp"
 
+inline Klass* InstanceKlass::array_klasses_acquire() const {
+  return (Klass*) OrderAccess::load_ptr_acquire(&_array_klasses);
+}
+
+inline void InstanceKlass::release_set_array_klasses(Klass* k) {
+  OrderAccess::release_store_ptr(&_array_klasses, k);
+}
+
+inline jmethodID* InstanceKlass::methods_jmethod_ids_acquire() const {
+  return (jmethodID*)OrderAccess::load_ptr_acquire(&_methods_jmethod_ids);
+}
+
+inline void InstanceKlass::release_set_methods_jmethod_ids(jmethodID* jmeths) {
+  OrderAccess::release_store_ptr(&_methods_jmethod_ids, jmeths);
+}
+
 // The iteration over the oops in objects is a hot path in the GC code.
 // By force inlining the following functions, we get similar GC performance
 // as the previous macro based implementation.
--- a/hotspot/src/share/vm/oops/method.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/oops/method.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -30,7 +30,6 @@
 #include "gc/shared/collectedHeap.inline.hpp"
 #include "gc/shared/gcLocker.hpp"
 #include "gc/shared/generation.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
 #include "interpreter/bytecodeStream.hpp"
 #include "interpreter/bytecodeTracer.hpp"
 #include "interpreter/bytecodes.hpp"
@@ -400,12 +399,6 @@
     return;
   }
 
-  // Do not profile method if current thread holds the pending list lock,
-  // which avoids deadlock for acquiring the MethodData_lock.
-  if (ReferencePendingListLocker::is_locked_by_self()) {
-    return;
-  }
-
   // Grab a lock here to prevent multiple
   // MethodData*s from being created.
   MutexLocker ml(MethodData_lock, THREAD);
--- a/hotspot/src/share/vm/oops/methodData.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/oops/methodData.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -30,6 +30,9 @@
 #include "oops/method.hpp"
 #include "oops/oop.hpp"
 #include "runtime/orderAccess.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci_globals.hpp"
+#endif
 
 class BytecodeStream;
 class KlassSizeStats;
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -34,6 +34,7 @@
 #include "memory/metadataFactory.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.inline.hpp"
+#include "oops/arrayKlass.inline.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/klass.inline.hpp"
 #include "oops/objArrayKlass.inline.hpp"
@@ -42,7 +43,6 @@
 #include "oops/symbol.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/mutexLocker.hpp"
-#include "runtime/orderAccess.inline.hpp"
 #include "utilities/copy.hpp"
 #include "utilities/macros.hpp"
 
@@ -321,7 +321,8 @@
   int dim = dimension();
   if (dim == n) return this;
 
-  if (higher_dimension() == NULL) {
+  // lock-free read needs acquire semantics
+  if (higher_dimension_acquire() == NULL) {
     if (or_null)  return NULL;
 
     ResourceMark rm;
@@ -339,8 +340,8 @@
           ObjArrayKlass::allocate_objArray_klass(class_loader_data(), dim + 1, this, CHECK_NULL);
         ObjArrayKlass* ak = ObjArrayKlass::cast(k);
         ak->set_lower_dimension(this);
-        OrderAccess::storestore();
-        set_higher_dimension(ak);
+        // use 'release' to pair with lock-free load
+        release_set_higher_dimension(ak);
         assert(ak->is_objArray_klass(), "incorrect initialization of ObjArrayKlass");
       }
     }
--- a/hotspot/src/share/vm/oops/symbol.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/oops/symbol.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -229,24 +229,25 @@
 }
 
 void Symbol::increment_refcount() {
-  // Only increment the refcount if positive.  If negative either
+  // Only increment the refcount if non-negative.  If negative either
   // overflow has occurred or it is a permanent symbol in a read only
   // shared archive.
-  if (_refcount >= 0) {
+  if (_refcount >= 0) { // not a permanent symbol
     Atomic::inc(&_refcount);
     NOT_PRODUCT(Atomic::inc(&_total_count);)
   }
 }
 
 void Symbol::decrement_refcount() {
-  if (_refcount >= 0) {
-    Atomic::dec(&_refcount);
+  if (_refcount >= 0) { // not a permanent symbol
+    jshort new_value = Atomic::add(-1, &_refcount);
 #ifdef ASSERT
-    if (_refcount < 0) {
+    if (new_value == -1) { // we have transitioned from 0 -> -1
       print();
       assert(false, "reference count underflow for symbol");
     }
 #endif
+    (void)new_value;
   }
 }
 
--- a/hotspot/src/share/vm/oops/typeArrayKlass.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -34,6 +34,7 @@
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
 #include "memory/universe.inline.hpp"
+#include "oops/arrayKlass.inline.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/klass.inline.hpp"
 #include "oops/objArrayKlass.hpp"
@@ -41,7 +42,6 @@
 #include "oops/typeArrayKlass.inline.hpp"
 #include "oops/typeArrayOop.inline.hpp"
 #include "runtime/handles.inline.hpp"
-#include "runtime/orderAccess.inline.hpp"
 #include "utilities/macros.hpp"
 
 bool TypeArrayKlass::compute_is_subtype_of(Klass* k) {
@@ -166,7 +166,8 @@
     if (dim == n)
       return this;
 
-  if (higher_dimension() == NULL) {
+  // lock-free read needs acquire semantics
+  if (higher_dimension_acquire() == NULL) {
     if (or_null)  return NULL;
 
     ResourceMark rm;
@@ -181,8 +182,8 @@
               class_loader_data(), dim + 1, this, CHECK_NULL);
         ObjArrayKlass* h_ak = ObjArrayKlass::cast(oak);
         h_ak->set_lower_dimension(this);
-        OrderAccess::storestore();
-        set_higher_dimension(h_ak);
+        // use 'release' to pair with lock-free load
+        release_set_higher_dimension(h_ak);
         assert(h_ak->is_objArray_klass(), "incorrect initialization of ObjArrayKlass");
       }
     }
--- a/hotspot/src/share/vm/opto/block.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/opto/block.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -1212,6 +1212,9 @@
       if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) {
         assert(j == 1 || block->get_node(j-1)->is_Phi(), "CreateEx must be first instruction in block");
       }
+      if (n->needs_anti_dependence_check()) {
+        verify_anti_dependences(block, n);
+      }
       for (uint k = 0; k < n->req(); k++) {
         Node *def = n->in(k);
         if (def && def != n) {
--- a/hotspot/src/share/vm/opto/block.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/opto/block.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -186,14 +186,13 @@
   Block* lone_fall_through();   // Return lone fall-through Block or null
 
   Block* dom_lca(Block* that);  // Compute LCA in dominator tree.
-#ifdef ASSERT
+
   bool dominates(Block* that) {
     int dom_diff = this->_dom_depth - that->_dom_depth;
     if (dom_diff > 0)  return false;
     for (; dom_diff < 0; dom_diff++)  that = that->_idom;
     return this == that;
   }
-#endif
 
   // Report the alignment required by this block.  Must be a power of 2.
   // The previous block will insert nops to get this alignment.
@@ -481,9 +480,9 @@
   MachNode* _goto;
 
   Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
-  void verify_anti_dependences(Block* LCA, Node* load) {
+  void verify_anti_dependences(Block* LCA, Node* load) const {
     assert(LCA == get_block_for_node(load), "should already be scheduled");
-    insert_anti_dependences(LCA, load, true);
+    const_cast<PhaseCFG*>(this)->insert_anti_dependences(LCA, load, true);
   }
 
   bool move_to_next(Block* bx, uint b_index);
--- a/hotspot/src/share/vm/opto/c2compiler.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -530,6 +530,7 @@
   case vmIntrinsics::_isInterrupted:
 #ifdef TRACE_HAVE_INTRINSICS
   case vmIntrinsics::_counterTime:
+  case vmIntrinsics::_getClassId:
 #endif
   case vmIntrinsics::_currentTimeMillis:
   case vmIntrinsics::_nanoTime:
--- a/hotspot/src/share/vm/opto/callGenerator.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -1164,7 +1164,10 @@
   GraphKit kit(jvms);
   kit.C->print_inlining_update(this);
   // Take the trap with arguments pushed on the stack.  (Cf. null_check_receiver).
-  int nargs = method()->arg_size();
+  // Callsite signature can be different from actual method being called (i.e _linkTo* sites).
+  // Use callsite signature always.
+  ciMethod* declared_method = kit.method()->get_method_at_bci(kit.bci());
+  int nargs = declared_method->arg_size();
   kit.inc_sp(nargs);
   assert(nargs <= kit.sp() && kit.sp() <= jvms->stk_size(), "sane sp w/ args pushed");
   if (_reason == Deoptimization::Reason_class_check &&
--- a/hotspot/src/share/vm/opto/cfgnode.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/opto/cfgnode.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -119,6 +119,9 @@
 // input in slot 0.
 class PhiNode : public TypeNode {
   const TypePtr* const _adr_type; // non-null only for Type::MEMORY nodes.
+  // The following fields are only used for data PhiNodes to indicate
+  // that the PhiNode represents the value of a known instance field.
+        int _inst_mem_id; // Instance memory id (node index of the memory Phi)
   const int _inst_id;     // Instance id of the memory slice.
   const int _inst_index;  // Alias index of the instance memory slice.
   // Array elements references have the same alias_idx but different offset.
@@ -138,11 +141,13 @@
   };
 
   PhiNode( Node *r, const Type *t, const TypePtr* at = NULL,
+           const int imid = -1,
            const int iid = TypeOopPtr::InstanceTop,
            const int iidx = Compile::AliasIdxTop,
            const int ioffs = Type::OffsetTop )
     : TypeNode(t,r->req()),
       _adr_type(at),
+      _inst_mem_id(imid),
       _inst_id(iid),
       _inst_index(iidx),
       _inst_offset(ioffs)
@@ -194,11 +199,14 @@
   virtual bool pinned() const { return in(0) != 0; }
   virtual const TypePtr *adr_type() const { verify_adr_type(true); return _adr_type; }
 
+  void  set_inst_mem_id(int inst_mem_id) { _inst_mem_id = inst_mem_id; }
+  const int inst_mem_id() const { return _inst_mem_id; }
   const int inst_id()     const { return _inst_id; }
   const int inst_index()  const { return _inst_index; }
   const int inst_offset() const { return _inst_offset; }
-  bool is_same_inst_field(const Type* tp, int id, int index, int offset) {
+  bool is_same_inst_field(const Type* tp, int mem_id, int id, int index, int offset) {
     return type()->basic_type() == tp->basic_type() &&
+           inst_mem_id() == mem_id &&
            inst_id()     == id     &&
            inst_index()  == index  &&
            inst_offset() == offset &&
--- a/hotspot/src/share/vm/opto/compile.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/opto/compile.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -1708,16 +1708,21 @@
   const TypePtr* flat = flatten_alias_type(adr_type);
 
 #ifdef ASSERT
-  assert(flat == flatten_alias_type(flat), "idempotent");
-  assert(flat != TypePtr::BOTTOM,     "cannot alias-analyze an untyped ptr");
-  if (flat->isa_oopptr() && !flat->isa_klassptr()) {
-    const TypeOopPtr* foop = flat->is_oopptr();
-    // Scalarizable allocations have exact klass always.
-    bool exact = !foop->klass_is_exact() || foop->is_known_instance();
-    const TypePtr* xoop = foop->cast_to_exactness(exact)->is_ptr();
-    assert(foop == flatten_alias_type(xoop), "exactness must not affect alias type");
+  {
+    ResourceMark rm;
+    assert(flat == flatten_alias_type(flat), "not idempotent: adr_type = %s; flat = %s => %s",
+           Type::str(adr_type), Type::str(flat), Type::str(flatten_alias_type(flat)));
+    assert(flat != TypePtr::BOTTOM, "cannot alias-analyze an untyped ptr: adr_type = %s",
+           Type::str(adr_type));
+    if (flat->isa_oopptr() && !flat->isa_klassptr()) {
+      const TypeOopPtr* foop = flat->is_oopptr();
+      // Scalarizable allocations have exact klass always.
+      bool exact = !foop->klass_is_exact() || foop->is_known_instance();
+      const TypePtr* xoop = foop->cast_to_exactness(exact)->is_ptr();
+      assert(foop == flatten_alias_type(xoop), "exactness must not affect alias type: foop = %s; xoop = %s",
+             Type::str(foop), Type::str(xoop));
+    }
   }
-  assert(flat == flatten_alias_type(flat), "exact bit doesn't matter");
 #endif
 
   int idx = AliasIdxTop;
@@ -3159,45 +3164,65 @@
     break;
 #endif
 
-  case Op_ModI:
+  case Op_ModI: {
+    Node* di = NULL;
     if (UseDivMod) {
       // Check if a%b and a/b both exist
-      Node* d = n->find_similar(Op_DivI);
-      if (d) {
+      di = n->find_similar(Op_DivI);
+      if (di) {
         // Replace them with a fused divmod if supported
         if (Matcher::has_match_rule(Op_DivModI)) {
           DivModINode* divmod = DivModINode::make(n);
-          d->subsume_by(divmod->div_proj(), this);
+          di->subsume_by(divmod->div_proj(), this);
           n->subsume_by(divmod->mod_proj(), this);
         } else {
           // replace a%b with a-((a/b)*b)
-          Node* mult = new MulINode(d, d->in(2));
-          Node* sub  = new SubINode(d->in(1), mult);
+          Node* mult = new MulINode(di, di->in(2));
+          Node* sub  = new SubINode(di->in(1), mult);
           n->subsume_by(sub, this);
         }
       }
     }
+    if (di == NULL) {
+      // Remove useless control edge in case of not mod-zero.
+      const Type *t = n->in(2)->bottom_type();
+      const TypeInt *ti = t->is_int();
+      if (n->in(0) && (ti->_hi < 0 || ti->_lo > 0)) {
+        n->set_req(0, NULL);
+      }
+    }
     break;
-
-  case Op_ModL:
+  }
+
+  case Op_ModL: {
+    Node* dl = NULL;
     if (UseDivMod) {
       // Check if a%b and a/b both exist
-      Node* d = n->find_similar(Op_DivL);
-      if (d) {
+      dl = n->find_similar(Op_DivL);
+      if (dl) {
         // Replace them with a fused divmod if supported
         if (Matcher::has_match_rule(Op_DivModL)) {
           DivModLNode* divmod = DivModLNode::make(n);
-          d->subsume_by(divmod->div_proj(), this);
+          dl->subsume_by(divmod->div_proj(), this);
           n->subsume_by(divmod->mod_proj(), this);
         } else {
           // replace a%b with a-((a/b)*b)
-          Node* mult = new MulLNode(d, d->in(2));
-          Node* sub  = new SubLNode(d->in(1), mult);
+          Node* mult = new MulLNode(dl, dl->in(2));
+          Node* sub  = new SubLNode(dl->in(1), mult);
           n->subsume_by(sub, this);
         }
       }
     }
+    if (dl == NULL) {
+      // Remove useless control edge in case of not mod-zero.
+      const Type *t = n->in(2)->bottom_type();
+      const TypeLong *tl = t->is_long();
+      if (n->in(0) && (tl->_hi < 0 || tl->_lo > 0)) {
+        n->set_req(0, NULL);
+      }
+    }
     break;
+  }
 
   case Op_LoadVector:
   case Op_StoreVector:
--- a/hotspot/src/share/vm/opto/divnode.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/opto/divnode.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -853,13 +853,6 @@
   if( t == Type::TOP ) return NULL;
   const TypeInt *ti = t->is_int();
 
-  // Check for useless control input
-  // Check for excluding mod-zero case
-  if( in(0) && (ti->_hi < 0 || ti->_lo > 0) ) {
-    set_req(0, NULL);        // Yank control input
-    return this;
-  }
-
   // See if we are MOD'ing by 2^k or 2^k-1.
   if( !ti->is_con() ) return NULL;
   jint con = ti->get_con();
@@ -1024,13 +1017,6 @@
   if( t == Type::TOP ) return NULL;
   const TypeLong *tl = t->is_long();
 
-  // Check for useless control input
-  // Check for excluding mod-zero case
-  if( in(0) && (tl->_hi < 0 || tl->_lo > 0) ) {
-    set_req(0, NULL);        // Yank control input
-    return this;
-  }
-
   // See if we are MOD'ing by 2^k or 2^k-1.
   if( !tl->is_con() ) return NULL;
   jlong con = tl->get_con();
--- a/hotspot/src/share/vm/opto/graphKit.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -664,7 +664,10 @@
   // callee (with all arguments still on the stack).
   Node* null_check_receiver_before_call(ciMethod* callee) {
     assert(!callee->is_static(), "must be a virtual method");
-    const int nargs = callee->arg_size();
+    // Callsite signature can be different from actual method being called (i.e _linkTo* sites).
+    // Use callsite signature always.
+    ciMethod* declared_method = method()->get_method_at_bci(bci());
+    const int nargs = declared_method->arg_size();
     inc_sp(nargs);
     Node* n = null_check_receiver();
     dec_sp(nargs);
--- a/hotspot/src/share/vm/opto/lcm.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/opto/lcm.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -240,6 +240,14 @@
       continue;
     }
 
+    // Check that node's control edge is not-null block's head or dominates it,
+    // otherwise we can't hoist it because there are other control dependencies.
+    Node* ctrl = mach->in(0);
+    if (ctrl != NULL && !(ctrl == not_null_block->head() ||
+        get_block_for_node(ctrl)->dominates(not_null_block))) {
+      continue;
+    }
+
     // check if the offset is not too high for implicit exception
     {
       intptr_t offset = 0;
@@ -379,9 +387,12 @@
   block->add_inst(best);
   map_node_to_block(best, block);
 
-  // Move the control dependence
-  if (best->in(0) && best->in(0) == old_block->head())
-    best->set_req(0, block->head());
+  // Move the control dependence if it is pinned to not-null block.
+  // Don't change it in other cases: NULL or dominating control.
+  if (best->in(0) == not_null_block->head()) {
+    // Set it to control edge of null check.
+    best->set_req(0, proj->in(0)->in(0));
+  }
 
   // Check for flag-killing projections that also need to be hoisted
   // Should be DU safe because no edge updates.
@@ -437,6 +448,18 @@
 
   latency_from_uses(nul_chk);
   latency_from_uses(best);
+
+  // insert anti-dependences to defs in this block
+  if (! best->needs_anti_dependence_check()) {
+    for (uint k = 1; k < block->number_of_nodes(); k++) {
+      Node *n = block->get_node(k);
+      if (n->needs_anti_dependence_check() &&
+          n->in(LoadNode::Memory) == best->in(StoreNode::Memory)) {
+        // Found anti-dependent load
+        insert_anti_dependences(block, n);
+      }
+    }
+  }
 }
 
 
--- a/hotspot/src/share/vm/opto/library_call.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -254,6 +254,9 @@
   bool inline_native_currentThread();
 
   bool inline_native_time_funcs(address method, const char* funcName);
+#ifdef TRACE_HAVE_INTRINSICS
+  bool inline_native_classID();
+#endif
   bool inline_native_isInterrupted();
   bool inline_native_Class_query(vmIntrinsics::ID id);
   bool inline_native_subtype_check();
@@ -708,6 +711,7 @@
 
 #ifdef TRACE_HAVE_INTRINSICS
   case vmIntrinsics::_counterTime:              return inline_native_time_funcs(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), "counterTime");
+  case vmIntrinsics::_getClassId:               return inline_native_classID();
 #endif
   case vmIntrinsics::_currentTimeMillis:        return inline_native_time_funcs(CAST_FROM_FN_PTR(address, os::javaTimeMillis), "currentTimeMillis");
   case vmIntrinsics::_nanoTime:                 return inline_native_time_funcs(CAST_FROM_FN_PTR(address, os::javaTimeNanos), "nanoTime");
@@ -2242,8 +2246,8 @@
 
 #ifndef PRODUCT
     if (C->print_intrinsics() || C->print_inlining()) {
-      tty->print("  from base type: ");  adr_type->dump();
-      tty->print("  sharpened value: ");  tjp->dump();
+      tty->print("  from base type:  ");  adr_type->dump(); tty->cr();
+      tty->print("  sharpened value: ");  tjp->dump();      tty->cr();
     }
 #endif
     // Sharpen the value type.
@@ -2308,26 +2312,30 @@
   adr = make_unsafe_address(base, offset);
   if (_gvn.type(base)->isa_ptr() != TypePtr::NULL_PTR) {
     heap_base_oop = base;
-  }
+  } else if (type == T_OBJECT) {
+    return false; // off-heap oop accesses are not supported
+  }
+
+  // Can base be NULL? Otherwise, always on-heap access.
+  bool can_access_non_heap = TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop));
+
   val = is_store ? argument(4) : NULL;
 
   const TypePtr *adr_type = _gvn.type(adr)->isa_ptr();
 
-  // Try to categorize the address.  If it comes up as TypeJavaPtr::BOTTOM,
-  // there was not enough information to nail it down.
+  // Try to categorize the address.
   Compile::AliasType* alias_type = C->alias_type(adr_type);
   assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here");
 
-  // Only field, array element or unknown locations are supported.
-  if (alias_type->adr_type() != TypeRawPtr::BOTTOM &&
-      alias_type->adr_type() != TypeOopPtr::BOTTOM &&
-      alias_type->basic_type() == T_ILLEGAL) {
-    return false;
+  if (alias_type->adr_type() == TypeInstPtr::KLASS ||
+      alias_type->adr_type() == TypeAryPtr::RANGE) {
+    return false; // not supported
   }
 
   bool mismatched = false;
   BasicType bt = alias_type->basic_type();
   if (bt != T_ILLEGAL) {
+    assert(alias_type->adr_type()->is_oopptr(), "should be on-heap access");
     if (bt == T_BYTE && adr_type->isa_aryptr()) {
       // Alias type doesn't differentiate between byte[] and boolean[]).
       // Use address type to get the element type.
@@ -2342,10 +2350,12 @@
       return false;
     }
     mismatched = (bt != type);
-  } else if (alias_type->adr_type() == TypeOopPtr::BOTTOM) {
+  } else if (alias_type->adr_type()->isa_oopptr()) {
     mismatched = true; // conservatively mark all "wide" on-heap accesses as mismatched
   }
 
+  assert(!mismatched || alias_type->adr_type()->is_oopptr(), "off-heap access can't be mismatched");
+
   // First guess at the value type.
   const Type *value_type = Type::get_const_basic_type(type);
 
@@ -2357,7 +2367,7 @@
   bool need_mem_bar;
   switch (kind) {
       case Relaxed:
-          need_mem_bar = (alias_type->adr_type() == TypeOopPtr::BOTTOM);
+          need_mem_bar = mismatched || can_access_non_heap;
           break;
       case Opaque:
           // Opaque uses CPUOrder membars for protection against code movement.
@@ -2508,34 +2518,10 @@
       break;
     }
 
-    if (type != T_OBJECT) {
-      (void) store_to_memory(control(), adr, val, type, adr_type, mo, requires_atomic_access, unaligned, mismatched);
+    if (type == T_OBJECT) {
+      store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type, mo, mismatched);
     } else {
-      // Possibly an oop being stored to Java heap or native memory
-      if (!TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop))) {
-        // oop to Java heap.
-        (void) store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type, mo, mismatched);
-      } else {
-        // We can't tell at compile time if we are storing in the Java heap or outside
-        // of it. So we need to emit code to conditionally do the proper type of
-        // store.
-
-        IdealKit ideal(this);
-#define __ ideal.
-        // QQQ who knows what probability is here??
-        __ if_then(heap_base_oop, BoolTest::ne, null(), PROB_UNLIKELY(0.999)); {
-          // Sync IdealKit and graphKit.
-          sync_kit(ideal);
-          Node* st = store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type, mo, mismatched);
-          // Update IdealKit memory.
-          __ sync_kit(this);
-        } __ else_(); {
-          __ store(__ ctrl(), adr, val, type, alias_type->index(), mo, requires_atomic_access, mismatched);
-        } __ end_if();
-        // Final sync IdealKit and GraphKit.
-        final_sync(ideal);
-#undef __
-      }
+      store_to_memory(control(), adr, val, type, adr_type, mo, requires_atomic_access, unaligned, mismatched);
     }
   }
 
@@ -3150,6 +3136,43 @@
   return true;
 }
 
+#ifdef TRACE_HAVE_INTRINSICS
+
+/*
+* oop -> myklass
+* myklass->trace_id |= USED
+* return myklass->trace_id & ~0x3
+*/
+bool LibraryCallKit::inline_native_classID() {
+  Node* cls = null_check(argument(0), T_OBJECT);
+  Node* kls = load_klass_from_mirror(cls, false, NULL, 0);
+  kls = null_check(kls, T_OBJECT);
+
+  ByteSize offset = TRACE_KLASS_TRACE_ID_OFFSET;
+  Node* insp = basic_plus_adr(kls, in_bytes(offset));
+  Node* tvalue = make_load(NULL, insp, TypeLong::LONG, T_LONG, MemNode::unordered);
+
+  Node* clsused = longcon(0x01l); // set the class bit
+  Node* orl = _gvn.transform(new OrLNode(tvalue, clsused));
+  const TypePtr *adr_type = _gvn.type(insp)->isa_ptr();
+  store_to_memory(control(), insp, orl, T_LONG, adr_type, MemNode::unordered);
+
+#ifdef TRACE_ID_META_BITS
+  Node* mbits = longcon(~TRACE_ID_META_BITS);
+  tvalue = _gvn.transform(new AndLNode(tvalue, mbits));
+#endif
+#ifdef TRACE_ID_CLASS_SHIFT
+  Node* cbits = intcon(TRACE_ID_CLASS_SHIFT);
+  tvalue = _gvn.transform(new URShiftLNode(tvalue, cbits));
+#endif
+
+  set_result(tvalue);
+  return true;
+
+}
+
+#endif
+
 //------------------------inline_native_currentThread------------------
 bool LibraryCallKit::inline_native_currentThread() {
   Node* junk = NULL;
--- a/hotspot/src/share/vm/opto/macro.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/opto/macro.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -491,7 +491,7 @@
   for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) {
     Node* phi = region->fast_out(k);
     if (phi->is_Phi() && phi != mem &&
-        phi->as_Phi()->is_same_inst_field(phi_type, instance_id, alias_idx, offset)) {
+        phi->as_Phi()->is_same_inst_field(phi_type, (int)mem->_idx, instance_id, alias_idx, offset)) {
       return phi;
     }
   }
@@ -510,7 +510,7 @@
   GrowableArray <Node *> values(length, length, NULL, false);
 
   // create a new Phi for the value
-  PhiNode *phi = new PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset);
+  PhiNode *phi = new PhiNode(mem->in(0), phi_type, NULL, mem->_idx, instance_id, alias_idx, offset);
   transform_later(phi);
   value_phis->push(phi, mem->_idx);
 
--- a/hotspot/src/share/vm/opto/memnode.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -1112,7 +1112,7 @@
     for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
       Node* phi = region->fast_out(i);
       if (phi->is_Phi() && phi != mem &&
-          phi->as_Phi()->is_same_inst_field(this_type, this_iid, this_index, this_offset)) {
+          phi->as_Phi()->is_same_inst_field(this_type, (int)mem->_idx, this_iid, this_index, this_offset)) {
         return phi;
       }
     }
@@ -1395,7 +1395,7 @@
     this_iid = base->_idx;
   }
   PhaseIterGVN* igvn = phase->is_IterGVN();
-  Node* phi = new PhiNode(region, this_type, NULL, this_iid, this_index, this_offset);
+  Node* phi = new PhiNode(region, this_type, NULL, mem->_idx, this_iid, this_index, this_offset);
   for (uint i = 1; i < region->req(); i++) {
     Node* x;
     Node* the_clone = NULL;
--- a/hotspot/src/share/vm/opto/phaseX.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/opto/phaseX.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -491,6 +491,8 @@
   uint current_idx = 0; // The current new node ID. Incremented after every assignment.
   for (uint i = 0; i < _useful.size(); i++) {
     Node* n = _useful.at(i);
+    // Sanity check that fails if we ever decide to execute this phase after EA
+    assert(!n->is_Phi() || n->as_Phi()->inst_mem_id() == -1, "should not be linked to data Phi");
     const Type* type = gvn->type_or_null(n);
     new_type_array.map(current_idx, type);
 
@@ -1448,6 +1450,18 @@
     i -= num_edges;    // we deleted 1 or more copies of this edge
   }
 
+  // Search for instance field data PhiNodes in the same region pointing to the old
+  // memory PhiNode and update their instance memory ids to point to the new node.
+  if (old->is_Phi() && old->as_Phi()->type()->has_memory() && old->in(0) != NULL) {
+    Node* region = old->in(0);
+    for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
+      PhiNode* phi = region->fast_out(i)->isa_Phi();
+      if (phi != NULL && phi->inst_mem_id() == (int)old->_idx) {
+        phi->set_inst_mem_id((int)nn->_idx);
+      }
+    }
+  }
+
   // Smash all inputs to 'old', isolating him completely
   Node *temp = new Node(1);
   temp->init_req(0,nn);     // Add a use to nn to prevent him from dying
--- a/hotspot/src/share/vm/opto/type.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/opto/type.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -1015,6 +1015,13 @@
     st->print(" [narrowklass]");
   }
 }
+
+//-----------------------------------------------------------------------------
+const char* Type::str(const Type* t) {
+  stringStream ss;
+  t->dump_on(&ss);
+  return ss.as_string();
+}
 #endif
 
 //------------------------------singleton--------------------------------------
--- a/hotspot/src/share/vm/opto/type.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/opto/type.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -210,11 +210,11 @@
   static int cmp( const Type *const t1, const Type *const t2 );
   // Test for higher or equal in lattice
   // Variant that drops the speculative part of the types
-  int higher_equal(const Type *t) const {
+  bool higher_equal(const Type *t) const {
     return !cmp(meet(t),t->remove_speculative());
   }
   // Variant that keeps the speculative part of the types
-  int higher_equal_speculative(const Type *t) const {
+  bool higher_equal_speculative(const Type *t) const {
     return !cmp(meet_speculative(t),t);
   }
 
@@ -359,6 +359,8 @@
   }
   virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
   static  void dump_stats();
+
+  static const char* str(const Type* t);
 #endif
   void typerr(const Type *t) const; // Mixing types error
 
@@ -963,7 +965,7 @@
 
   // If not InstanceTop or InstanceBot, indicates that this is
   // a particular instance of this type which is distinct.
-  // This is the the node index of the allocation node creating this instance.
+  // This is the node index of the allocation node creating this instance.
   int           _instance_id;
 
   static const TypeOopPtr* make_from_klass_common(ciKlass* klass, bool klass_change, bool try_for_exact);
--- a/hotspot/src/share/vm/prims/jvm.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -3352,6 +3352,35 @@
 JVM_END
 
 
+// java.lang.ref.Reference ///////////////////////////////////////////////////////////////
+
+
+JVM_ENTRY(jobject, JVM_GetAndClearReferencePendingList(JNIEnv* env))
+  JVMWrapper("JVM_GetAndClearReferencePendingList");
+
+  MonitorLockerEx ml(Heap_lock);
+  oop ref = Universe::reference_pending_list();
+  if (ref != NULL) {
+    Universe::set_reference_pending_list(NULL);
+  }
+  return JNIHandles::make_local(env, ref);
+JVM_END
+
+JVM_ENTRY(jboolean, JVM_HasReferencePendingList(JNIEnv* env))
+  JVMWrapper("JVM_HasReferencePendingList");
+  MonitorLockerEx ml(Heap_lock);
+  return Universe::has_reference_pending_list();
+JVM_END
+
+JVM_ENTRY(void, JVM_WaitForReferencePendingList(JNIEnv* env))
+  JVMWrapper("JVM_WaitForReferencePendingList");
+  MonitorLockerEx ml(Heap_lock);
+  while (!Universe::has_reference_pending_list()) {
+    ml.wait();
+  }
+JVM_END
+
+
 // ObjectInputStream ///////////////////////////////////////////////////////////////
 
 bool force_verify_field_access(Klass* current_class, Klass* field_class, AccessFlags access, bool classloader_only) {
--- a/hotspot/src/share/vm/prims/jvm.h	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvm.h	Thu Sep 01 15:20:56 2016 -0700
@@ -297,6 +297,18 @@
 JVM_GetSystemPackages(JNIEnv *env);
 
 /*
+ * java.lang.ref.Reference
+ */
+JNIEXPORT jobject JNICALL
+JVM_GetAndClearReferencePendingList(JNIEnv *env);
+
+JNIEXPORT jboolean JNICALL
+JVM_HasReferencePendingList(JNIEnv *env);
+
+JNIEXPORT void JNICALL
+JVM_WaitForReferencePendingList(JNIEnv *env);
+
+/*
  * java.io.ObjectInputStream
  */
 JNIEXPORT jobject JNICALL
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -163,26 +163,47 @@
 
 bool needs_module_property_warning = false;
 
-#define MODULE_PROPERTY_PREFIX "jdk.module"
-#define MODULE_PROPERTY_PREFIX_LEN 10
-#define MODULE_MAIN_PROPERTY "jdk.module.main"
-#define MODULE_MAIN_PROPERTY_LEN 15
-
-// Return TRUE if option matches property, or property=, or property..
-static bool matches_property_prefix(const char* option, const char* property, size_t len) {
-  return (strncmp(option, property, len) == 0) &&
-          (option[len] == '=' || option[len] == '.' || option[len] == '\0');
+#define MODULE_PROPERTY_PREFIX "jdk.module."
+#define MODULE_PROPERTY_PREFIX_LEN 11
+#define ADDEXPORTS "addexports"
+#define ADDEXPORTS_LEN 10
+#define ADDREADS "addreads"
+#define ADDREADS_LEN 8
+#define PATCH "patch"
+#define PATCH_LEN 5
+#define ADDMODS "addmods"
+#define ADDMODS_LEN 7
+#define LIMITMODS "limitmods"
+#define LIMITMODS_LEN 9
+#define PATH "path"
+#define PATH_LEN 4
+#define UPGRADE_PATH "upgrade.path"
+#define UPGRADE_PATH_LEN 12
+
+// Return TRUE if option matches 'property', or 'property=', or 'property.'.
+static bool matches_property_suffix(const char* option, const char* property, size_t len) {
+  return ((strncmp(option, property, len) == 0) &&
+          (option[len] == '=' || option[len] == '.' || option[len] == '\0'));
 }
 
-// Return true if the property is either "jdk.module" or starts with "jdk.module.",
-// but does not start with "jdk.module.main".
-// Return false if jdk.module.main because jdk.module.main and jdk.module.main.class
-// are valid non-internal system properties.
-// "property" should be passed without the leading "-D".
+// Return true if property starts with "jdk.module." and its ensuing chars match
+// any of the reserved module properties.
+// property should be passed without the leading "-D".
 bool Arguments::is_internal_module_property(const char* property) {
   assert((strncmp(property, "-D", 2) != 0), "Unexpected leading -D");
-  return (matches_property_prefix(property, MODULE_PROPERTY_PREFIX, MODULE_PROPERTY_PREFIX_LEN) &&
-          !matches_property_prefix(property, MODULE_MAIN_PROPERTY, MODULE_MAIN_PROPERTY_LEN));
+  if  (strncmp(property, MODULE_PROPERTY_PREFIX, MODULE_PROPERTY_PREFIX_LEN) == 0) {
+    const char* property_suffix = property + MODULE_PROPERTY_PREFIX_LEN;
+    if (matches_property_suffix(property_suffix, ADDEXPORTS, ADDEXPORTS_LEN) ||
+        matches_property_suffix(property_suffix, ADDREADS, ADDREADS_LEN) ||
+        matches_property_suffix(property_suffix, PATCH, PATCH_LEN) ||
+        matches_property_suffix(property_suffix, ADDMODS, ADDMODS_LEN) ||
+        matches_property_suffix(property_suffix, LIMITMODS, LIMITMODS_LEN) ||
+        matches_property_suffix(property_suffix, PATH, PATH_LEN) ||
+        matches_property_suffix(property_suffix, UPGRADE_PATH, UPGRADE_PATH_LEN)) {
+      return true;
+    }
+  }
+  return false;
 }
 
 // Process java launcher properties.
@@ -4287,8 +4308,8 @@
   }
 
   if (needs_module_property_warning) {
-    warning("Ignoring system property options whose names start with '-Djdk.module'."
-            "  They are reserved for internal use.");
+    warning("Ignoring system property options whose names match the '-Djdk.module.*'."
+            " names that are reserved for internal use.");
   }
 
 #if defined(_ALLBSD_SOURCE) || defined(AIX)  // UseLargePages is not yet supported on BSD and AIX.
--- a/hotspot/src/share/vm/runtime/atomic.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/runtime/atomic.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -76,6 +76,7 @@
 
   // Atomically add to a location. Returns updated value. add*() provide:
   // <fence> add-value-to-dest <membar StoreLoad|StoreStore>
+  inline static jshort   add    (jshort   add_value, volatile jshort*   dest);
   inline static jint     add    (jint     add_value, volatile jint*     dest);
   inline static size_t   add    (size_t   add_value, volatile size_t*   dest);
   inline static intptr_t add_ptr(intptr_t add_value, volatile intptr_t* dest);
@@ -208,10 +209,11 @@
   return old;
 }
 
-inline void Atomic::inc(volatile short* dest) {
-  // Most platforms do not support atomic increment on a 2-byte value. However,
+inline jshort Atomic::add(jshort add_value, volatile jshort* dest) {
+  // Most platforms do not support atomic add on a 2-byte value. However,
   // if the value occupies the most significant 16 bits of an aligned 32-bit
-  // word, then we can do this with an atomic add of 0x10000 to the 32-bit word.
+  // word, then we can do this with an atomic add of (add_value << 16)
+  // to the 32-bit word.
   //
   // The least significant parts of this 32-bit word will never be affected, even
   // in case of overflow/underflow.
@@ -219,21 +221,20 @@
   // Use the ATOMIC_SHORT_PAIR macro (see macros.hpp) to get the desired alignment.
 #ifdef VM_LITTLE_ENDIAN
   assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
-  (void)Atomic::add(0x10000, (volatile int*)(dest-1));
+  jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest-1));
 #else
   assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
-  (void)Atomic::add(0x10000, (volatile int*)(dest));
+  jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest));
 #endif
+  return (jshort)(new_value >> 16); // preserves sign
 }
 
-inline void Atomic::dec(volatile short* dest) {
-#ifdef VM_LITTLE_ENDIAN
-  assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
-  (void)Atomic::add(-0x10000, (volatile int*)(dest-1));
-#else
-  assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
-  (void)Atomic::add(-0x10000, (volatile int*)(dest));
-#endif
+inline void Atomic::inc(volatile jshort* dest) {
+  (void)add(1, dest);
+}
+
+inline void Atomic::dec(volatile jshort* dest) {
+  (void)add(-1, dest);
 }
 
 #endif // SHARE_VM_RUNTIME_ATOMIC_HPP
--- a/hotspot/src/share/vm/runtime/globals.hpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Thu Sep 01 15:20:56 2016 -0700
@@ -3017,9 +3017,6 @@
           "Number of receiver types to record in call/cast profile")        \
           range(0, 8)                                                       \
                                                                             \
-  experimental(intx, MethodProfileWidth, 0,                                 \
-          "Number of methods to record in call profile")                    \
-                                                                            \
   develop(intx, BciProfileWidth,      2,                                    \
           "Number of return bci's to record in ret profile")                \
                                                                             \
--- a/hotspot/src/share/vm/runtime/thread.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -35,7 +35,6 @@
 #include "compiler/compileTask.hpp"
 #include "gc/shared/gcId.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
 #include "gc/shared/workgroup.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/linkResolver.hpp"
@@ -3718,14 +3717,6 @@
   Management::record_vm_init_completed();
 #endif // INCLUDE_MANAGEMENT
 
-  // Note that we do not use CHECK_0 here since we are inside an EXCEPTION_MARK and
-  // set_init_completed has just been called, causing exceptions not to be shortcut
-  // anymore. We call vm_exit_during_initialization directly instead.
-
-  // Initialize reference pending list locker
-  bool needs_locker_thread = Universe::heap()->needs_reference_pending_list_locker_thread();
-  ReferencePendingListLocker::initialize(needs_locker_thread, CHECK_JNI_ERR);
-
   // Signal Dispatcher needs to be started before VMInit event is posted
   os::signal_init();
 
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -54,7 +54,6 @@
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/generation.hpp"
 #include "gc/shared/generationSpec.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
 #include "gc/shared/space.hpp"
 #include "interpreter/bytecodeInterpreter.hpp"
 #include "interpreter/bytecodes.hpp"
@@ -242,7 +241,7 @@
   nonstatic_field(ConstantPool,                _reference_map,                                Array<u2>*)                            \
   nonstatic_field(ConstantPoolCache,           _length,                                       int)                                   \
   nonstatic_field(ConstantPoolCache,           _constant_pool,                                ConstantPool*)                         \
-  nonstatic_field(InstanceKlass,               _array_klasses,                                Klass*)                                \
+  volatile_nonstatic_field(InstanceKlass,      _array_klasses,                                Klass*)                                \
   nonstatic_field(InstanceKlass,               _methods,                                      Array<Method*>*)                       \
   nonstatic_field(InstanceKlass,               _default_methods,                              Array<Method*>*)                       \
   nonstatic_field(InstanceKlass,               _local_interfaces,                             Array<Klass*>*)                        \
@@ -271,7 +270,7 @@
   nonstatic_field(InstanceKlass,               _osr_nmethods_head,                            nmethod*)                              \
   JVMTI_ONLY(nonstatic_field(InstanceKlass,    _breakpoints,                                  BreakpointInfo*))                      \
   nonstatic_field(InstanceKlass,               _generic_signature_index,                      u2)                                    \
-  nonstatic_field(InstanceKlass,               _methods_jmethod_ids,                          jmethodID*)                            \
+  volatile_nonstatic_field(InstanceKlass,      _methods_jmethod_ids,                          jmethodID*)                            \
   volatile_nonstatic_field(InstanceKlass,      _idnum_allocated_count,                        u2)                                    \
   nonstatic_field(InstanceKlass,               _annotations,                                  Annotations*)                          \
   nonstatic_field(InstanceKlass,               _method_ordering,                              Array<int>*)                           \
@@ -1637,7 +1636,6 @@
            declare_type(JavaThread, Thread)                               \
            declare_type(JvmtiAgentThread, JavaThread)                     \
            declare_type(ServiceThread, JavaThread)                        \
-           declare_type(ReferencePendingListLockerThread, JavaThread)     \
   declare_type(CompilerThread, JavaThread)                                \
   declare_type(CodeCacheSweeperThread, JavaThread)                        \
   declare_toplevel_type(OSThread)                                         \
@@ -2628,6 +2626,11 @@
   declare_constant(Deoptimization::Reason_rtm_state_change)               \
   declare_constant(Deoptimization::Reason_unstable_if)                    \
   declare_constant(Deoptimization::Reason_unstable_fused_if)              \
+  NOT_ZERO(JVMCI_ONLY(declare_constant(Deoptimization::Reason_aliasing)))                       \
+  NOT_ZERO(JVMCI_ONLY(declare_constant(Deoptimization::Reason_transfer_to_interpreter)))        \
+  NOT_ZERO(JVMCI_ONLY(declare_constant(Deoptimization::Reason_not_compiled_exception_handler))) \
+  NOT_ZERO(JVMCI_ONLY(declare_constant(Deoptimization::Reason_unresolved)))                     \
+  NOT_ZERO(JVMCI_ONLY(declare_constant(Deoptimization::Reason_jsr_mismatch)))                   \
   declare_constant(Deoptimization::Reason_tenured)                        \
   declare_constant(Deoptimization::Reason_LIMIT)                          \
   declare_constant(Deoptimization::Reason_RECORDED_LIMIT)                 \
@@ -2752,7 +2755,13 @@
   declare_constant(ConcreteRegisterImpl::number_of_registers)             \
   declare_preprocessor_constant("REG_COUNT", REG_COUNT)                \
   declare_c2_preprocessor_constant("SAVED_ON_ENTRY_REG_COUNT", SAVED_ON_ENTRY_REG_COUNT) \
-  declare_c2_preprocessor_constant("C_SAVED_ON_ENTRY_REG_COUNT", C_SAVED_ON_ENTRY_REG_COUNT)
+  declare_c2_preprocessor_constant("C_SAVED_ON_ENTRY_REG_COUNT", C_SAVED_ON_ENTRY_REG_COUNT) \
+                                                                          \
+  /****************/                                                      \
+  /* JVMCI */                                                             \
+  /****************/                                                      \
+                                                                          \
+  declare_preprocessor_constant("INCLUDE_JVMCI", INCLUDE_JVMCI)
 
 
 //--------------------------------------------------------------------------------
--- a/hotspot/src/share/vm/utilities/internalVMTests.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -56,12 +56,10 @@
   run_unit_test(CollectedHeap_test);
   run_unit_test(QuickSort_test);
   run_unit_test(GuardedMemory_test);
-  run_unit_test(AltHashing_test);
   run_unit_test(TestNewSize_test);
   run_unit_test(TestOldSize_test);
   run_unit_test(TestKlass_test);
   run_unit_test(TestBitMap_test);
-  run_unit_test(TestAsUtf8);
   run_unit_test(TestResourcehash_test);
   run_unit_test(ObjectMonitor_test);
   run_unit_test(Test_linked_list);
@@ -89,16 +87,13 @@
   run_unit_test(VMStructs_test);
 #endif
 #if INCLUDE_ALL_GCS
-  run_unit_test(TestOldFreeSpaceCalculation_test);
   run_unit_test(TestG1BiasedArray_test);
   run_unit_test(TestBufferingOopClosure_test);
-  run_unit_test(TestCodeCacheRemSet_test);
   if (UseG1GC) {
     run_unit_test(FreeRegionList_test);
     run_unit_test(IHOP_test);
   }
   run_unit_test(test_memset_with_concurrent_readers);
-  run_unit_test(TestPredictions_test);
   run_unit_test(WorkerDataArray_test);
   run_unit_test(ParallelCompact_test);
 #endif
--- a/hotspot/src/share/vm/utilities/utf8.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/src/share/vm/utilities/utf8.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -547,30 +547,3 @@
 template int UNICODE::quoted_ascii_length<jchar>(jchar* base, int length);
 template void UNICODE::as_quoted_ascii<jbyte>(const jbyte* base, int length, char* buf, int buflen);
 template void UNICODE::as_quoted_ascii<jchar>(const jchar* base, int length, char* buf, int buflen);
-
-
-#ifndef PRODUCT
-void TestAsUtf8() {
-  char res[60];
-  jchar str[20];
-
-  for (int i = 0; i < 20; i++) {
-    str[i] = 0x0800; // char that is 2B in UTF-16 but 3B in UTF-8
-  }
-  str[19] = (jchar)'\0';
-
-  // The resulting string in UTF-8 is 3*19 bytes long, but should be truncated
-  UNICODE::as_utf8(str, 19, res, 10);
-  assert(strlen(res) == 9, "string should be truncated here");
-
-  UNICODE::as_utf8(str, 19, res, 18);
-  assert(strlen(res) == 15, "string should be truncated here");
-
-  UNICODE::as_utf8(str, 19, res, 20);
-  assert(strlen(res) == 18, "string should be truncated here");
-
-  // Test with an "unbounded" buffer
-  UNICODE::as_utf8(str, 19, res, INT_MAX);
-  assert(strlen(res) == 3*19, "string should end here");
-}
-#endif
--- a/hotspot/test/compiler/jsr292/NullConstantReceiver.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/compiler/jsr292/NullConstantReceiver.java	Thu Sep 01 15:20:56 2016 -0700
@@ -23,9 +23,10 @@
 
 /**
  * @test
- * @bug 8059556
+ * @bug 8059556 8158639
  *
  * @run main/othervm -Xbatch compiler.jsr292.NullConstantReceiver
+ * @run main/othervm -Xbatch -XX:CompileCommand=exclude,*::run compiler.jsr292.NullConstantReceiver
  */
 
 package compiler.jsr292;
--- a/hotspot/test/compiler/jvmci/compilerToVM/CompileCodeTestCase.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/compiler/jvmci/compilerToVM/CompileCodeTestCase.java	Thu Sep 01 15:20:56 2016 -0700
@@ -107,6 +107,12 @@
     }
 
     public NMethod compile(int level) {
+        String directive = "[{ match: \"" + executable.getDeclaringClass().getName().replace('.', '/')
+                + "." + (executable instanceof Constructor ? "<init>" : executable.getName())
+                + "\", " + "BackgroundCompilation: false }]";
+        if (WB.addCompilerDirective(directive) != 1) {
+            throw new Error("Failed to add compiler directive: " + directive);
+        }
         boolean enqueued = WB.enqueueMethodForCompilation(executable,
                 level, bci);
         if (!enqueued) {
--- a/hotspot/test/compiler/jvmci/compilerToVM/DisassembleCodeBlobTest.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/compiler/jvmci/compilerToVM/DisassembleCodeBlobTest.java	Thu Sep 01 15:20:56 2016 -0700
@@ -34,8 +34,9 @@
  *          jdk.vm.ci/jdk.vm.ci.hotspot
  *          jdk.vm.ci/jdk.vm.ci.code
  *
- * @ignore 8139700
- * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper sun.hotspot.WhiteBox
+ * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @build sun.hotspot.WhiteBox
+ *        compiler.jvmci.compilerToVM.DisassembleCodeBlobTest
  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
  *                                sun.hotspot.WhiteBox$WhiteBoxPermission
  * @run main/othervm -Xbootclasspath/a:.
--- a/hotspot/test/compiler/jvmci/compilerToVM/InitializeConfigurationTest.java	Thu Sep 01 14:09:01 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8136421
- * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64")
- * @library / /test/lib
- * @library ../common/patches
- * @modules java.base/jdk.internal.misc
- * @modules jdk.vm.ci/jdk.vm.ci.hotspot
- * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
- *                   compiler.jvmci.compilerToVM.InitializeConfigurationTest
- */
-
-package compiler.jvmci.compilerToVM;
-
-import jdk.test.lib.Asserts;
-import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
-import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
-import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
-
-public class InitializeConfigurationTest {
-    public static void main(String args[]) {
-        new InitializeConfigurationTest().runTest();
-    }
-
-    private void runTest() {
-        TestHotSpotVMConfig config = new TestHotSpotVMConfig(HotSpotJVMCIRuntime.runtime().getConfigStore());
-        Asserts.assertNE(config.codeCacheHighBound, 0L, "Got null address");
-        Asserts.assertNE(config.stubRoutineJintArrayCopy, 0L, "Got null address");
-    }
-
-    private static class TestHotSpotVMConfig extends HotSpotVMConfigAccess {
-
-        private TestHotSpotVMConfig(HotSpotVMConfigStore store) {
-            super(store);
-        }
-
-        final long codeCacheHighBound = getFieldValue("CodeCache::_high_bound", Long.class);
-        final long stubRoutineJintArrayCopy = getFieldValue("StubRoutines::_jint_arraycopy", Long.class);
-    }
-}
--- a/hotspot/test/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java	Thu Sep 01 15:20:56 2016 -0700
@@ -35,8 +35,10 @@
  *          jdk.vm.ci/jdk.vm.ci.code
  *          jdk.vm.ci/jdk.vm.ci.runtime
  *
- * @ignore 8139700
- * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper sun.hotspot.WhiteBox
+ * @ignore 8163894
+ * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @build compiler.jvmci.compilerToVM.InvalidateInstalledCodeTest
+ * @build sun.hotspot.WhiteBox
  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
  *                                sun.hotspot.WhiteBox$WhiteBoxPermission
  * @run main/othervm -Xbootclasspath/a:.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ReadConfigurationTest.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8136421
+ * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64")
+ * @library / /test/lib
+ * @library ../common/patches
+ * @modules java.base/jdk.internal.misc
+ * @modules jdk.vm.ci/jdk.vm.ci.hotspot
+ * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @build compiler.jvmci.compilerToVM.ReadConfigurationTest
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *                   compiler.jvmci.compilerToVM.ReadConfigurationTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import jdk.test.lib.Asserts;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
+import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
+import jdk.vm.ci.hotspot.VMIntrinsicMethod;
+
+public class ReadConfigurationTest {
+    public static void main(String args[]) {
+        new ReadConfigurationTest().runTest();
+    }
+
+    private void runTest() {
+        TestHotSpotVMConfig config = new TestHotSpotVMConfig(HotSpotJVMCIRuntime.runtime().getConfigStore());
+        Asserts.assertNE(config.codeCacheHighBound, 0L, "Got null address");
+        Asserts.assertNE(config.stubRoutineJintArrayCopy, 0L, "Got null address");
+
+        for (VMIntrinsicMethod m : config.getStore().getIntrinsics()) {
+            Asserts.assertNotNull(m);
+            Asserts.assertNotNull(m.declaringClass);
+            Asserts.assertFalse(m.declaringClass.contains("."),
+                "declaringClass should be in class file format: " + m.declaringClass);
+            Asserts.assertNotNull(m.name);
+            Asserts.assertNotNull(m.descriptor);
+            Asserts.assertTrue(m.id > 0);
+        }
+    }
+
+    private static class TestHotSpotVMConfig extends HotSpotVMConfigAccess {
+
+        private TestHotSpotVMConfig(HotSpotVMConfigStore store) {
+            super(store);
+        }
+
+        final long codeCacheHighBound = getFieldValue("CodeCache::_high_bound", Long.class);
+        final long stubRoutineJintArrayCopy = getFieldValue("StubRoutines::_jint_arraycopy", Long.class);
+    }
+}
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/MaxOopMapStackOffsetTest.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/MaxOopMapStackOffsetTest.java	Thu Sep 01 15:20:56 2016 -0700
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") & os.arch != "aarch64"
  * @library /
  * @modules jdk.vm.ci/jdk.vm.ci.hotspot
  *          jdk.vm.ci/jdk.vm.ci.meta
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java	Thu Sep 01 15:20:56 2016 -0700
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") & os.arch != "aarch64"
  * @library /test/lib /
  * @modules jdk.vm.ci/jdk.vm.ci.hotspot
  *          jdk.vm.ci/jdk.vm.ci.code
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java	Thu Sep 01 15:20:56 2016 -0700
@@ -33,19 +33,16 @@
 
 package jdk.vm.ci.runtime.test;
 
-import jdk.vm.ci.meta.ConstantPool;
-import jdk.vm.ci.meta.ExceptionHandler;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
-import org.junit.Assert;
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
-import java.lang.invoke.MethodHandle;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
@@ -57,10 +54,13 @@
 import java.util.Map;
 import java.util.Set;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import org.junit.Assert;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.ConstantPool;
+import jdk.vm.ci.meta.ExceptionHandler;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
 
 /**
  * Tests for {@link ResolvedJavaMethod}.
@@ -407,20 +407,6 @@
         }
     }
 
-    @Test
-    public void isSignaturePolymorphicTest() {
-        ResolvedJavaType methodHandleType = metaAccess.lookupJavaType(MethodHandle.class);
-        assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "invokeExact", metaAccess));
-        assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "invoke", metaAccess));
-        assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "invokeBasic", metaAccess));
-        assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToVirtual", metaAccess));
-        assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToStatic", metaAccess));
-        assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToSpecial", metaAccess));
-        assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToInterface", metaAccess));
-        assertFalse(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "type", metaAccess));
-        assertFalse(ResolvedJavaMethod.isSignaturePolymorphic(metaAccess.lookupJavaType(Object.class), "toString", metaAccess));
-    }
-
     /**
      * All public non-final methods should be available in the vtable.
      */
--- a/hotspot/test/compiler/profiling/spectrapredefineclass/Launcher.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/compiler/profiling/spectrapredefineclass/Launcher.java	Thu Sep 01 15:20:56 2016 -0700
@@ -40,7 +40,7 @@
 package compiler.profiling.spectrapredefineclass;
 
 import jdk.test.lib.JDKToolLauncher;
-import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.process.OutputAnalyzer;
 
 import java.io.File;
 import java.io.IOException;
--- a/hotspot/test/compiler/profiling/spectrapredefineclass_classloaders/Launcher.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/compiler/profiling/spectrapredefineclass_classloaders/Launcher.java	Thu Sep 01 15:20:56 2016 -0700
@@ -43,7 +43,7 @@
 package compiler.profiling.spectrapredefineclass_classloaders;
 
 import jdk.test.lib.JDKToolLauncher;
-import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.process.OutputAnalyzer;
 
 import java.io.File;
 import java.io.IOException;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/unsafe/MixedUnsafeStoreObject.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8155635
+ * @modules java.base/jdk.internal.misc
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch -XX:-TieredCompilation compiler.unsafe.MixedUnsafeStoreObject
+ * @run main/othervm -Xbatch compiler.unsafe.MixedUnsafeStoreObject
+ */
+
+package compiler.unsafe;
+
+import jdk.internal.misc.Unsafe;
+
+public class MixedUnsafeStoreObject {
+    static final Unsafe UNSAFE = Unsafe.getUnsafe();
+
+    static final long F_OFFSET;
+
+    static {
+        try {
+            F_OFFSET = UNSAFE.objectFieldOffset(T.class.getDeclaredField("f"));
+        } catch (Exception e) {
+            throw new Error(e);
+        }
+    }
+
+    static class T {
+        Object f;
+    }
+
+    public static void testFieldInstanceObject(Object t) {
+        for (int c = 0; c < 20000; c++) { // trigger OSR compilation
+            // java/lang/Object+12 *
+            // _base = InstPtr, _ptr = BotPTR, _field = NULL, mismatched = true
+            UNSAFE.putObject(t, F_OFFSET, "foo");
+        }
+    }
+
+    public static void testFieldInstanceT(T t) {
+        for (int c = 0; c < 20000; c++) { // trigger OSR compilation
+            // ...$T+12 *
+            // _base = InstPtr, _ptr = BotPTR, _field = T.f, mismatched = false
+            UNSAFE.putObject(t, F_OFFSET, "foo");
+        }
+    }
+    public static void main(String[] args) {
+        testFieldInstanceObject(new T());
+        testFieldInstanceT(new T());
+    }
+}
+
--- a/hotspot/test/compiler/unsafe/OpaqueAccesses.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/compiler/unsafe/OpaqueAccesses.java	Thu Sep 01 15:20:56 2016 -0700
@@ -30,6 +30,22 @@
  *
  * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  *                                 -XX:-TieredCompilation -Xbatch
+ *                                 -XX:+UseCompressedOops -XX:+UseCompressedClassPointers
+ *                                 -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test*
+ *                                 compiler.unsafe.OpaqueAccesses
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
+ *                                 -XX:-TieredCompilation -Xbatch
+ *                                 -XX:+UseCompressedOops -XX:-UseCompressedClassPointers
+ *                                 -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test*
+ *                                 compiler.unsafe.OpaqueAccesses
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
+ *                                 -XX:-TieredCompilation -Xbatch
+ *                                 -XX:-UseCompressedOops -XX:+UseCompressedClassPointers
+ *                                 -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test*
+ *                                 compiler.unsafe.OpaqueAccesses
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
+ *                                 -XX:-TieredCompilation -Xbatch
+ *                                 -XX:-UseCompressedOops -XX:-UseCompressedClassPointers
  *                                 -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test*
  *                                 compiler.unsafe.OpaqueAccesses
  */
@@ -61,6 +77,7 @@
     }
 
     private Object f = new Object();
+    private long l1, l2;
 
     static Object testFixedOffsetField(Object o) {
         return UNSAFE.getObject(o, F_OFFSET);
@@ -74,6 +91,22 @@
         return UNSAFE.getInt(o, 4);
     }
 
+    static int testFixedOffsetHeader8(Object o) {
+        return UNSAFE.getInt(o, 8);
+    }
+
+    static int testFixedOffsetHeader12(Object o) {
+        return UNSAFE.getInt(o, 12);
+    }
+
+    static int testFixedOffsetHeader16(Object o) {
+        return UNSAFE.getInt(o, 16);
+    }
+
+    static int testFixedOffsetHeader17(Object o) {
+        return UNSAFE.getIntUnaligned(o, 17);
+    }
+
     static Object testFixedBase(long off) {
         return UNSAFE.getObject(INSTANCE, off);
     }
@@ -90,6 +123,22 @@
         return UNSAFE.getInt(arr, 4);
     }
 
+    static int testFixedOffsetHeaderArray8(Object[] arr) {
+        return UNSAFE.getInt(arr, 8);
+    }
+
+    static int testFixedOffsetHeaderArray12(Object[] arr) {
+        return UNSAFE.getInt(arr, 12);
+    }
+
+    static int testFixedOffsetHeaderArray16(Object[] arr) {
+        return UNSAFE.getInt(arr, 16);
+    }
+
+    static int testFixedOffsetHeaderArray17(Object[] arr) {
+        return UNSAFE.getIntUnaligned(arr, 17);
+    }
+
     static Object testFixedOffsetArray(Object[] arr) {
         return UNSAFE.getObject(arr, E_OFFSET);
     }
@@ -118,6 +167,10 @@
             testFixedOffsetField(INSTANCE);
             testFixedOffsetHeader0(INSTANCE);
             testFixedOffsetHeader4(INSTANCE);
+            testFixedOffsetHeader8(INSTANCE);
+            testFixedOffsetHeader12(INSTANCE);
+            testFixedOffsetHeader16(INSTANCE);
+            testFixedOffsetHeader17(INSTANCE);
             testFixedBase(F_OFFSET);
             testOpaque(INSTANCE, F_OFFSET);
             testMixedAccess();
@@ -125,6 +178,10 @@
             // Array
             testFixedOffsetHeaderArray0(ARRAY);
             testFixedOffsetHeaderArray4(ARRAY);
+            testFixedOffsetHeaderArray8(ARRAY);
+            testFixedOffsetHeaderArray12(ARRAY);
+            testFixedOffsetHeaderArray16(ARRAY);
+            testFixedOffsetHeaderArray17(ARRAY);
             testFixedOffsetArray(ARRAY);
             testFixedBaseArray(E_OFFSET);
             testOpaqueArray(ARRAY, E_OFFSET);
--- a/hotspot/test/gc/TestCardTablePageCommits.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/TestCardTablePageCommits.java	Thu Sep 01 15:20:56 2016 -0700
@@ -34,7 +34,6 @@
  * @requires vm.gc.Parallel
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
- *          java.management
  * @run driver TestCardTablePageCommits
  */
 public class TestCardTablePageCommits {
--- a/hotspot/test/gc/TestObjectAlignment.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/TestObjectAlignment.java	Thu Sep 01 15:20:56 2016 -0700
@@ -28,7 +28,6 @@
  * @summary G1: Concurrent marking crashes with -XX:ObjectAlignmentInBytes>=32 in 64bit VMs
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
- *          java.management
  * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=8
  * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=16
  * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=32
--- a/hotspot/test/gc/TestSmallHeap.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/TestSmallHeap.java	Thu Sep 01 15:20:56 2016 -0700
@@ -28,7 +28,6 @@
  * @summary Verify that starting the VM with a small heap works
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
- * @modules java.management/sun.management
  * @build sun.hotspot.WhiteBox
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI TestSmallHeap
--- a/hotspot/test/gc/TestSoftReferencesBehaviorOnOOME.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/TestSoftReferencesBehaviorOnOOME.java	Thu Sep 01 15:20:56 2016 -0700
@@ -27,7 +27,6 @@
  * @summary Tests that all SoftReferences has been cleared at time of OOM.
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
- *          java.management
  * @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 512 2k
  * @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 128k 256k
  * @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 2k 32k
--- a/hotspot/test/gc/TestVerifyDuringStartup.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/TestVerifyDuringStartup.java	Thu Sep 01 15:20:56 2016 -0700
@@ -27,7 +27,6 @@
  * @summary Simple test run with -XX:+VerifyDuringStartup -XX:-UseTLAB to verify 8010463
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
- *          java.management
  */
 
 import jdk.test.lib.JDKToolFinder;
--- a/hotspot/test/gc/TestVerifySilently.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/TestVerifySilently.java	Thu Sep 01 15:20:56 2016 -0700
@@ -27,7 +27,6 @@
  * @summary Test silent verification.
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
- *          java.management
  */
 
 import jdk.test.lib.process.ProcessTools;
--- a/hotspot/test/gc/TestVerifySubSet.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/TestVerifySubSet.java	Thu Sep 01 15:20:56 2016 -0700
@@ -27,7 +27,6 @@
  * @summary Test VerifySubSet option
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
- *          java.management
  */
 
 import jdk.test.lib.process.ProcessTools;
--- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegions.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegions.java	Thu Sep 01 15:20:56 2016 -0700
@@ -27,6 +27,7 @@
  * @summary Test to make sure that eager reclaim of humongous objects work. We simply try to fill
  * up the heap with humongous objects that should be eagerly reclaimable to avoid Full GC.
  * @key gc
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java	Thu Sep 01 15:20:56 2016 -0700
@@ -27,6 +27,7 @@
  * @summary Test to make sure that eager reclaim of humongous objects correctly clears
  * mark bitmaps at reclaim.
  * @key gc
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java	Thu Sep 01 15:20:56 2016 -0700
@@ -30,6 +30,7 @@
  * referencing that we know is in the old gen. After changing this reference, the object
  * should still be eagerly reclaimable to avoid Full GC.
  * @key gc
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java	Thu Sep 01 15:20:56 2016 -0700
@@ -27,6 +27,7 @@
  * @summary Ensure that the output for a G1TraceEagerReclaimHumongousObjects
  * includes the expected necessary messages.
  * @key gc
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/g1/TestGCLogMessages.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestGCLogMessages.java	Thu Sep 01 15:20:56 2016 -0700
@@ -27,6 +27,7 @@
  * @summary Ensure the output for a minor GC with G1
  * includes the expected necessary messages.
  * @key gc
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java	Thu Sep 01 15:20:56 2016 -0700
@@ -25,6 +25,7 @@
  * @test TestHumongousAllocInitialMark
  * @bug 7168848
  * @summary G1: humongous object allocations should initiate marking cycles when necessary
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/g1/TestHumongousAllocNearlyFullRegion.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestHumongousAllocNearlyFullRegion.java	Thu Sep 01 15:20:56 2016 -0700
@@ -26,6 +26,7 @@
  * @bug 8143587
  * @summary G1: humongous object allocations should work even when there is
  *              not enough space in the heapRegion to fit a filler object.
+ * @requires vm.gc.G1
  * @modules java.base/jdk.internal.misc
  * @library /test/lib
  * @run driver TestHumongousAllocNearlyFullRegion
--- a/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java	Thu Sep 01 15:20:56 2016 -0700
@@ -26,6 +26,7 @@
  * @key regression
  * @key gc
  * @bug 8027756
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java	Thu Sep 01 15:20:56 2016 -0700
@@ -26,6 +26,7 @@
  * @key gc
  * @bug 8014240
  * @summary Test output of G1PrintRegionRememberedSetInfo
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/g1/TestStringDeduplicationAgeThreshold.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringDeduplicationAgeThreshold.java	Thu Sep 01 15:20:56 2016 -0700
@@ -26,6 +26,7 @@
  * @summary Test string deduplication age threshold
  * @bug 8029075
  * @key gc
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/g1/TestStringDeduplicationFullGC.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringDeduplicationFullGC.java	Thu Sep 01 15:20:56 2016 -0700
@@ -26,6 +26,7 @@
  * @summary Test string deduplication during full GC
  * @bug 8029075
  * @key gc
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/g1/TestStringDeduplicationInterned.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringDeduplicationInterned.java	Thu Sep 01 15:20:56 2016 -0700
@@ -26,6 +26,7 @@
  * @summary Test string deduplication of interned strings
  * @bug 8029075
  * @key gc
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/g1/TestStringDeduplicationPrintOptions.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringDeduplicationPrintOptions.java	Thu Sep 01 15:20:56 2016 -0700
@@ -26,6 +26,7 @@
  * @summary Test string deduplication print options
  * @bug 8029075
  * @key gc
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/g1/TestStringDeduplicationTableRehash.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringDeduplicationTableRehash.java	Thu Sep 01 15:20:56 2016 -0700
@@ -26,6 +26,7 @@
  * @summary Test string deduplication table rehash
  * @bug 8029075
  * @key gc
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/g1/TestStringDeduplicationTableResize.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringDeduplicationTableResize.java	Thu Sep 01 15:20:56 2016 -0700
@@ -26,6 +26,7 @@
  * @summary Test string deduplication table resize
  * @bug 8029075
  * @key gc
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/g1/TestStringDeduplicationYoungGC.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringDeduplicationYoungGC.java	Thu Sep 01 15:20:56 2016 -0700
@@ -26,6 +26,7 @@
  * @summary Test string deduplication during young GC
  * @bug 8029075
  * @key gc
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/g1/TestStringSymbolTableStats.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringSymbolTableStats.java	Thu Sep 01 15:20:56 2016 -0700
@@ -26,6 +26,7 @@
  * @bug 8027476 8027455
  * @summary Ensure that the G1TraceStringSymbolTableScrubbing prints the expected message.
  * @key gc
+ * @requires vm.gc.G1
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/gc/serial/HeapChangeLogging.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/gc/serial/HeapChangeLogging.java	Thu Sep 01 15:20:56 2016 -0700
@@ -24,9 +24,9 @@
 /*
  * @test HeapChangeLogging.java
  * @bug 8027440
+ * @requires vm.gc.Serial
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
- *          java.management
  * @summary Allocate to get a promotion failure and verify that that heap change logging is present.
  * @run main HeapChangeLogging
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/classfile/test_AltHashing.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+#include "precompiled.hpp"
+#include "classfile/altHashing.hpp"
+#include "unittest.hpp"
+
+// Internal test for alternate hashing.  Translated from JDK version
+// test/sun/misc/Hashing.java
+static const jbyte ONE_BYTE[] = {(jbyte) 0x80};
+static const jbyte TWO_BYTE[] = {(jbyte) 0x80, (jbyte) 0x81};
+static const jchar ONE_CHAR[] = {(jchar) 0x8180};
+static const jbyte THREE_BYTE[] = {(jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82};
+static const jbyte FOUR_BYTE[] = {(jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83};
+static const jchar TWO_CHAR[] = {(jchar) 0x8180, (jchar) 0x8382};
+static const jint ONE_INT[] = {(jint) 0x83828180};
+static const jbyte SIX_BYTE[] = {(jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85};
+static const jchar THREE_CHAR[] = {(jchar) 0x8180, (jchar) 0x8382, (jchar) 0x8584};
+static const jbyte EIGHT_BYTE[] = {
+  (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82,
+  (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85,
+  (jbyte) 0x86, (jbyte) 0x87
+};
+static const jchar FOUR_CHAR[] = {
+  (jchar) 0x8180, (jchar) 0x8382,
+  (jchar) 0x8584, (jchar) 0x8786
+};
+
+static const jint TWO_INT[] = {(jint) 0x83828180, (jint) 0x87868584};
+static const juint MURMUR3_32_X86_CHECK_VALUE = 0xB0F57EE3;
+
+class AltHashingTest : public ::testing::Test {
+ public:
+
+  static juint murmur3_32(const int* data, int len) {
+    return AltHashing::murmur3_32(data, len);
+  }
+};
+
+TEST_F(AltHashingTest, murmur3_32_byte_array_test) {
+  jbyte vector[256];
+  jbyte hashes[4 * 256];
+
+  for (int i = 0; i < 256; i++) {
+    vector[i] = (jbyte) i;
+  }
+
+  // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255}
+  for (int i = 0; i < 256; i++) {
+    juint hash = AltHashing::murmur3_32(256 - i, vector, i);
+    hashes[i * 4] = (jbyte) hash;
+    hashes[i * 4 + 1] = (jbyte) (hash >> 8);
+    hashes[i * 4 + 2] = (jbyte) (hash >> 16);
+    hashes[i * 4 + 3] = (jbyte) (hash >> 24);
+  }
+
+  // hash to get const result.
+  juint final_hash = AltHashing::murmur3_32(0, hashes, 4 * 256);
+
+  ASSERT_EQ(MURMUR3_32_X86_CHECK_VALUE, final_hash)
+          << "Calculated hash result not as expected.";
+}
+
+TEST_F(AltHashingTest, equivalent_hashes_test) {
+  juint jbytes, jchars, ints;
+
+  jbytes = AltHashing::murmur3_32(0, TWO_BYTE, 2);
+  jchars = AltHashing::murmur3_32(0, ONE_CHAR, 1);
+  ASSERT_EQ(jbytes, jchars) << "Hashes did not match.";
+
+  jbytes = AltHashing::murmur3_32(0, FOUR_BYTE, 4);
+  jchars = AltHashing::murmur3_32(0, TWO_CHAR, 2);
+  ints = AltHashingTest::murmur3_32(ONE_INT, 1);
+
+  ASSERT_EQ(jbytes, jchars) << "Hashes did not match.";
+  ASSERT_EQ(jbytes, ints) << "Hashes did not match.";
+
+  jbytes = AltHashing::murmur3_32(0, SIX_BYTE, 6);
+  jchars = AltHashing::murmur3_32(0, THREE_CHAR, 3);
+  ASSERT_EQ(jbytes, jchars) << "Hashes did not match.";
+
+  jbytes = AltHashing::murmur3_32(0, EIGHT_BYTE, 8);
+  jchars = AltHashing::murmur3_32(0, FOUR_CHAR, 4);
+  ints = AltHashingTest::murmur3_32(TWO_INT, 2);
+
+  ASSERT_EQ(jbytes, jchars) << "Hashes did not match.";
+  ASSERT_EQ(jbytes, ints) << "Hashes did not match.";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/gc/g1/test_g1CodeCacheRemSet.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CodeRootSetTable.hpp"
+#include "gc/g1/g1CodeCacheRemSet.hpp"
+#include "unittest.hpp"
+
+class G1CodeRootSetTest : public ::testing::Test {
+ public:
+
+  size_t threshold() {
+    return G1CodeRootSet::Threshold;
+  }
+
+  G1CodeRootSetTable* purge_list() {
+    return G1CodeRootSetTable::_purge_list;
+  }
+};
+
+TEST_VM_F(G1CodeRootSetTest, g1_code_cache_rem_set) {
+  G1CodeRootSet root_set;
+
+  ASSERT_TRUE(root_set.is_empty()) << "Code root set must be initially empty "
+          "but is not.";
+
+  ASSERT_EQ(G1CodeRootSet::static_mem_size(), sizeof (void*)) <<
+          "The code root set's static memory usage is incorrect, "
+          << G1CodeRootSet::static_mem_size() << " bytes";
+
+  root_set.add((nmethod*) 1);
+  ASSERT_EQ(root_set.length(), (size_t) 1) << "Added exactly one element, but"
+          " set contains " << root_set.length() << " elements";
+
+  const size_t num_to_add = (size_t) threshold() + 1;
+
+  for (size_t i = 1; i <= num_to_add; i++) {
+    root_set.add((nmethod*) 1);
+  }
+  ASSERT_EQ(root_set.length(), (size_t) 1)
+          << "Duplicate detection should not have increased the set size but "
+          << "is " << root_set.length();
+
+  for (size_t i = 2; i <= num_to_add; i++) {
+    root_set.add((nmethod*) (uintptr_t) (i));
+  }
+
+  ASSERT_EQ(root_set.length(), num_to_add)
+          << "After adding in total " << num_to_add << " distinct code roots, "
+          "they need to be in the set, but there are only " << root_set.length();
+
+  ASSERT_NE(purge_list(), (G1CodeRootSetTable*) NULL)
+          << "should have grown to large hashtable";
+
+  size_t num_popped = 0;
+  for (size_t i = 1; i <= num_to_add; i++) {
+    bool removed = root_set.remove((nmethod*) i);
+    if (removed) {
+      num_popped += 1;
+    } else {
+      break;
+    }
+  }
+  ASSERT_EQ(num_popped, num_to_add)
+          << "Managed to pop " << num_popped << " code roots, but only "
+          << num_to_add << " were added";
+  ASSERT_NE(purge_list(), (G1CodeRootSetTable*) NULL)
+          << "should have grown to large hashtable";
+
+  G1CodeRootSet::purge();
+
+  ASSERT_EQ(purge_list(), (G1CodeRootSetTable*) NULL)
+          << "should have purged old small tables";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/gc/g1/test_g1Predictions.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1Predictions.hpp"
+#include "unittest.hpp"
+
+static const double epsilon = 1e-6;
+
+// Some basic formula tests with confidence = 0.0
+TEST_VM(G1Predictions, basic_predictions) {
+  G1Predictions predictor(0.0);
+  TruncatedSeq s;
+
+  double p0 = predictor.get_new_prediction(&s);
+  ASSERT_LT(p0, epsilon) << "Initial prediction of empty sequence must be 0.0";
+
+  s.add(5.0);
+  double p1 = predictor.get_new_prediction(&s);
+  ASSERT_NEAR(p1, 5.0, epsilon);
+
+  for (int i = 0; i < 40; i++) {
+    s.add(5.0);
+  }
+  double p2 = predictor.get_new_prediction(&s);
+  ASSERT_NEAR(p2, 5.0, epsilon);
+}
+
+// The following tests checks that the initial predictions are based on
+// the average of the sequence and not on the stddev (which is 0).
+TEST_VM(G1Predictions, average_not_stdev_predictions) {
+  G1Predictions predictor(0.5);
+  TruncatedSeq s;
+
+  s.add(1.0);
+  double p1 = predictor.get_new_prediction(&s);
+  ASSERT_GT(p1, s.davg()) << "First prediction must be greater than average";
+
+  s.add(1.0);
+  double p2 = predictor.get_new_prediction(&s);
+  ASSERT_GT(p1, p2) << "First prediction must be greater than second";
+
+  s.add(1.0);
+  double p3 = predictor.get_new_prediction(&s);
+  ASSERT_GT(p2, p3) << "Second prediction must be greater than third";
+
+  s.add(1.0);
+  s.add(1.0); // Five elements are now in the sequence.
+  double p4 = predictor.get_new_prediction(&s);
+  ASSERT_LT(p4, p3) << "Fourth prediction must be smaller than third";
+  ASSERT_NEAR(p4, 1.0, epsilon);
+}
+
+// The following tests checks that initially prediction based on
+// the average is used, that gets overridden by the stddev prediction at
+// the end.
+TEST_VM(G1Predictions, average_stdev_predictions) {
+  G1Predictions predictor(0.5);
+  TruncatedSeq s;
+
+  s.add(0.5);
+  double p1 = predictor.get_new_prediction(&s);
+  ASSERT_GT(p1, s.davg()) << "First prediction must be greater than average";
+
+  s.add(0.2);
+  double p2 = predictor.get_new_prediction(&s);
+  ASSERT_GT(p1, p2) << "First prediction must be greater than second";
+
+  s.add(0.5);
+  double p3 = predictor.get_new_prediction(&s);
+  ASSERT_GT(p2, p3) << "Second prediction must be greater than third";
+
+  s.add(0.2);
+  s.add(2.0);
+  double p4 = predictor.get_new_prediction(&s);
+  ASSERT_GT(p4, p3) << "Fourth prediction must be greater than third";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/gc/parallel/test_psAdaptiveSizePolicy.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "utilities/macros.hpp"
+#include "gc/parallel/psAdaptiveSizePolicy.hpp"
+#include "unittest.hpp"
+
+#if INCLUDE_ALL_GCS
+
+  TEST_VM(gc, oldFreeSpaceCalculation) {
+
+    struct TestCase {
+        size_t live;
+        uintx ratio;
+        size_t expectedResult;
+    };
+
+    TestCase test_cases[] = {
+                                {100, 20, 25},
+                                {100, 50, 100},
+                                {100, 60, 150},
+                                {100, 75, 300},
+                                {400, 20, 100},
+                                {400, 50, 400},
+                                {400, 60, 600},
+                                {400, 75, 1200},
+                            };
+
+    size_t array_len = sizeof(test_cases) / sizeof(TestCase);
+    for (size_t i = 0; i < array_len; ++i) {
+      ASSERT_EQ(PSAdaptiveSizePolicy::calculate_free_based_on_live(
+          test_cases[i].live, test_cases[i].ratio),
+          test_cases[i].expectedResult)
+          << " Calculation of free memory failed"
+          << " - Test case " << i << ": live = " << test_cases[i].live
+          << "; ratio = " << test_cases[i].ratio;
+    }
+  }
+#endif
--- a/hotspot/test/native/logging/test_logConfiguration.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/native/logging/test_logConfiguration.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -164,10 +164,17 @@
   // Add TestLogFileName as an output
   set_log_config(TestLogFileName, "logging=info");
 
+  // Add a second file output
+  char other_file_name[2 * K];
+  jio_snprintf(other_file_name, sizeof(other_file_name), "%s-other", TestLogFileName);
+  set_log_config(other_file_name, "logging=info");
+
   LogConfiguration::disable_logging();
 
-  // Verify TestLogFileName was disabled
+  // Verify that both file outputs were disabled
   EXPECT_FALSE(is_described(TestLogFileName));
+  EXPECT_FALSE(is_described(other_file_name));
+  delete_file(other_file_name);
 
   // Verify that no tagset has logging enabled
   for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
@@ -287,5 +294,44 @@
     const LogDecorators::Decorator decorator = static_cast<LogDecorators::Decorator>(d);
     EXPECT_TRUE(LogConfiguration::parse_log_arguments("#0", "", LogDecorators::name(decorator), "", &ss));
   }
-  EXPECT_STREQ("", ss.as_string()) << "Error reported while parsing: " << ss.as_string();
+}
+
+TEST_F(LogConfigurationTest, parse_invalid_tagset) {
+  static const char* invalid_tagset = "logging+start+exit+safepoint+gc"; // Must not exist for test to function.
+
+  // Make sure warning is produced if one or more configured tagsets are invalid
+  ResourceMark rm;
+  stringStream ss;
+  bool success = LogConfiguration::parse_log_arguments("stdout", invalid_tagset, NULL, NULL, &ss);
+  const char* msg = ss.as_string();
+  EXPECT_TRUE(success) << "Should only cause a warning, not an error";
+  EXPECT_TRUE(string_contains_substring(msg, "No tag set matches selection(s):"));
+  EXPECT_TRUE(string_contains_substring(msg, invalid_tagset));
 }
+
+TEST_F(LogConfigurationTest, output_name_normalization) {
+  const char* patterns[] = { "%s", "file=%s", "\"%s\"", "file=\"%s\"" };
+  char buf[1 * K];
+  for (size_t i = 0; i < ARRAY_SIZE(patterns); i++) {
+    int ret = jio_snprintf(buf, sizeof(buf), patterns[i], TestLogFileName);
+    ASSERT_NE(-1, ret);
+    set_log_config(buf, "logging=trace");
+    EXPECT_TRUE(is_described("#2: "));
+    EXPECT_TRUE(is_described(TestLogFileName));
+    EXPECT_FALSE(is_described("#3: "))
+        << "duplicate file output due to incorrect normalization for pattern: " << patterns[i];
+  }
+
+  // Make sure prefixes are ignored when used within quotes
+  // (this should create a log with "file=" in its filename)
+  int ret = jio_snprintf(buf, sizeof(buf), "\"file=%s\"", TestLogFileName);
+  ASSERT_NE(-1, ret);
+  set_log_config(buf, "logging=trace");
+  EXPECT_TRUE(is_described("#3: ")) << "prefix within quotes not ignored as it should be";
+  set_log_config(buf, "all=off");
+
+  // Remove the extra log file created
+  ret = jio_snprintf(buf, sizeof(buf), "file=%s", TestLogFileName);
+  ASSERT_NE(-1, ret);
+  delete_file(buf);
+}
--- a/hotspot/test/native/logging/test_logFileOutput.cpp	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/native/logging/test_logFileOutput.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -29,7 +29,7 @@
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/ostream.hpp"
 
-static const char* name = "testlog.pid%p.%t.log";
+static const char* name = "file=testlog.pid%p.%t.log";
 
 // Test parsing a bunch of valid file output options
 TEST(LogFileOutput, parse_valid) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/utilities/test_utf8.cpp	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "utilities/utf8.hpp"
+#include "unittest.hpp"
+
+TEST(utf8, length) {
+  char res[60];
+  jchar str[20];
+
+  for (int i = 0; i < 20; i++) {
+    str[i] = 0x0800; // char that is 2B in UTF-16 but 3B in UTF-8
+  }
+  str[19] = (jchar) '\0';
+
+  // The resulting string in UTF-8 is 3*19 bytes long, but should be truncated
+  UNICODE::as_utf8(str, 19, res, 10);
+  ASSERT_EQ(strlen(res), (size_t) 9) << "string should be truncated here";
+
+  UNICODE::as_utf8(str, 19, res, 18);
+  ASSERT_EQ(strlen(res), (size_t) 15) << "string should be truncated here";
+
+  UNICODE::as_utf8(str, 19, res, 20);
+  ASSERT_EQ(strlen(res), (size_t) 18) << "string should be truncated here";
+
+  // Test with an "unbounded" buffer
+  UNICODE::as_utf8(str, 19, res, INT_MAX);
+  ASSERT_EQ(strlen(res), (size_t) 3 * 19) << "string should end here";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/RedefineTests/RedefineCount.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8164692
+ * @summary Redefine previous_versions count goes negative
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules java.compiler
+ *          java.instrument
+ *          jdk.jartool/sun.tools.jar
+ * @run main RedefineClassHelper
+ * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class+iklass+add=trace,redefine+class+iklass+purge=trace RedefineCount
+ */
+public class RedefineCount {
+
+    public static String newB =
+                "class RedefineCount$B {" +
+                "}";
+
+    static class B { }
+
+    public static void main(String[] args) throws Exception {
+
+        // Redefine a class and create some garbage
+        // Since there are no methods running, the previous version is never added to the
+        // previous_version_list and the count should stay zero and not go negative
+        RedefineClassHelper.redefineClass(B.class, newB);
+
+        for (int i = 0; i < 20 ; i++) {
+            String s = new String("some garbage");
+            System.gc();
+        }
+    }
+}
--- a/hotspot/test/runtime/modules/ModuleOptionsWarn.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/runtime/modules/ModuleOptionsWarn.java	Thu Sep 01 15:20:56 2016 -0700
@@ -29,6 +29,7 @@
  * @library /test/lib
  */
 
+import java.util.Map;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
 
@@ -37,16 +38,65 @@
 
     public static void main(String[] args) throws Exception {
 
-        // Test that a warning is issued for module related properties that get ignored.
+        // Test that a warning is not issued for extraneous jdk.module properties.
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-XX:+PrintWarnings", "-Djdk.module.ignored", "-version");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldNotContain("Ignoring system property option");
+        output.shouldHaveExitValue(0);
+
+        // Test that a warning is issued for a reserved jdk.module property.
+        pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+PrintWarnings", "-Djdk.module.addmods", "-version");
+        output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Ignoring system property option");
+        output.shouldHaveExitValue(0);
+
+        // Test that a warning is issued for a reserved jdk.module property ending in '.'.
+        pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+PrintWarnings", "-Djdk.module.limitmods.", "-version");
+        output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Ignoring system property option");
+        output.shouldHaveExitValue(0);
+
+        // Test that a warning is issued for a reserved jdk.module property ending in '='.
+        pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+PrintWarnings", "-Djdk.module.addexports=", "-version");
+        output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Ignoring system property option");
+        output.shouldHaveExitValue(0);
+
+        // Test that a warning is issued for a reserved jdk.module property ending in ".stuff"
+        pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+PrintWarnings", "-Djdk.module.addreads.stuff", "-version");
+        output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Ignoring system property option");
+        output.shouldHaveExitValue(0);
+
+        // Test that a warning is issued for a reserved jdk.module property ending in "=stuff"
+        pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+PrintWarnings", "-Djdk.module.path=stuff", "-version");
+        output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Ignoring system property option");
+        output.shouldHaveExitValue(0);
+
+        // Test that a warning is issued for a reserved jdk.module property ending in ".="
+        pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+PrintWarnings", "-Djdk.module.upgrade.path.=xx", "-version");
+        output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Ignoring system property option");
+        output.shouldHaveExitValue(0);
+
+        // Test that a warning is issued for a reserved jdk.module property ending in ".<num>"
+        pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+PrintWarnings", "-Djdk.module.patch.3=xx", "-version");
+        output = new OutputAnalyzer(pb.start());
         output.shouldContain("Ignoring system property option");
         output.shouldHaveExitValue(0);
 
         // Test that a warning can be suppressed for module related properties that get ignored.
         pb = ProcessTools.createJavaProcessBuilder(
-            "-Djdk.module.ignored", "-XX:-PrintWarnings", "-version");
+            "-Djdk.module.addmods", "-XX:-PrintWarnings", "-version");
         output = new OutputAnalyzer(pb.start());
         output.shouldNotContain("Ignoring system property option");
         output.shouldHaveExitValue(0);
@@ -57,5 +107,13 @@
         output = new OutputAnalyzer(pb.start());
         output.shouldNotContain("Ignoring system property option");
         output.shouldHaveExitValue(0);
+
+        // Test that a warning is issued for module related properties specified using _JAVA_OPTIONS.
+        pb = ProcessTools.createJavaProcessBuilder("-XX:+PrintWarnings", "-version");
+        Map<String, String> env = pb.environment();
+        env.put("_JAVA_OPTIONS", "-Djdk.module.addreads");
+        output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Ignoring system property option");
+        output.shouldHaveExitValue(0);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/AllModulesCommandTest.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.Set;
+import java.util.HashSet;
+import static jdk.test.lib.Asserts.assertTrue;
+
+/**
+ * @test
+ * @summary Tests AllModules JDWP command
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @compile AllModulesCommandTestDebuggee.java
+ * @run main/othervm AllModulesCommandTest
+ */
+public class AllModulesCommandTest implements DebuggeeLauncher.Listener {
+
+    private DebuggeeLauncher launcher;
+    private JdwpChannel channel;
+    private CountDownLatch jdwpLatch = new CountDownLatch(1);
+    private Set<String> jdwpModuleNames = new HashSet<>();
+    private Set<String> javaModuleNames = new HashSet<>();
+
+    public static void main(String[] args) throws Throwable {
+        new AllModulesCommandTest().doTest();
+    }
+
+    private void doTest() throws Throwable {
+        launcher = new DebuggeeLauncher(this);
+        launcher.launchDebuggee();
+        // Await till the debuggee sends all the necessary modules info to check against
+        // then start the JDWP session
+        jdwpLatch.await();
+        doJdwp();
+    }
+
+    @Override
+    public void onDebuggeeModuleInfo(String modName) {
+        // The debuggee has sent out info about a loaded module
+        javaModuleNames.add(modName);
+    }
+
+    @Override
+    public void onDebuggeeSendingCompleted() {
+        // The debuggee has completed sending all the info
+        // We can start the JDWP session
+        jdwpLatch.countDown();
+    }
+
+    @Override
+    public void onDebuggeeError(String message) {
+        System.err.println("Debuggee error: '" + message + "'");
+        System.exit(1);
+    }
+
+    private void doJdwp() throws Exception {
+        try {
+            // Establish JDWP socket connection
+            channel = new JdwpChannel();
+            channel.connect();
+            // Send out ALLMODULES JDWP command
+            // and verify the reply
+            JdwpAllModulesReply reply = new JdwpAllModulesCmd().send(channel);
+            assertReply(reply);
+            for (int i = 0; i < reply.getModulesCount(); ++i) {
+                long modId = reply.getModuleId(i);
+                // For each module reported by JDWP get its name using the JDWP  NAME command
+                getModuleName(modId);
+                // Assert the JDWP CANREAD and CLASSLOADER commands
+                assertCanRead(modId);
+                assertClassLoader(modId);
+            }
+
+            System.out.println("Module names reported by JDWP: " + Arrays.toString(jdwpModuleNames.toArray()));
+            System.out.println("Module names reported by Java: " + Arrays.toString(javaModuleNames.toArray()));
+
+            // Modules reported by the JDWP should be the same as reported by the Java API
+            if (!jdwpModuleNames.equals(javaModuleNames)) {
+                throw new RuntimeException("Modules info reported by Java API differs from that reported by JDWP.");
+            } else {
+                System.out.println("Test passed!");
+            }
+
+        } finally {
+            launcher.terminateDebuggee();
+            try {
+                new JdwpExitCmd(0).send(channel);
+                channel.disconnect();
+            } catch (Exception x) {
+            }
+        }
+    }
+
+    private void getModuleName(long modId) throws IOException {
+        // Send out the JDWP NAME command and store the reply
+        JdwpModNameReply reply = new JdwpModNameCmd(modId).send(channel);
+        assertReply(reply);
+        String modName = reply.getModuleName();
+        if (modName != null) { // JDWP reports unnamed modules, ignore them
+            jdwpModuleNames.add(modName);
+        }
+    }
+
+    private void assertReply(JdwpReply reply) {
+        // Simple assert for any JDWP reply
+        if (reply.getErrorCode() != 0) {
+            throw new RuntimeException("Unexpected reply error code " + reply.getErrorCode() + " for reply " + reply);
+        }
+    }
+
+    private void assertCanRead(long modId) throws IOException {
+        // Simple assert for the CANREAD command
+        JdwpCanReadReply reply = new JdwpCanReadCmd(modId, modId).send(channel);
+        assertReply(reply);
+        assertTrue(reply.canRead(), "canRead() reports false for reading from the same module");
+    }
+
+    private void assertClassLoader(long modId) throws IOException {
+        // Simple assert for the CLASSLOADER command
+        JdwpClassLoaderReply reply = new JdwpClassLoaderCmd(modId).send(channel);
+        assertReply(reply);
+        long clId = reply.getClassLoaderId();
+        assertTrue(clId >= 0, "bad classloader refId " + clId + " for module id " + modId);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/AllModulesCommandTestDebuggee.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.reflect.Module;
+import java.lang.reflect.Layer;
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * The debuggee to be launched by the test
+ * Sends out the info about the loaded modules
+ * then stays to respond to the JDWP commands
+ */
+public class AllModulesCommandTestDebuggee {
+
+    public static void main(String[] args) throws InterruptedException {
+
+        int modCount = Layer.boot().modules().size();
+
+        // Send all modules names via the process output
+        for (Module mod : Layer.boot().modules()) {
+            String info = String.format("module %s", mod.getName());
+            write(info);
+        }
+        // Signal that the sending is done
+        write("ready");
+        Thread.sleep(Long.MAX_VALUE);
+    }
+
+    private static void write(String s) {
+        System.out.println(s);
+        System.out.flush();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/DebuggeeLauncher.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.StringTokenizer;
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.Utils;
+import static jdk.test.lib.Asserts.assertFalse;
+
+/**
+ * Launches the debuggee with the necessary JDWP options and handles the output
+ */
+public class DebuggeeLauncher implements StreamHandler.Listener {
+
+    public interface Listener {
+
+        /**
+         * Callback to use when a module name is received from the debuggee
+         *
+         * @param modName module name reported by the debuggee
+         */
+        void onDebuggeeModuleInfo(String modName);
+
+        /**
+         * Callback to use when the debuggee completes sending out the info
+         */
+        void onDebuggeeSendingCompleted();
+
+        /**
+         * Callback to handle any debuggee error
+         *
+         * @param line line from the debuggee's stderr
+         */
+        void onDebuggeeError(String line);
+    }
+
+    private static int jdwpPort = -1;
+    private static final String CLS_DIR = System.getProperty("test.classes", "").trim();
+    private static final String DEBUGGEE = "AllModulesCommandTestDebuggee";
+    private Process p;
+    private final Listener listener;
+    private StreamHandler inputHandler;
+    private StreamHandler errorHandler;
+
+    /**
+     * @param listener the listener we report the debuggee events to
+     */
+    public DebuggeeLauncher(Listener listener) {
+        this.listener = listener;
+    }
+
+    /**
+     * Starts the debuggee with the necessary JDWP options and handles the
+     * debuggee's stdout and stderr outputs
+     *
+     * @throws Throwable
+     */
+    public void launchDebuggee() throws Throwable {
+
+        ProcessBuilder pb = new ProcessBuilder(getCommand());
+        p = pb.start();
+        inputHandler = new StreamHandler(p.getInputStream(), this);
+        errorHandler = new StreamHandler(p.getErrorStream(), this);
+        inputHandler.start();
+        errorHandler.start();
+    }
+
+    /**
+     * Command to start the debuggee with the JDWP options and using the JDK
+     * under test
+     *
+     * @return the command
+     */
+    private String[] getCommand() {
+        return new String[]{
+            JDKToolFinder.getTestJDKTool("java"),
+            getJdwpOptions(),
+            "-cp",
+            CLS_DIR,
+            DEBUGGEE
+        };
+    }
+
+    /**
+     * Terminates the debuggee
+     */
+    public void terminateDebuggee() {
+        if (p.isAlive()) {
+            p.destroyForcibly();
+        }
+    }
+
+    /**
+     * Debuggee JDWP options
+     *
+     * @return the JDWP options to start the debuggee with
+     */
+    private static String getJdwpOptions() {
+        return "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=" + getJdwpPort();
+    }
+
+    /**
+     * Find an available port for the JDWP session
+     *
+     * @return JDWP port
+     */
+    public static int getJdwpPort() {
+        if (jdwpPort == -1) {
+            jdwpPort = findFreePort();
+            assertFalse(jdwpPort == -1, "Can not find vailbale port for JDWP");
+        }
+        return jdwpPort;
+    }
+
+    private static int findFreePort() {
+        try (ServerSocket socket = new ServerSocket(0)) {
+            return socket.getLocalPort();
+        } catch (IOException e) {
+        }
+        return -1;
+    }
+
+    @Override
+    public void onStringRead(StreamHandler handler, String line) {
+        if (handler.equals(errorHandler)) {
+            terminateDebuggee();
+            listener.onDebuggeeError(line);
+        } else {
+            processDebuggeeOutput(line);
+        }
+    }
+
+    private void processDebuggeeOutput(String line) {
+        StringTokenizer st = new StringTokenizer(line);
+        String token = st.nextToken();
+        switch (token) {
+            case "module":
+                listener.onDebuggeeModuleInfo(st.nextToken());
+                break;
+            case "ready":
+                listener.onDebuggeeSendingCompleted();
+                break;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpAllModulesCmd.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * The JDWP ALLMODULES command
+ */
+public class JdwpAllModulesCmd extends JdwpCmd<JdwpAllModulesReply> {
+
+    public JdwpAllModulesCmd() {
+        super(22, 1, JdwpAllModulesReply.class, 0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpAllModulesReply.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * The JDWP reply to the ALLMODULES command
+ */
+public class JdwpAllModulesReply extends JdwpReply {
+
+    private int modulesCount;
+    private long[] modulesId;
+
+    protected void parseData(DataInputStream ds) throws IOException {
+        modulesCount = ds.readInt();
+        modulesId = new long[modulesCount];
+        for (int nmod = 0; nmod < modulesCount; ++nmod) {
+            modulesId[nmod] = readRefId(ds);
+        }
+    }
+
+    /**
+     * Number of modules reported
+     *
+     * @return modules count
+     */
+    public int getModulesCount() {
+        return modulesCount;
+    }
+
+    /**
+     * The id of a module reported
+     *
+     * @param ndx module index in the array of the reported ids
+     * @return module id
+     */
+    public long getModuleId(int ndx) {
+        return modulesId[ndx];
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpCanReadCmd.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * The JDWP CANREAD command
+ */
+public class JdwpCanReadCmd extends JdwpCmd<JdwpCanReadReply> {
+
+    public JdwpCanReadCmd(long modId, long srcModId) {
+        super(3, 18, JdwpCanReadReply.class, 2 * refLen());
+        putRefId(modId);
+        putRefId(srcModId);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpCanReadReply.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * The reply to the JDWP CANREAD command
+ */
+public class JdwpCanReadReply extends JdwpReply {
+
+    private boolean canRead;
+
+    protected void parseData(DataInputStream ds) throws IOException {
+        canRead = ds.read() == 1;
+    }
+
+    public boolean canRead() {
+        return canRead;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpChannel.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import java.util.Arrays;
+
+/**
+ * JDWP socket transport
+ */
+public class JdwpChannel {
+
+    private Socket sock;
+
+    public void connect() throws IOException {
+        sock = new Socket("localhost", DebuggeeLauncher.getJdwpPort());
+        handshake();
+    }
+
+    /**
+     * Sends JDWP handshake and verifies the reply
+     * @throws IOException
+     */
+    private void handshake() throws IOException {
+        final byte[] HANDSHAKE = "JDWP-Handshake".getBytes();
+        sock.getOutputStream().write(HANDSHAKE, 0, HANDSHAKE.length);
+
+        byte[] reply = new byte[14];
+        sock.getInputStream().read(reply, 0, 14);
+        if (!Arrays.equals(HANDSHAKE, reply)) {
+            throw new RuntimeException("Error during handshake. Reply was: " + new String(reply) + " expected " + new String(HANDSHAKE));
+        }
+    }
+
+    public void disconnect() {
+        try {
+            sock.close();
+        } catch (IOException x) {
+        }
+    }
+
+    public void write(byte[] data, int length) throws IOException {
+        sock.getOutputStream().write(data, 0, length);
+    }
+
+    public InputStream getInputStream() throws IOException {
+        return sock.getInputStream();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpClassLoaderCmd.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * The JDWP CLASSLOADER command
+ */
+public class JdwpClassLoaderCmd extends JdwpCmd<JdwpClassLoaderReply> {
+
+    public JdwpClassLoaderCmd(long modId) {
+        super(2, 18, JdwpClassLoaderReply.class, refLen());
+        putRefId(modId);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpClassLoaderReply.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * The JDWP CLASSLOADER reply
+ */
+public class JdwpClassLoaderReply extends JdwpReply {
+
+    private long refId;
+
+    protected void parseData(DataInputStream ds) throws IOException {
+        refId = readRefId(ds);
+    }
+
+    public long getClassLoaderId() {
+        return refId;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpCmd.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Generic JDWP command
+ * @param <T> the corresponding JDWP reply class, to construct a reply object
+ */
+public abstract class JdwpCmd<T extends JdwpReply> {
+
+    private ByteBuffer data;
+    private static int id = 1;
+    private final byte FLAGS = 0;
+    private T reply;
+    private final int dataLen;
+    private final int HEADER_LEN = 11;
+
+    /**
+     * JDWWp command
+     * @param cmd command code
+     * @param cmdSet command set
+     * @param replyClz command reply class
+     * @param dataLen length of additional data for the command
+     */
+    JdwpCmd(int cmd, int cmdSet, Class<T> replyClz, int dataLen) {
+        this.dataLen = dataLen;
+        data = ByteBuffer.allocate(HEADER_LEN + dataLen);
+        data.putInt(HEADER_LEN + dataLen);
+        data.putInt(id++);
+        data.put(FLAGS);
+        data.put((byte) cmdSet);
+        data.put((byte) cmd);
+        if (replyClz != null) {
+            try {
+                reply = replyClz.newInstance();
+            } catch (Exception ex) {
+                ex.printStackTrace();
+            }
+        }
+    }
+
+    JdwpCmd(int cmd, int cmdSet, Class<T> replyClz) {
+        this(cmd, cmdSet, replyClz, 0);
+    }
+
+    int getDataLength() {
+        return dataLen;
+    }
+
+    public final T send(JdwpChannel channel) throws IOException {
+        System.err.println("Sending command: " + this);
+        channel.write(data.array(), HEADER_LEN + getDataLength());
+        if (reply != null) {
+            reply.initFromStream(channel.getInputStream());
+        }
+        return (T) reply;
+    }
+
+    protected void putRefId(long refId) {
+        data.putLong(refId);
+    }
+
+    protected void putInt(int val) {
+        data.putInt(val);
+    }
+
+    protected static int refLen() {
+        return 8;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpExitCmd.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * The JDWP EXIT command to terminate the debuggee
+ */
+public class JdwpExitCmd extends JdwpCmd {
+
+    public JdwpExitCmd(int exitCode) {
+        super(10, 1, null, 4);
+        putInt(exitCode);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpModNameCmd.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * The JDWP NAME command
+ */
+public class JdwpModNameCmd extends JdwpCmd<JdwpModNameReply> {
+
+    public JdwpModNameCmd(long modId) {
+        super(1, 18, JdwpModNameReply.class, refLen());
+        putRefId(modId);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpModNameReply.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * JDWP reply to the NAME command
+ */
+public class JdwpModNameReply extends JdwpReply {
+
+    private byte[] name;
+
+    protected void parseData(DataInputStream ds) throws IOException {
+        name = readJdwpString(ds);
+    }
+
+    public String getModuleName() {
+        return name == null ? null : new String(name);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpReply.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Generic JDWP reply
+ */
+public abstract class JdwpReply {
+
+    protected final static int HEADER_LEN = 11;
+    private byte[] errCode = new byte[2];
+    private byte[] data;
+
+    public final void initFromStream(InputStream is) throws IOException {
+        DataInputStream ds = new DataInputStream(is);
+
+        int length = ds.readInt();
+        int id = ds.readInt();
+        byte flags = (byte) ds.read();
+
+        ds.read(errCode, 0, 2);
+
+        int dataLength = length - HEADER_LEN;
+        if (dataLength > 0) {
+            data = new byte[dataLength];
+            ds.read(data, 0, dataLength);
+            parseData(new DataInputStream(new ByteArrayInputStream(data)));
+        }
+    }
+
+    protected void parseData(DataInputStream ds) throws IOException {
+    }
+
+    protected byte[] readJdwpString(DataInputStream ds) throws IOException {
+        byte[] str = null;
+        int len = ds.readInt();
+        if (len > 0) {
+            str = new byte[len];
+            ds.read(str, 0, len);
+        }
+        return str;
+    }
+
+    protected long readRefId(DataInputStream ds) throws IOException {
+        return ds.readLong();
+    }
+
+    public int getErrorCode() {
+        return (((errCode[0] & 0xFF) << 8) | (errCode[1] & 0xFF));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/StreamHandler.java	Thu Sep 01 15:20:56 2016 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Handles the process output (either stdin or stdout)
+ * passing the lines to a listener
+ */
+public class StreamHandler implements Runnable {
+
+    public interface Listener {
+        /**
+         * Called when a line has been read from the process output stream
+         * @param handler this StreamHandler
+         * @param s the line
+         */
+        void onStringRead(StreamHandler handler, String s);
+    }
+
+    private final ExecutorService executor;
+    private final InputStream is;
+    private final Listener listener;
+
+    /**
+     * @param is input stream to read from
+     * @param listener listener to pass the read lines to
+     * @throws IOException
+     */
+    public StreamHandler(InputStream is, Listener listener) throws IOException {
+        this.is = is;
+        this.listener = listener;
+        executor = Executors.newSingleThreadExecutor();
+    }
+
+    /**
+     * Starts asynchronous reading
+     */
+    public void start() {
+        executor.submit(this);
+    }
+
+    @Override
+    public void run() {
+        try {
+            BufferedReader br = new BufferedReader(new InputStreamReader(is));
+            String line;
+            while ((line = br.readLine()) != null) {
+                listener.onStringRead(this, line);
+            }
+        } catch (Exception x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+}
--- a/hotspot/test/serviceability/sa/TestInstanceKlassSize.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/serviceability/sa/TestInstanceKlassSize.java	Thu Sep 01 15:20:56 2016 -0700
@@ -23,6 +23,7 @@
 
 import sun.jvm.hotspot.HotSpotAgent;
 import sun.jvm.hotspot.utilities.SystemDictionaryHelper;
+import sun.jvm.hotspot.oops.InstanceKlass;
 import sun.jvm.hotspot.debugger.*;
 
 import java.util.ArrayList;
@@ -44,15 +45,19 @@
  * @test
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
- * @modules jdk.hotspot.agent
- * @modules jdk.hotspot.agent/sun.jvm.hotspot
- * @modules jdk.hotspot.agent/sun.jvm.hotspot.utilities
- * @modules jdk.hotspot.agent/sun.jvm.hotspot.oops
- * @compile -XDignore.symbol.file=true -Xmodule:jdk.hotspot.agent
- *          -XaddExports:java.base/jdk.internal.misc=jdk.hotspot.agent
- *          -XaddExports:java.management/java.lang.management=jdk.hotspot.agent
+ * @compile -XDignore.symbol.file=true
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED
  *          TestInstanceKlassSize.java
- * @run main/othervm  TestInstanceKlassSize
+ * @run main/othervm
+ *          --add-modules=jdk.hotspot.agent
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED
+ *          TestInstanceKlassSize
  */
 
 public class TestInstanceKlassSize {
@@ -112,11 +117,11 @@
                                               " java.lang.Byte",
                                           };
             String[] toolArgs = {
-                "-XX:+UnlockDiagnosticVMOptions",
                 "--add-modules=jdk.hotspot.agent",
                 "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED",
                 "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED",
                 "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
+                "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED",
                 "TestInstanceKlassSize",
                 Long.toString(app.getPid())
             };
@@ -136,6 +141,8 @@
                 String jcmdInstanceKlassSize = getJcmdInstanceKlassSize(
                                                       jcmdOutput,
                                                       instanceKlassName);
+                Asserts.assertNotNull(jcmdInstanceKlassSize,
+                    "Could not get the instance klass size from the jcmd output");
                 for (String s : output.asLines()) {
                     if (s.contains(instanceKlassName)) {
                        Asserts.assertTrue(
@@ -165,10 +172,12 @@
         }
 
         for (String SAInstanceKlassName : SAInstanceKlassNames) {
-            Long size = SystemDictionaryHelper.findInstanceKlass(
-                            SAInstanceKlassName).getSize();
+            InstanceKlass ik = SystemDictionaryHelper.findInstanceKlass(
+                               SAInstanceKlassName);
+            Asserts.assertNotNull(ik,
+                String.format("Unable to find instance klass for %s", ik));
             System.out.println("SA: The size of " + SAInstanceKlassName +
-                               " is " + size);
+                               " is " + ik.getSize());
         }
         agent.detach();
     }
--- a/hotspot/test/serviceability/sa/TestInstanceKlassSizeForInterface.java	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/serviceability/sa/TestInstanceKlassSizeForInterface.java	Thu Sep 01 15:20:56 2016 -0700
@@ -38,15 +38,20 @@
  * @test
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
- * @modules jdk.hotspot.agent
- * @modules jdk.hotspot.agent/sun.jvm.hotspot
- * @modules jdk.hotspot.agent/sun.jvm.hotspot.utilities
- * @modules jdk.hotspot.agent/sun.jvm.hotspot.oops
- * @compile -XDignore.symbol.file=true -Xmodule:jdk.hotspot.agent
- *          -XaddExports:java.base/jdk.internal.misc=jdk.hotspot.agent
- *          -XaddExports:java.management/java.lang.management=jdk.hotspot.agent
+ * @compile -XDignore.symbol.file=true
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED
  *          TestInstanceKlassSizeForInterface.java
- * @run main/othervm TestInstanceKlassSizeForInterface
+ * @run main/othervm
+ *          -XX:+UnlockDiagnosticVMOptions
+ *          --add-modules=jdk.hotspot.agent
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED
+ *          --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED
+ *          TestInstanceKlassSizeForInterface
  */
 
 interface Language {
@@ -80,6 +85,8 @@
         for (String instanceKlassName : instanceKlassNames) {
             InstanceKlass iKlass = SystemDictionaryHelper.findInstanceKlass(
                                        instanceKlassName);
+            Asserts.assertNotNull(iKlass,
+                String.format("Unable to find instance klass for %s", instanceKlassName));
             System.out.println("SA: The size of " + instanceKlassName +
                                " is " + iKlass.getSize());
         }
@@ -106,11 +113,11 @@
 
         // Grab the pid from the current java process and pass it
         String[] toolArgs = {
-            "-XX:+UnlockDiagnosticVMOptions",
             "--add-modules=jdk.hotspot.agent",
             "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED",
             "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED",
             "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
+            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED",
             "TestInstanceKlassSizeForInterface",
             Long.toString(ProcessTools.getProcessId())
         };
@@ -138,6 +145,8 @@
             String jcmdInstanceKlassSize = getJcmdInstanceKlassSize(
                                                       jcmdOutput,
                                                       instanceKlassName);
+            Asserts.assertNotNull(jcmdInstanceKlassSize,
+                "Could not get the instance klass size from the jcmd output");
             for (String s : SAOutput.asLines()) {
                 if (s.contains(instanceKlassName)) {
                    Asserts.assertTrue(
@@ -162,7 +171,7 @@
             return;
         }
 
-        if ( args == null || args.length == 0 ) {
+        if (args == null || args.length == 0) {
             ParselTongue lang = new ParselTongue();
 
             Language ventro = new Language() {
--- a/hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java	Thu Sep 01 14:09:01 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import jdk.test.lib.JDKToolLauncher;
-import jdk.test.lib.process.OutputBuffer;
-import jdk.test.lib.Platform;
-import jdk.test.lib.process.ProcessTools;
-
-import java.io.File;
-
-/*
- * @test
- * @bug 8028623
- * @summary Test hashing of extended characters in Serviceability Agent.
- * @library /test/lib
- * @modules java.base/jdk.internal.misc
- *          java.compiler
- *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
- * @compile -encoding utf8 Test8028623.java
- * @run main/othervm -XX:+UsePerfData Test8028623
- */
-public class Test8028623 {
-
-  public static int \u00CB = 1;
-  public static String dumpFile = "heap.bin";
-
-  public static void main (String[] args) {
-
-    System.out.println(\u00CB);
-
-    try {
-        if (!Platform.shouldSAAttach()) {
-            System.out.println("SA attach not expected to work - test skipped.");
-            return;
-        }
-        long pid = ProcessTools.getProcessId();
-        JDKToolLauncher jmap = JDKToolLauncher.create("jhsdb")
-                                              .addToolArg("jmap")
-                                              .addToolArg("--binaryheap")
-                                              .addToolArg("--pid")
-                                              .addToolArg(Long.toString(pid));
-        ProcessBuilder pb = new ProcessBuilder(jmap.getCommand());
-        OutputBuffer output = ProcessTools.getOutput(pb);
-        Process p = pb.start();
-        int e = p.waitFor();
-        System.out.println("stdout:");
-        System.out.println(output.getStdout());
-        System.out.println("stderr:");
-        System.out.println(output.getStderr());
-
-        if (e != 0) {
-            throw new RuntimeException("jmap returns: " + e);
-        }
-        if (! new File(dumpFile).exists()) {
-            throw new RuntimeException("dump file NOT created: '" + dumpFile + "'");
-        }
-    } catch (Throwable t) {
-        t.printStackTrace();
-        throw new RuntimeException("Test failed with: " + t);
-    }
-  }
-}
--- a/hotspot/test/testlibrary/jittester/Makefile	Thu Sep 01 14:09:01 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/Makefile	Thu Sep 01 15:20:56 2016 -0700
@@ -70,17 +70,17 @@
 DIST_JAR = $(DIST_DIR)/JITtester.jar
 
 SRC_FILES = $(shell find $(SRC_DIR) -name '*.java')
-TESTLIBRARY_SRC_DIR = ../jdk/test/lib
+TESTLIBRARY_SRC_DIR = ../../../../test/lib/jdk/test/lib
 TESTLIBRARY_SRC_FILES = $(TESTLIBRARY_SRC_DIR)/Asserts.java \
                         $(TESTLIBRARY_SRC_DIR)/JDKToolFinder.java \
                         $(TESTLIBRARY_SRC_DIR)/JDKToolLauncher.java \
-                        $(TESTLIBRARY_SRC_DIR)/OutputAnalyzer.java \
-                        $(TESTLIBRARY_SRC_DIR)/OutputBuffer.java \
-                        $(TESTLIBRARY_SRC_DIR)/Pair.java \
                         $(TESTLIBRARY_SRC_DIR)/Platform.java \
-                        $(TESTLIBRARY_SRC_DIR)/ProcessTools.java \
-                        $(TESTLIBRARY_SRC_DIR)/StreamPumper.java \
-                        $(TESTLIBRARY_SRC_DIR)/Utils.java
+                        $(TESTLIBRARY_SRC_DIR)/Utils.java \
+                        $(TESTLIBRARY_SRC_DIR)/process/OutputAnalyzer.java \
+                        $(TESTLIBRARY_SRC_DIR)/process/OutputBuffer.java \
+                        $(TESTLIBRARY_SRC_DIR)/process/ProcessTools.java \
+                        $(TESTLIBRARY_SRC_DIR)/process/StreamPumper.java \
+                        $(TESTLIBRARY_SRC_DIR)/util/Pair.java
 
 .PHONY: cleantmp
 
@@ -120,7 +120,6 @@
 
 copytestlibrary: $(DRIVER_DIR)
 	@cp -r src/jdk/test/lib/jittester/jtreg/*.java $(DRIVER_DIR)
-	@cp -r ../jdk $(TESTBASE_DIR)/
 
 testgroup: $(TESTBASE_DIR)
 	@echo 'jittester_all = \\' > $(TESTGROUP_FILE)