--- a/jdk/make/mapfiles/libjava/mapfile-vers Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/make/mapfiles/libjava/mapfile-vers Sat Sep 10 12:18:34 2016 -0700
@@ -176,6 +176,9 @@
Java_java_lang_ProcessHandleImpl_00024Info_info0;
Java_java_lang_ProcessImpl_init;
Java_java_lang_ProcessImpl_forkAndExec;
+ Java_java_lang_ref_Reference_getAndClearReferencePendingList;
+ Java_java_lang_ref_Reference_hasReferencePendingList;
+ Java_java_lang_ref_Reference_waitForReferencePendingList;
Java_java_lang_reflect_Array_get;
Java_java_lang_reflect_Array_getBoolean;
Java_java_lang_reflect_Array_getByte;
--- a/jdk/src/java.base/share/classes/java/lang/ref/Reference.java Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/ref/Reference.java Sat Sep 10 12:18:34 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
@@ -110,22 +110,6 @@
private transient Reference<T> discovered; /* used by VM */
- /* Object used to synchronize with the garbage collector. The collector
- * must acquire this lock at the beginning of each collection cycle. It is
- * therefore critical that any code holding this lock complete as quickly
- * as possible, allocate no new objects, and avoid calling user code.
- */
- private static class Lock { }
- private static Lock lock = new Lock();
-
-
- /* List of References waiting to be enqueued. The collector adds
- * References to this list, while the Reference-handler thread removes
- * them. This list is protected by the above lock object. The
- * list uses the discovered field to link its elements.
- */
- private static Reference<Object> pending = null;
-
/* High-priority thread to enqueue pending References
*/
private static class ReferenceHandler extends Thread {
@@ -139,10 +123,9 @@
}
static {
- // pre-load and initialize InterruptedException and Cleaner classes
- // so that we don't get into trouble later in the run loop if there's
- // memory shortage while loading/initializing them lazily.
- ensureClassInitialized(InterruptedException.class);
+ // pre-load and initialize Cleaner class so that we don't
+ // get into trouble later in the run loop if there's
+ // memory shortage while loading/initializing it lazily.
ensureClassInitialized(Cleaner.class);
}
@@ -152,72 +135,80 @@
public void run() {
while (true) {
- tryHandlePending(true);
+ processPendingReferences();
}
}
}
- /**
- * Try handle pending {@link Reference} if there is one.<p>
- * Return {@code true} as a hint that there might be another
- * {@link Reference} pending or {@code false} when there are no more pending
- * {@link Reference}s at the moment and the program can do some other
- * useful work instead of looping.
- *
- * @param waitForNotify if {@code true} and there was no pending
- * {@link Reference}, wait until notified from VM
- * or interrupted; if {@code false}, return immediately
- * when there is no pending {@link Reference}.
- * @return {@code true} if there was a {@link Reference} pending and it
- * was processed, or we waited for notification and either got it
- * or thread was interrupted before being notified;
- * {@code false} otherwise.
+ /* Atomically get and clear (set to null) the VM's pending list.
+ */
+ private static native Reference<Object> getAndClearReferencePendingList();
+
+ /* Test whether the VM's pending list contains any entries.
+ */
+ private static native boolean hasReferencePendingList();
+
+ /* Wait until the VM's pending list may be non-null.
*/
- static boolean tryHandlePending(boolean waitForNotify) {
- Reference<Object> r;
- Cleaner c;
- try {
- synchronized (lock) {
- if (pending != null) {
- r = pending;
- // 'instanceof' might throw OutOfMemoryError sometimes
- // so do this before un-linking 'r' from the 'pending' chain...
- c = r instanceof Cleaner ? (Cleaner) r : null;
- // unlink 'r' from 'pending' chain
- pending = r.discovered;
- r.discovered = null;
- } else {
- // The waiting on the lock may cause an OutOfMemoryError
- // because it may try to allocate exception objects.
- if (waitForNotify) {
- lock.wait();
- }
- // retry if waited
- return waitForNotify;
+ private static native void waitForReferencePendingList();
+
+ private static final Object processPendingLock = new Object();
+ private static boolean processPendingActive = false;
+
+ private static void processPendingReferences() {
+ // Only the singleton reference processing thread calls
+ // waitForReferencePendingList() and getAndClearReferencePendingList().
+ // These are separate operations to avoid a race with other threads
+ // that are calling waitForReferenceProcessing().
+ waitForReferencePendingList();
+ Reference<Object> pendingList;
+ synchronized (processPendingLock) {
+ pendingList = getAndClearReferencePendingList();
+ processPendingActive = true;
+ }
+ while (pendingList != null) {
+ Reference<Object> ref = pendingList;
+ pendingList = ref.discovered;
+ ref.discovered = null;
+
+ if (ref instanceof Cleaner) {
+ ((Cleaner)ref).clean();
+ // Notify any waiters that progress has been made.
+ // This improves latency for nio.Bits waiters, which
+ // are the only important ones.
+ synchronized (processPendingLock) {
+ processPendingLock.notifyAll();
}
+ } else {
+ ReferenceQueue<? super Object> q = ref.queue;
+ if (q != ReferenceQueue.NULL) q.enqueue(ref);
}
- } catch (OutOfMemoryError x) {
- // Give other threads CPU time so they hopefully drop some live references
- // and GC reclaims some space.
- // Also prevent CPU intensive spinning in case 'r instanceof Cleaner' above
- // persistently throws OOME for some time...
- Thread.yield();
- // retry
- return true;
- } catch (InterruptedException x) {
- // retry
- return true;
+ }
+ // Notify any waiters of completion of current round.
+ synchronized (processPendingLock) {
+ processPendingActive = false;
+ processPendingLock.notifyAll();
}
+ }
- // Fast path for cleaners
- if (c != null) {
- c.clean();
- return true;
+ // Wait for progress in reference processing.
+ //
+ // Returns true after waiting (for notification from the reference
+ // processing thread) if either (1) the VM has any pending
+ // references, or (2) the reference processing thread is
+ // processing references. Otherwise, returns false immediately.
+ private static boolean waitForReferenceProcessing()
+ throws InterruptedException
+ {
+ synchronized (processPendingLock) {
+ if (processPendingActive || hasReferencePendingList()) {
+ // Wait for progress, not necessarily completion.
+ processPendingLock.wait();
+ return true;
+ } else {
+ return false;
+ }
}
-
- ReferenceQueue<? super Object> q = r.queue;
- if (q != ReferenceQueue.NULL) q.enqueue(r);
- return true;
}
static {
@@ -236,8 +227,10 @@
// provide access in SharedSecrets
SharedSecrets.setJavaLangRefAccess(new JavaLangRefAccess() {
@Override
- public boolean tryHandlePendingReference() {
- return tryHandlePending(false);
+ public boolean waitForReferenceProcessing()
+ throws InterruptedException
+ {
+ return Reference.waitForReferenceProcessing();
}
});
}
--- a/jdk/src/java.base/share/classes/java/nio/Bits.java Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/src/java.base/share/classes/java/nio/Bits.java Sat Sep 10 12:18:34 2016 -0700
@@ -131,23 +131,38 @@
}
final JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess();
-
- // retry while helping enqueue pending Reference objects
- // which includes executing pending Cleaner(s) which includes
- // Cleaner(s) that free direct buffer memory
- while (jlra.tryHandlePendingReference()) {
- if (tryReserveMemory(size, cap)) {
- return;
- }
- }
-
- // trigger VM's Reference processing
- System.gc();
-
- // a retry loop with exponential back-off delays
- // (this gives VM some time to do it's job)
boolean interrupted = false;
try {
+
+ // Retry allocation until success or there are no more
+ // references (including Cleaners that might free direct
+ // buffer memory) to process and allocation still fails.
+ boolean refprocActive;
+ do {
+ try {
+ refprocActive = jlra.waitForReferenceProcessing();
+ } catch (InterruptedException e) {
+ // Defer interrupts and keep trying.
+ interrupted = true;
+ refprocActive = true;
+ }
+ if (tryReserveMemory(size, cap)) {
+ return;
+ }
+ } while (refprocActive);
+
+ // trigger VM's Reference processing
+ System.gc();
+
+ // A retry loop with exponential back-off delays.
+ // Sometimes it would suffice to give up once reference
+ // processing is complete. But if there are many threads
+ // competing for memory, this gives more opportunities for
+ // any given thread to make progress. In particular, this
+ // seems to be enough for a stress test like
+ // DirectBufferAllocTest to (usually) succeed, while
+ // without it that test likely fails. Since failure here
+ // ends in OOME, there's no need to hurry.
long sleepTime = 1;
int sleeps = 0;
while (true) {
@@ -157,14 +172,14 @@
if (sleeps >= MAX_SLEEPS) {
break;
}
- if (!jlra.tryHandlePendingReference()) {
- try {
+ try {
+ if (!jlra.waitForReferenceProcessing()) {
Thread.sleep(sleepTime);
sleepTime <<= 1;
sleeps++;
- } catch (InterruptedException e) {
- interrupted = true;
}
+ } catch (InterruptedException e) {
+ interrupted = true;
}
}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangRefAccess.java Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangRefAccess.java Sat Sep 10 12:18:34 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 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,12 +28,12 @@
public interface JavaLangRefAccess {
/**
- * Help ReferenceHandler thread process next pending
- * {@link java.lang.ref.Reference}
+ * Wait for progress in {@link java.lang.ref.Reference}
+ * processing. If there aren't any pending {@link
+ * java.lang.ref.Reference}s, return immediately.
*
- * @return {@code true} if there was a pending reference and it
- * was enqueue-ed or {@code false} if there was no
- * pending reference
+ * @return {@code true} if there were any pending
+ * {@link java.lang.ref.Reference}s, {@code false} otherwise.
*/
- boolean tryHandlePendingReference();
+ boolean waitForReferenceProcessing() throws InterruptedException;
}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Sat Sep 10 12:18:34 2016 -0700
@@ -1197,6 +1197,9 @@
if (hostClass == null || data == null) {
throw new NullPointerException();
}
+ if (hostClass.isArray() || hostClass.isPrimitive()) {
+ throw new IllegalArgumentException();
+ }
return defineAnonymousClass0(hostClass, data, cpPatches);
}
--- a/jdk/src/java.base/share/native/include/jvm.h Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/src/java.base/share/native/include/jvm.h Sat Sep 10 12:18:34 2016 -0700
@@ -282,6 +282,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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libjava/Reference.c Sat Sep 10 12:18:34 2016 -0700
@@ -0,0 +1,45 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 "jvm.h"
+#include "java_lang_ref_Reference.h"
+
+JNIEXPORT jobject JNICALL
+Java_java_lang_ref_Reference_getAndClearReferencePendingList(JNIEnv *env, jclass ignore)
+{
+ return JVM_GetAndClearReferencePendingList(env);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_java_lang_ref_Reference_hasReferencePendingList(JNIEnv *env, jclass ignore)
+{
+ return JVM_HasReferencePendingList(env);
+}
+
+JNIEXPORT void JNICALL
+Java_java_lang_ref_Reference_waitForReferencePendingList(JNIEnv *env, jclass ignore)
+{
+ JVM_WaitForReferencePendingList(env);
+}
--- a/jdk/src/java.management/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/src/java.management/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java Sat Sep 10 12:18:34 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -1707,25 +1707,6 @@
throw new UnsupportedOperationException("Not supported yet.");
}
- @SuppressWarnings("deprecation")
- public ObjectInputStream deserialize(ObjectName name, byte[] data) throws InstanceNotFoundException,
- OperationsException {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @SuppressWarnings("deprecation")
- public ObjectInputStream deserialize(String className, byte[] data) throws OperationsException,
- ReflectionException {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @SuppressWarnings("deprecation")
- public ObjectInputStream deserialize(String className, ObjectName loaderName,
- byte[] data) throws InstanceNotFoundException, OperationsException,
- ReflectionException {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
public ClassLoaderRepository getClassLoaderRepository() {
throw new UnsupportedOperationException("Not supported yet.");
}
--- a/jdk/src/java.management/share/classes/com/sun/jmx/interceptor/MBeanServerInterceptor.java Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/src/java.management/share/classes/com/sun/jmx/interceptor/MBeanServerInterceptor.java Sat Sep 10 12:18:34 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2008, 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
@@ -98,32 +98,6 @@
* This method should never be called.
* Usually throws UnsupportedOperationException.
*/
- @Deprecated
- public ObjectInputStream deserialize(ObjectName name, byte[] data)
- throws InstanceNotFoundException, OperationsException;
-
- /**
- * This method should never be called.
- * Usually throws UnsupportedOperationException.
- */
- @Deprecated
- public ObjectInputStream deserialize(String className, byte[] data)
- throws OperationsException, ReflectionException;
-
- /**
- * This method should never be called.
- * Usually hrows UnsupportedOperationException.
- */
- @Deprecated
- public ObjectInputStream deserialize(String className,
- ObjectName loaderName, byte[] data)
- throws InstanceNotFoundException, OperationsException,
- ReflectionException;
-
- /**
- * This method should never be called.
- * Usually throws UnsupportedOperationException.
- */
public ClassLoaderRepository getClassLoaderRepository();
}
--- a/jdk/src/java.management/share/classes/javax/management/MBeanServer.java Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/src/java.management/share/classes/javax/management/MBeanServer.java Sat Sep 10 12:18:34 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -655,6 +655,8 @@
* used for the de-serialization.
* @param data The byte array to be de-sererialized.
*
+ * @implSpec This method throws {@link UnsupportedOperationException} by default.
+ *
* @return The de-serialized object stream.
*
* @exception InstanceNotFoundException The MBean specified is not
@@ -665,10 +667,11 @@
* @deprecated Use {@link #getClassLoaderFor getClassLoaderFor} to
* obtain the appropriate class loader for deserialization.
*/
- @Deprecated
- public ObjectInputStream deserialize(ObjectName name, byte[] data)
- throws InstanceNotFoundException, OperationsException;
-
+ @Deprecated(since="1.5")
+ default public ObjectInputStream deserialize(ObjectName name, byte[] data)
+ throws InstanceNotFoundException, OperationsException {
+ throw new UnsupportedOperationException("Not supported.");
+ }
/**
* <p>De-serializes a byte array in the context of a given MBean
@@ -682,6 +685,8 @@
* used for the de-serialization.
* @param data The byte array to be de-sererialized.
*
+ * @implSpec This method throws {@link UnsupportedOperationException} by default.
+ *
* @return The de-serialized object stream.
*
* @exception OperationsException Any of the usual Input/Output
@@ -692,9 +697,11 @@
* @deprecated Use {@link #getClassLoaderRepository} to obtain the
* class loader repository and use it to deserialize.
*/
- @Deprecated
- public ObjectInputStream deserialize(String className, byte[] data)
- throws OperationsException, ReflectionException;
+ @Deprecated(since="1.5")
+ default public ObjectInputStream deserialize(String className, byte[] data)
+ throws OperationsException, ReflectionException {
+ throw new UnsupportedOperationException("Not supported.");
+ }
/**
@@ -711,6 +718,8 @@
* loading the specified class. If null, the MBean Server's class
* loader will be used.
*
+ * @implSpec This method throws {@link UnsupportedOperationException} by default.
+ *
* @return The de-serialized object stream.
*
* @exception InstanceNotFoundException The specified class loader
@@ -723,12 +732,14 @@
* @deprecated Use {@link #getClassLoader getClassLoader} to obtain
* the class loader for deserialization.
*/
- @Deprecated
- public ObjectInputStream deserialize(String className,
+ @Deprecated(since="1.5")
+ default public ObjectInputStream deserialize(String className,
ObjectName loaderName,
byte[] data)
throws InstanceNotFoundException, OperationsException,
- ReflectionException;
+ ReflectionException {
+ throw new UnsupportedOperationException("Not supported.");
+ }
/**
* <p>Return the {@link java.lang.ClassLoader} that was used for
--- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java Sat Sep 10 12:18:34 2016 -0700
@@ -993,32 +993,39 @@
return minorVersion;
}
- private void getConstantPoolInfo() {
+ private byte[] getConstantPoolInfo() {
JDWP.ReferenceType.ConstantPool jdwpCPool;
if (!vm.canGetConstantPool()) {
throw new UnsupportedOperationException();
}
if (constantPoolInfoGotten) {
- return;
- } else {
- try {
- jdwpCPool = JDWP.ReferenceType.ConstantPool.process(vm, this);
- } catch (JDWPException exc) {
- if (exc.errorCode() == JDWP.Error.ABSENT_INFORMATION) {
- constanPoolCount = 0;
- constantPoolBytesRef = null;
- constantPoolInfoGotten = true;
- return;
- } else {
- throw exc.toJDIException();
- }
+ if (constantPoolBytesRef == null) {
+ return null;
+ }
+ byte[] cpbytes = constantPoolBytesRef.get();
+ if (cpbytes != null) {
+ return cpbytes;
}
- byte[] cpbytes;
- constanPoolCount = jdwpCPool.count;
- cpbytes = jdwpCPool.bytes;
- constantPoolBytesRef = new SoftReference<byte[]>(cpbytes);
- constantPoolInfoGotten = true;
}
+
+ try {
+ jdwpCPool = JDWP.ReferenceType.ConstantPool.process(vm, this);
+ } catch (JDWPException exc) {
+ if (exc.errorCode() == JDWP.Error.ABSENT_INFORMATION) {
+ constanPoolCount = 0;
+ constantPoolBytesRef = null;
+ constantPoolInfoGotten = true;
+ return null;
+ } else {
+ throw exc.toJDIException();
+ }
+ }
+ byte[] cpbytes;
+ constanPoolCount = jdwpCPool.count;
+ cpbytes = jdwpCPool.bytes;
+ constantPoolBytesRef = new SoftReference<byte[]>(cpbytes);
+ constantPoolInfoGotten = true;
+ return cpbytes;
}
public int constantPoolCount() {
@@ -1031,13 +1038,13 @@
}
public byte[] constantPool() {
+ byte[] cpbytes;
try {
- getConstantPoolInfo();
+ cpbytes = getConstantPoolInfo();
} catch (RuntimeException exc) {
throw exc;
}
- if (constantPoolBytesRef != null) {
- byte[] cpbytes = constantPoolBytesRef.get();
+ if (cpbytes != null) {
/*
* Arrays are always modifiable, so it is a little unsafe
* to return the cached bytecodes directly; instead, we
--- a/jdk/test/ProblemList.txt Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/test/ProblemList.txt Sat Sep 10 12:18:34 2016 -0700
@@ -328,9 +328,6 @@
com/sun/jdi/sde/SourceDebugExtensionTest.java 8158066 windows-all
-com/sun/jdi/ClassesByName2Test.java 8160833 generic-all
-com/sun/jdi/RedefineCrossEvent.java 8160833 generic-all
-
############################################################################
# jdk_time
@@ -357,9 +354,11 @@
sun/tools/jhsdb/BasicLauncherTest.java 8160376 macosx-all
+sun/tools/jhsdb/HeapDumpTest.java 8160376 macosx-all
+
sun/tools/jhsdb/heapconfig/JMapHeapConfigTest.java 8160376 macosx-all
-sun/tools/jps/TestJpsJar.java 8160923 generic-all
+sun/tools/jps/TestJpsJar.java 8165500 generic-all
sun/tools/jps/TestJpsJarRelative.java 6456333 generic-all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/jdi/ConstantPoolInfoGC.java Sat Sep 10 12:18:34 2016 -0700
@@ -0,0 +1,104 @@
+/*
+ * 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 6822627
+ * @summary Test that ReferenceType.constantPool does not produce an NPE
+ *
+ * @author Egor Ushakov
+ *
+ * @modules jdk.jdi/com.sun.tools.jdi
+ * @run build TestScaffold VMConnection
+ * @run compile -g ConstantPoolInfoGC.java
+ * @run main/othervm ConstantPoolInfoGC
+ */
+
+import com.sun.jdi.ReferenceType;
+import com.sun.tools.jdi.ReferenceTypeImpl;
+
+import java.lang.ref.Reference;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+
+ /********** target program **********/
+
+class ConstantPoolGCTarg {
+ public static void main(String[] args){
+ System.out.println("Anything");
+ }
+}
+
+ /********** test program **********/
+
+public class ConstantPoolInfoGC extends TestScaffold {
+ ReferenceType targetClass;
+
+ ConstantPoolInfoGC(String args[]) {
+ super(args);
+ }
+
+ public static void main(String[] args) throws Exception {
+ new ConstantPoolInfoGC(args).startTests();
+ }
+
+ /********** test core **********/
+
+ protected void runTests() throws Exception {
+ targetClass = startToMain("ConstantPoolGCTarg").location().declaringType();
+
+ if (vm().canGetConstantPool()) {
+ byte[] cpbytes = targetClass.constantPool();
+
+ // imitate SoftReference cleared
+ Field constantPoolBytesRef = ReferenceTypeImpl.class.getDeclaredField("constantPoolBytesRef");
+ constantPoolBytesRef.setAccessible(true);
+ Reference softRef = (Reference) constantPoolBytesRef.get(targetClass);
+ softRef.clear();
+
+ byte[] cpbytes2 = targetClass.constantPool();
+ if (!Arrays.equals(cpbytes, cpbytes2)) {
+ failure("Consequent constantPool results vary, first was : " + cpbytes + ", now: " + cpbytes2);
+ };
+
+ } else {
+ System.out.println("can get constant pool version not supported");
+ }
+
+
+ /*
+ * resume until end
+ */
+ listenUntilVMDisconnect();
+
+ /*
+ * deal with results of test
+ * if anything has called failure("foo") testFailed will be true
+ */
+ if (!testFailed) {
+ println("ConstantPoolInfoGC: passed");
+ } else {
+ throw new Exception("ConstantPoolInfoGC: failed");
+ }
+ }
+}
--- a/jdk/test/java/lang/Class/GetModuleTest.java Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/test/java/lang/Class/GetModuleTest.java Sat Sep 10 12:18:34 2016 -0700
@@ -101,11 +101,8 @@
return new Object[][] {
{ GetModuleTest.class, null },
- { GetModuleTest[].class, null },
{ Object.class, null },
- { Object[].class, null },
{ Component.class, null },
- { Component[].class, null },
};
}
@@ -117,7 +114,7 @@
public void testGetModuleOnVMAnonymousClass(Class<?> hostClass, String ignore) {
// choose a class name in the same package as the host class
- String prefix = packageName(hostClass);
+ String prefix = hostClass.getPackageName();
if (prefix.length() > 0)
prefix = prefix.replace('.', '/') + "/";
String className = prefix + "Anon";
@@ -136,17 +133,6 @@
assertTrue(anonClass.getModule() == hostClass.getModule());
}
- private static String packageName(Class<?> c) {
- if (c.isArray()) {
- return packageName(c.getComponentType());
- } else {
- String name = c.getName();
- int dot = name.lastIndexOf('.');
- if (dot == -1) return "";
- return name.substring(0, dot);
- }
- }
-
private static int constantPoolSize(byte[] classFile) {
return ((classFile[8] & 0xFF) << 8) | (classFile[9] & 0xFF);
}
--- a/jdk/test/java/lang/invoke/VMAnonymousClass.java Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/test/java/lang/invoke/VMAnonymousClass.java Sat Sep 10 12:18:34 2016 -0700
@@ -57,9 +57,9 @@
@Test public void testJavaLangInvoke() throws Throwable { test("java/lang/invoke"); }
@Test public void testProhibitedJavaPkg() throws Throwable {
try {
- test("java/prohibited");
- } catch (SecurityException e) {
- return;
+ test("java/prohibited");
+ } catch (IllegalArgumentException e) {
+ return;
}
throw new RuntimeException("Expected SecurityException");
}
@@ -72,10 +72,17 @@
if (pkg.equals("java/prohibited")) {
VMAnonymousClass sampleclass = new VMAnonymousClass();
host_class = (Class)sampleclass.getClass();
+ } else if (pkg.equals("java/lang")) {
+ host_class = Object.class;
+ } else if (pkg.equals("java/util")) {
+ host_class = java.util.ArrayList.class;
+ } else if (pkg.equals("jdk/internal/misc")) {
+ host_class = jdk.internal.misc.Signal.class;
+ } else if (pkg.equals("java/lang/invoke")) {
+ host_class = java.lang.invoke.CallSite.class;
} else {
- host_class = Object.class;
+ throw new RuntimeException("Unexpected pkg: " + pkg);
}
-
// Define VM anonymous class
Class anonClass = unsafe.defineAnonymousClass(host_class, bytes, null);
--- a/jdk/test/java/lang/management/ThreadMXBean/Locks.java Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/test/java/lang/management/ThreadMXBean/Locks.java Sat Sep 10 12:18:34 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -26,27 +26,28 @@
* @bug 4530538
* @summary Basic unit test of ThreadInfo.getLockName()
* and ThreadInfo.getLockOwnerName()
+ * @library /lib/testlibrary
* @author Mandy Chung
* @author Jaroslav Bachorik
*
- * @library /lib/testlibrary
* @modules java.management
* @build jdk.testlibrary.*
* @run main/othervm Locks
*/
-
import java.lang.management.*;
+import java.util.Arrays;
+import java.util.Optional;
import java.util.concurrent.Phaser;
+import java.util.function.Predicate;
import jdk.testlibrary.LockFreeLogManager;
public class Locks {
- private static final Object objA = new Object();
- private static final Object objB = new Object();
- private static final Object objC = new Object();
- private static final ThreadMXBean tm = ManagementFactory.getThreadMXBean();
- private static final LockFreeLogManager logger = new LockFreeLogManager();
- private static boolean testFailed = false;
+ private static final Object OBJA = new Object();
+ private static final Object OBJB = new Object();
+ private static final EnhancedWaiter OBJC = new EnhancedWaiter();
+ private static final ThreadMXBean TM = ManagementFactory.getThreadMXBean();
+ private static final LockFreeLogManager LOGGER = new LockFreeLogManager();
private static String getLockName(Object lock) {
if (lock == null) return null;
@@ -56,67 +57,103 @@
}
private static void assertNoLock(Thread t) {
- long tid = t.getId();
- ThreadInfo info = tm.getThreadInfo(tid);
- String result = info.getLockName();
+ if (t == null) {
+ return;
+ }
+ Optional<ThreadInfo> result = Arrays.asList(
+ TM.getThreadInfo(TM.getAllThreadIds(), true, true)).
+ stream().
+ filter(tInfo -> (tInfo != null && tInfo.getLockOwnerName() != null)
+ ? tInfo.getLockOwnerName().equals(t.getName()) : false).
+ findAny();
+ if (result.isPresent()) {
+ throw new RuntimeException("Thread " + t.getName() + " is not "
+ + "supposed to be hold any lock. Currently owning lock : "
+ + result.get().getLockName());
+ }
+ }
- if (result != null) {
- throw new RuntimeException("Thread " + t.getName() + " is not supposed to hold any lock. " +
- "Currently owning lock: " + result);
+ /*
+ * Handy debug function to check if error condition is because of test code or not.
+ */
+ private static void printStackTrace(Thread thread) {
+ if (thread == null) {
+ return;
+ }
+ StackTraceElement[] stackTrace = thread.getStackTrace();
+ log("Stack dump : Thread -> " + thread.getName());
+ for (StackTraceElement stackTraceEl : stackTrace) {
+ log("\t" + stackTraceEl.toString());
}
}
- private static void checkBlockedObject(Thread t, Object lock, Thread owner,
- Thread.State expectedState) {
+ private static void assertThreadState(Thread t, Thread.State expectedState) {
long tid = t.getId();
- ThreadInfo info = tm.getThreadInfo(tid);
- String result = info.getLockName();
- String expectedLock = (lock != null ? getLockName(lock) : null);
- String expectedOwner = (owner != null ? owner.getName() : null);
+ if (expectedState == Thread.State.BLOCKED
+ && TM.getThreadInfo(tid).getThreadState() != Thread.State.BLOCKED) {
+ int retryCount = 0;
+ printStackTrace(t);
+ while (TM.getThreadInfo(tid).getThreadState() != Thread.State.BLOCKED) {
+ if (retryCount++ > 500) {
+ printStackTrace(t);
+ throw new RuntimeException("Thread " + t.getName() + " is at "
+ + TM.getThreadInfo(tid).getThreadState() + " state but is expected to "
+ + "be in Thread.State = " + expectedState);
+ }
+ goSleep(100);
+ }
+ }
+ if (!TM.getThreadInfo(tid).getThreadState().equals(expectedState)) {
+ printStackTrace(t);
+ throw new RuntimeException("Thread " + t.getName() + " is at "
+ + TM.getThreadInfo(tid).getThreadState() + " state but is expected to "
+ + "be in Thread.State = " + expectedState);
+ }
+ }
- if (lock != null) {
- if (expectedState == Thread.State.BLOCKED) {
- int retryCount=0;
- while(info.getThreadState() != Thread.State.BLOCKED) {
- if (retryCount++ > 500) {
- throw new RuntimeException("Thread " + t.getName() +
- " is expected to block on " + expectedLock +
- " but got " + result +
- " Thread.State = " + info.getThreadState());
- }
- goSleep(100);
- info = tm.getThreadInfo(tid);
- result = info.getLockName();
+ /*
+ * Do slow check if thread is blocked on a lock. It is possible that last thread
+ * to come out of Phaser might still be in Phaser call stack (Unsafe.park) and
+ * hence might eventually acquire expected lock.
+ */
+ private static void checkBlockedObject(Thread t, Object lock, Thread owner) {
+ long tid = t.getId();
+ String result = TM.getThreadInfo(tid).getLockName();
+ final String expectedLock = (lock != null ? getLockName(lock) : null);
+ Predicate<String> p = (res) -> ((res != null && !res.equals(expectedLock))
+ || (res == null && expectedLock != null));
+
+ if (p.test(result)) {
+ printStackTrace(t);
+ int retryCount = 0;
+ while (p.test(result)) {
+ if (retryCount++ > 500) {
+ printStackTrace(t);
+ throw new RuntimeException("Thread " + t.getName() + " is blocked on "
+ + expectedLock + " but got " + result);
}
- }
- if (expectedState == Thread.State.WAITING &&
- info.getThreadState() != Thread.State.WAITING) {
- throw new RuntimeException("Thread " + t.getName() +
- " is expected to wait on " + expectedLock +
- " but got " + result +
- " Thread.State = " + info.getThreadState());
+ goSleep(100);
+ result = TM.getThreadInfo(tid).getLockName();
}
}
- if ((result != null && !result.equals(expectedLock)) ||
- (result == null && expectedLock != null)) {
- throw new RuntimeException("Thread " + t.getName() + " is blocked on " +
- expectedLock + " but got " + result);
- }
- result = info.getLockOwnerName();
- if ((result != null && !result.equals(expectedOwner)) ||
- (result == null && expectedOwner != null)) {
- throw new RuntimeException("Owner of " + lock + " should be " +
- expectedOwner + " but got " + result);
+ result = TM.getThreadInfo(tid).getLockOwnerName();
+ final String expectedOwner = (owner != null ? owner.getName() : null);
+
+ p = (res) -> ((res != null && !res.equals(expectedOwner))
+ || (res == null && expectedOwner != null));
+ if (p.test(result)) {
+ printStackTrace(t);
+ throw new RuntimeException("Owner of " + lock + " should be "
+ + expectedOwner + " but got " + result);
}
}
- private static void goSleep(long ms) {
+ private static void goSleep(long ms){
try {
Thread.sleep(ms);
- } catch (InterruptedException e) {
- e.printStackTrace();
- testFailed = true;
+ } catch (InterruptedException ex) {
+ throw new RuntimeException(ex);
}
}
@@ -128,14 +165,15 @@
super("LockAThread");
this.p = p;
}
+ @Override
public void run() {
- synchronized(objA) {
- // stop here for LockBThread to hold objB
- log("LockAThread about to block on objB");
+ synchronized(OBJA) {
+ // block here while LockBThread holds OBJB
+ log("LockAThread about to block on OBJB");
p.arriveAndAwaitAdvance(); // Phase 1 (blocking)
- synchronized(objB) {
+ synchronized(OBJB) {
dummyCounter++;
- };
+ }
}
p.arriveAndAwaitAdvance(); // Phase 2 (blocking)
log("LockAThread about to exit");
@@ -150,14 +188,15 @@
super("LockBThread");
this.p = p;
}
+ @Override
public void run() {
- synchronized(objB) {
- log("LockBThread about to block on objC");
+ synchronized(OBJB) {
+ log("LockBThread about to block on OBJC");
p.arriveAndAwaitAdvance(); // Phase 1 (blocking)
- // Signal main thread about to block on objC
- synchronized(objC) {
+ // Signal main thread about to block on OBJC
+ synchronized(OBJC) {
dummyCounter++;
- };
+ }
}
p.arriveAndAwaitAdvance(); // Phase 2 (blocking)
log("LockBThread about to exit");
@@ -166,9 +205,30 @@
}
}
+ /*
+ * Must be invoked from within a synchronized context
+ */
+ private static class EnhancedWaiter {
+
+ boolean isNotified = false;
+
+ public void doWait() throws InterruptedException {
+ while (!isNotified) {
+ wait();
+ }
+ isNotified = false;
+ }
+
+ public void doNotify() {
+ isNotified = true;
+ notify();
+ }
+ }
+
private static WaitingThread waiter;
private static final Object ready = new Object();
private static CheckerThread checker;
+
static class WaitingThread extends Thread {
private final Phaser p;
@@ -180,17 +240,16 @@
}
@Override
public void run() {
- synchronized(objC) {
- log("WaitingThread about to wait on objC");
+ synchronized(OBJC) {
+ log("WaitingThread about to wait on OBJC");
try {
- // Signal checker thread, about to wait on objC.
+ // Signal checker thread, about to wait on OBJC.
waiting = false;
p.arriveAndAwaitAdvance(); // Phase 1 (waiting)
waiting = true;
- objC.wait();
+ OBJC.doWait();
} catch (InterruptedException e) {
- e.printStackTrace();
- testFailed = true;
+ throw new RuntimeException(e); // Do not continue test
}
// block until CheckerThread finishes checking
@@ -202,19 +261,18 @@
dummyCounter++;
}
}
- synchronized(objC) {
+ synchronized(OBJC) {
try {
- // signal checker thread, about to wait on objC
+ // signal checker thread, about to wait on OBJC
waiting = false;
p.arriveAndAwaitAdvance(); // Phase 3 (waiting)
waiting = true;
- objC.wait();
+ OBJC.doWait();
} catch (InterruptedException e) {
- e.printStackTrace();
- testFailed = true;
+ throw new RuntimeException(e);
}
}
- log("WaitingThread about to exit waiting on objC 2");
+ log("WaitingThread about to exit waiting on OBJC 2");
}
public void waitForWaiting() {
@@ -241,85 +299,87 @@
super("CheckerThread");
}
+ @Override
public void run() {
- synchronized (ready) {
- // wait until WaitingThread about to wait for objC
+ synchronized(ready) {
+ // wait until WaitingThread about to wait for OBJC
waiter.waitForWaiting(); // Phase 1 (waiting)
- checkBlockedObject(waiter, objC, null, Thread.State.WAITING);
+ assertThreadState(waiter, Thread.State.WAITING);
+ checkBlockedObject(waiter, OBJC, null);
- synchronized (objC) {
- objC.notify();
+ synchronized(OBJC) {
+ OBJC.doNotify();
}
-
// wait for waiter thread to about to enter
// synchronized object ready.
waiter.waitForBlocked(); // Phase 2 (waiting)
- checkBlockedObject(waiter, ready, this, Thread.State.BLOCKED);
+ assertThreadState(waiter, Thread.State.BLOCKED);
+ checkBlockedObject(waiter, ready, this);
}
// wait for signal from waiting thread that it is about
- // wait for objC.
+ // wait for OBJC.
waiter.waitForWaiting(); // Phase 3 (waiting)
- synchronized(objC) {
- checkBlockedObject(waiter, objC, Thread.currentThread(), Thread.State.WAITING);
- objC.notify();
+ synchronized(OBJC) {
+ assertThreadState(waiter, Thread.State.WAITING);
+ checkBlockedObject(waiter, OBJC, Thread.currentThread());
+ OBJC.doNotify();
}
-
}
}
public static void main(String args[]) throws Exception {
- Thread mainThread = Thread.currentThread();
+ try {
+ Thread mainThread = Thread.currentThread();
- // Test uncontested case
- LockAThread t1;
- LockBThread t2;
-
- Phaser p = new Phaser(3);
- synchronized(objC) {
- // Make sure the main thread is not holding any lock
- assertNoLock(mainThread);
+ // Test uncontested case
+ LockAThread t1;
+ LockBThread t2;
- // Test deadlock case
- // t1 holds lockA and attempts to lock B
- // t2 holds lockB and attempts to lock C
-
- t1 = new LockAThread(p);
- t1.start();
+ Phaser p = new Phaser(3);
+ synchronized(OBJC) {
+ // Make sure the main thread is not holding any lock
+ assertNoLock(mainThread);
- t2 = new LockBThread(p);
- t2.start();
+ // Test deadlock case
+ // t1 holds lockA and attempts to lock B
+ // t2 holds lockB and attempts to lock C
+ t1 = new LockAThread(p);
+ t1.start();
- p.arriveAndAwaitAdvance(); // Phase 1 (blocking)
- checkBlockedObject(t2, objC, mainThread, Thread.State.BLOCKED);
- checkBlockedObject(t1, objB, t2, Thread.State.BLOCKED);
+ t2 = new LockBThread(p);
+ t2.start();
- long[] expectedThreads = new long[3];
- expectedThreads[0] = t1.getId(); // blocked on lockB
- expectedThreads[1] = t2.getId(); // owner of lockB blocking on lockC
- expectedThreads[2] = mainThread.getId(); // owner of lockC
- findThreadsBlockedOn(objB, expectedThreads);
- }
- p.arriveAndAwaitAdvance(); // Phase 2 (blocking)
+ p.arriveAndAwaitAdvance(); // Phase 1 (blocking)
+ assertThreadState(t2, Thread.State.BLOCKED);
+ checkBlockedObject(t2, OBJC, mainThread);
+ assertThreadState(t1, Thread.State.BLOCKED);
+ checkBlockedObject(t1, OBJB, t2);
- p = new Phaser(2);
- // Test Object.wait() case
- waiter = new WaitingThread(p);
- waiter.start();
+ long[] expectedThreads = new long[3];
+ expectedThreads[0] = t1.getId(); // blocked on lockB
+ expectedThreads[1] = t2.getId(); // owner of lockB blocking on lockC
+ expectedThreads[2] = mainThread.getId(); // owner of lockC
+ findThreadsBlockedOn(OBJB, expectedThreads);
+ }
+ p.arriveAndAwaitAdvance(); // Phase 2 (blocking)
- checker = new CheckerThread();
- checker.start();
+ p = new Phaser(2);
+ // Test Object.wait() case
+ waiter = new WaitingThread(p);
+ waiter.start();
+
+ checker = new CheckerThread();
+ checker.start();
- try {
- waiter.join();
- checker.join();
- } catch (InterruptedException e) {
- e.printStackTrace();
- testFailed = true;
- }
-
- if (testFailed) {
- throw new RuntimeException("TEST FAILED.");
+ try {
+ waiter.join();
+ checker.join();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ } finally { // log all the messages to STDOUT
+ System.out.println(LOGGER.toString());
}
System.out.println("Test passed.");
}
@@ -335,9 +395,9 @@
throw new RuntimeException("TEST FAILED: " +
lock + " expected to have owner");
}
- for (int j = 0; j < infos.length; j++) {
- if (infos[j].getThreadId() == threadId) {
- ownerInfo = infos[j];
+ for (ThreadInfo info1 : infos) {
+ if (info1.getThreadId() == threadId) {
+ ownerInfo = info1;
break;
}
}
@@ -349,11 +409,11 @@
throws Exception {
String lock = getLockName(o);
// Check with ThreadInfo with no stack trace (i.e. no safepoint)
- ThreadInfo[] infos = tm.getThreadInfo(tm.getAllThreadIds());
+ ThreadInfo[] infos = TM.getThreadInfo(TM.getAllThreadIds());
doCheck(infos, lock, expectedThreads);
// Check with ThreadInfo with stack trace
- infos = tm.getThreadInfo(tm.getAllThreadIds(), 1);
+ infos = TM.getThreadInfo(TM.getAllThreadIds(), 1);
doCheck(infos, lock, expectedThreads);
}
@@ -376,7 +436,7 @@
long[] threads = new long[10];
int count = 0;
threads[count++] = ownerInfo.getThreadId();
- while (ownerInfo != null && ownerInfo.getThreadState() == Thread.State.BLOCKED) {
+ while (ownerInfo.getThreadState() == Thread.State.BLOCKED) {
ownerInfo = findOwnerInfo(infos, lock);
threads[count++] = ownerInfo.getThreadId();
log(" Owner = %s id = %d",
@@ -407,6 +467,6 @@
}
private static void log(String format, Object ... args) {
- logger.log(format + "%n", args);
+ LOGGER.log(format + "%n", args);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/internal/misc/Unsafe/TestBadHostClass.java Sat Sep 10 12:18:34 2016 -0700
@@ -0,0 +1,111 @@
+/*
+ * 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 8058575
+ * @summary Test that bad host classes cause exceptions to get thrown.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * java.base/jdk.internal.org.objectweb.asm
+ * @run main TestBadHostClass
+ */
+
+
+import java.lang.*;
+import java.lang.reflect.Field;
+import jdk.internal.misc.Unsafe;
+import jdk.test.lib.unsafe.UnsafeHelper;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+
+// Test that bad host classes cause exceptions.
+public class TestBadHostClass {
+
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+ private static String packageName(Class<?> c) {
+ if (c.isArray()) {
+ return packageName(c.getComponentType());
+ } else {
+ String name = c.getName();
+ int dot = name.lastIndexOf('.');
+ if (dot == -1) return "";
+ return name.substring(0, dot);
+ }
+ }
+
+ private static int constantPoolSize(byte[] classFile) {
+ return ((classFile[8] & 0xFF) << 8) | (classFile[9] & 0xFF);
+ }
+
+ static public void badHostClass(Class<?> hostClass) {
+ // choose a class name in the same package as the host class
+ String className;
+ if (hostClass != null) {
+ String prefix = packageName(hostClass);
+ if (prefix.length() > 0)
+ prefix = prefix.replace('.', '/') + "/";
+ className = prefix + "Anon";
+ } else {
+ className = "Anon";
+ }
+
+ // create the class
+ String superName = "java/lang/Object";
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+ + ClassWriter.COMPUTE_FRAMES);
+ cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER,
+ className, null, superName, null);
+ byte[] classBytes = cw.toByteArray();
+ int cpPoolSize = constantPoolSize(classBytes);
+ Class<?> anonClass
+ = unsafe.defineAnonymousClass(hostClass, classBytes, new Object[cpPoolSize]);
+ }
+
+ public static void main(String args[]) throws Exception {
+ // host class is an array of java.lang.Objects.
+ try {
+ badHostClass(Object[].class);
+ } catch (IllegalArgumentException ex) {
+ }
+
+ // host class is an array of objects of this class.
+ try {
+ badHostClass(TestBadHostClass[].class);
+ } catch (IllegalArgumentException ex) {
+ }
+
+ // host class is null.
+ try {
+ badHostClass(null);
+ } catch (NullPointerException ex) {
+ }
+
+ // host class is a primitive array class.
+ try {
+ badHostClass(int[].class);
+ } catch (IllegalArgumentException ex) {
+ }
+ }
+}
--- a/jdk/test/sun/security/provider/FileInputStreamPool/FileInputStreamPoolTest.java Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/test/sun/security/provider/FileInputStreamPool/FileInputStreamPoolTest.java Sat Sep 10 12:18:34 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 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
@@ -69,7 +69,7 @@
// make JVM process References
System.gc();
// help ReferenceHandler thread enqueue References
- while (TestProxy.Reference_tryHandlePending(false)) {}
+ while (TestProxy.Reference_waitForReferenceProcessing()) { }
// help run Finalizers
System.runFinalization();
}
@@ -103,11 +103,11 @@
/**
* A proxy for (package)private static methods:
* sun.security.provider.FileInputStreamPool.getInputStream
- * java.lang.ref.Reference.tryHandlePending
+ * java.lang.ref.Reference.waitForReferenceProcessing
*/
static class TestProxy {
private static final Method getInputStreamMethod;
- private static final Method tryHandlePendingMethod;
+ private static final Method waitForReferenceProcessingMethod;
static {
try {
@@ -118,9 +118,9 @@
"getInputStream", File.class);
getInputStreamMethod.setAccessible(true);
- tryHandlePendingMethod = Reference.class.getDeclaredMethod(
- "tryHandlePending", boolean.class);
- tryHandlePendingMethod.setAccessible(true);
+ waitForReferenceProcessingMethod =
+ Reference.class.getDeclaredMethod("waitForReferenceProcessing");
+ waitForReferenceProcessingMethod.setAccessible(true);
} catch (Exception e) {
throw new Error(e);
}
@@ -146,13 +146,14 @@
}
}
- static boolean Reference_tryHandlePending(boolean waitForNotify) {
+ static boolean Reference_waitForReferenceProcessing() {
try {
- return (boolean) tryHandlePendingMethod
- .invoke(null, waitForNotify);
+ return (boolean) waitForReferenceProcessingMethod.invoke(null);
} catch (InvocationTargetException e) {
Throwable te = e.getTargetException();
- if (te instanceof RuntimeException) {
+ if (te instanceof InterruptedException) {
+ return true;
+ } else if (te instanceof RuntimeException) {
throw (RuntimeException) te;
} else if (te instanceof Error) {
throw (Error) te;
--- a/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java Sat Sep 10 12:18:34 2016 -0700
@@ -31,12 +31,10 @@
* @run main BasicLauncherTest
*/
-import static jdk.testlibrary.Asserts.assertTrue;
-
import java.io.BufferedReader;
import java.io.IOException;
+import java.io.OutputStream;
import java.io.InputStreamReader;
-import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
@@ -84,15 +82,56 @@
ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand());
processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
Process toolProcess = processBuilder.start();
- toolProcess.getOutputStream().write("quit\n".getBytes());
- toolProcess.getOutputStream().close();
+
+ try (OutputStream out = toolProcess.getOutputStream()) {
+ out.write("universe\n".getBytes());
+ out.write("printmdo -a\n".getBytes());
+ out.write("quit\n".getBytes());
+ }
// By default child process output stream redirected to pipe, so we are reading it in foreground.
- BufferedReader reader = new BufferedReader(new InputStreamReader(toolProcess.getInputStream()));
+ Exception unexpected = null;
+ try (BufferedReader reader =
+ new BufferedReader(new InputStreamReader(toolProcess.getInputStream()))) {
+ String line;
+ String unexpectedMsg =
+ "One or more of 'VirtualCallData', 'CounterData', " +
+ "'ReceiverTypeData', 'bci', 'MethodData' " +
+ "or 'java/lang/Object' not found";
+ boolean knownClassFound = false;
+ boolean knownProfileDataTypeFound = false;
+ boolean knownTokensFound = false;
+
+ while ((line = reader.readLine()) != null) {
+ line = line.trim();
+ System.out.println(line);
- String line;
- while ((line = reader.readLine()) != null) {
- System.out.println(line.trim());
+ if (line.contains("unknown subtype of CollectedHeap")) {
+ unexpected = new RuntimeException("CollectedHeap type should be known.");
+ break;
+ }
+ else if (line.contains("missing reason for ")) {
+ unexpected = new RuntimeException("missing reason for ");
+ break;
+ }
+ if (line.contains("VirtualCallData") ||
+ line.contains("CounterData") ||
+ line.contains("ReceiverTypeData")) {
+ knownProfileDataTypeFound = true;
+ }
+ if (line.contains("bci") ||
+ line.contains("MethodData")) {
+ knownTokensFound = true;
+ }
+ if (line.contains("java/lang/Object")) {
+ knownClassFound = true;
+ }
+ }
+ if ((knownClassFound == false) ||
+ (knownTokensFound == false) ||
+ (knownProfileDataTypeFound == false)) {
+ unexpected = new RuntimeException(unexpectedMsg);
+ }
}
toolProcess.waitFor();
@@ -100,6 +139,14 @@
if (toolProcess.exitValue() != 0) {
throw new RuntimeException("FAILED CLHSDB terminated with non-zero exit code " + toolProcess.exitValue());
}
+
+ if (unexpected != null) {
+ throw unexpected;
+ }
+
+ if (unexpected != null) {
+ throw unexpected;
+ }
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
@@ -183,21 +230,6 @@
Arrays.asList(toolArgs));
}
- public static void testHeapDump() throws IOException {
- File dump = new File("jhsdb.jmap.dump." +
- System.currentTimeMillis() + ".hprof");
- if (dump.exists()) {
- dump.delete();
- }
- dump.deleteOnExit();
-
- launch("heap written to", null, "jmap",
- "--binaryheap", "--dumpfile=" + dump.getAbsolutePath());
-
- assertTrue(dump.exists() && dump.isFile(),
- "Could not create dump file " + dump.getAbsolutePath());
- }
-
public static void main(String[] args)
throws IOException {
@@ -216,8 +248,6 @@
"System Properties info not available", "jinfo");
launch("java.threads", null, "jsnap");
- testHeapDump();
-
// The test throws RuntimeException on error.
// IOException is thrown if LingeredApp can't start because of some bad
// environment condition
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/tools/jhsdb/HeapDumpTest.java Sat Sep 10 12:18:34 2016 -0700
@@ -0,0 +1,129 @@
+/*
+ * 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 8163346
+ * @summary Test hashing of extended characters in Serviceability Agent.
+ * @library /test/lib
+ * @library /lib/testlibrary
+ * @compile -encoding utf8 HeapDumpTest.java
+ * @run main/timeout=240 HeapDumpTest
+ */
+
+import static jdk.testlibrary.Asserts.assertTrue;
+
+import java.io.IOException;
+import java.io.File;
+import java.util.List;
+import java.util.Arrays;
+import jdk.testlibrary.JDKToolLauncher;
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.test.lib.apps.LingeredApp;
+import jdk.testlibrary.Platform;
+
+public class HeapDumpTest {
+
+ private static LingeredAppWithExtendedChars theApp = null;
+
+ /**
+ *
+ * @param vmArgs - tool arguments to launch jhsdb
+ * @return exit code of tool
+ */
+ public static void launch(String expectedMessage, List<String> toolArgs)
+ throws IOException {
+
+ System.out.println("Starting LingeredApp");
+ try {
+ theApp = new LingeredAppWithExtendedChars();
+ LingeredApp.startApp(Arrays.asList("-Xmx256m"), theApp);
+
+ System.out.println(theApp.\u00CB);
+ System.out.println("Starting " + toolArgs.get(0) + " against " + theApp.getPid());
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+
+ for (String cmd : toolArgs) {
+ launcher.addToolArg(cmd);
+ }
+
+ launcher.addToolArg("--pid=" + Long.toString(theApp.getPid()));
+
+ ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand());
+ processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
+ OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
+ System.out.println("stdout:");
+ System.out.println(output.getStdout());
+ System.out.println("stderr:");
+ System.out.println(output.getStderr());
+ output.shouldContain(expectedMessage);
+ output.shouldHaveExitValue(0);
+
+ } catch (Exception ex) {
+ throw new RuntimeException("Test ERROR " + ex, ex);
+ } finally {
+ LingeredApp.stopApp(theApp);
+ }
+ }
+
+ public static void launch(String expectedMessage, String... toolArgs)
+ throws IOException {
+
+ launch(expectedMessage, Arrays.asList(toolArgs));
+ }
+
+ public static void testHeapDump() throws IOException {
+ File dump = new File("jhsdb.jmap.heap." +
+ System.currentTimeMillis() + ".hprof");
+ if (dump.exists()) {
+ dump.delete();
+ }
+
+ launch("heap written to", "jmap",
+ "--binaryheap", "--dumpfile=" + dump.getAbsolutePath());
+
+ assertTrue(dump.exists() && dump.isFile(),
+ "Could not create dump file " + dump.getAbsolutePath());
+
+ dump.delete();
+ }
+
+ public static void main(String[] args)
+ throws IOException {
+
+ if (!Platform.shouldSAAttach()) {
+ // Silently skip the test if we don't have enough permissions to attach
+ System.err.println("Error! Insufficient permissions to attach - test skipped.");
+ return;
+ }
+
+
+ testHeapDump();
+
+ // The test throws RuntimeException on error.
+ // IOException is thrown if LingeredApp can't start because of some bad
+ // environment condition
+ System.out.println("Test PASSED");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/tools/jhsdb/LingeredAppWithExtendedChars.java Sat Sep 10 12:18:34 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.
+ */
+import jdk.test.lib.apps.LingeredApp;
+
+public class LingeredAppWithExtendedChars extends LingeredApp {
+
+ public static int \u00CB = 1;
+
+ public static void main(String args[]) {
+ LingeredApp.main(args);
+ }
+ }
--- a/jdk/test/sun/tools/jps/TestJpsJar.java Sat Sep 10 06:46:45 2016 +0530
+++ b/jdk/test/sun/tools/jps/TestJpsJar.java Sat Sep 10 12:18:34 2016 -0700
@@ -38,7 +38,7 @@
* @library /lib/testlibrary
* @modules jdk.jartool/sun.tools.jar
* java.management
- * @build jdk.testlibrary.* JpsHelper JpsBase
+ * @build JpsHelper JpsBase
* @run main/othervm TestJpsJar
*/
public class TestJpsJar {