# HG changeset patch # User amurillo # Date 1473535114 25200 # Node ID 482eb34be1913bacb153753026893c70087073e4 # Parent 99330a831848ddcb9e2a13e8b6e3a76847c08f2d# Parent 626487a7488ad0ed4f5bc8c71868381626e0d5ef Merge diff -r 99330a831848 -r 482eb34be191 jdk/make/mapfiles/libjava/mapfile-vers --- 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; diff -r 99330a831848 -r 482eb34be191 jdk/src/java.base/share/classes/java/lang/ref/Reference.java --- 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 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 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.

- * 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 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 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 pendingList; + synchronized (processPendingLock) { + pendingList = getAndClearReferencePendingList(); + processPendingActive = true; + } + while (pendingList != null) { + Reference 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 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 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(); } }); } diff -r 99330a831848 -r 482eb34be191 jdk/src/java.base/share/classes/java/nio/Bits.java --- 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; } } diff -r 99330a831848 -r 482eb34be191 jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangRefAccess.java --- 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; } diff -r 99330a831848 -r 482eb34be191 jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java --- 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); } diff -r 99330a831848 -r 482eb34be191 jdk/src/java.base/share/native/include/jvm.h --- 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 diff -r 99330a831848 -r 482eb34be191 jdk/src/java.base/share/native/libjava/Reference.c --- /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); +} diff -r 99330a831848 -r 482eb34be191 jdk/src/java.management/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java --- 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."); } diff -r 99330a831848 -r 482eb34be191 jdk/src/java.management/share/classes/com/sun/jmx/interceptor/MBeanServerInterceptor.java --- 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(); } diff -r 99330a831848 -r 482eb34be191 jdk/src/java.management/share/classes/javax/management/MBeanServer.java --- 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."); + } /** *

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."); + } /** *

Return the {@link java.lang.ClassLoader} that was used for diff -r 99330a831848 -r 482eb34be191 jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java --- 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(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(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 diff -r 99330a831848 -r 482eb34be191 jdk/test/ProblemList.txt --- 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 diff -r 99330a831848 -r 482eb34be191 jdk/test/com/sun/jdi/ConstantPoolInfoGC.java --- /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"); + } + } +} diff -r 99330a831848 -r 482eb34be191 jdk/test/java/lang/Class/GetModuleTest.java --- 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); } diff -r 99330a831848 -r 482eb34be191 jdk/test/java/lang/invoke/VMAnonymousClass.java --- 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); diff -r 99330a831848 -r 482eb34be191 jdk/test/java/lang/management/ThreadMXBean/Locks.java --- 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 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 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); } } diff -r 99330a831848 -r 482eb34be191 jdk/test/jdk/internal/misc/Unsafe/TestBadHostClass.java --- /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) { + } + } +} diff -r 99330a831848 -r 482eb34be191 jdk/test/sun/security/provider/FileInputStreamPool/FileInputStreamPoolTest.java --- 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; diff -r 99330a831848 -r 482eb34be191 jdk/test/sun/tools/jhsdb/BasicLauncherTest.java --- 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 diff -r 99330a831848 -r 482eb34be191 jdk/test/sun/tools/jhsdb/HeapDumpTest.java --- /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 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"); + } +} diff -r 99330a831848 -r 482eb34be191 jdk/test/sun/tools/jhsdb/LingeredAppWithExtendedChars.java --- /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); + } + } diff -r 99330a831848 -r 482eb34be191 jdk/test/sun/tools/jps/TestJpsJar.java --- 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 {