changeset 14143:96b1cfa80016

Merge
author jwilhelm
date Sat, 02 Apr 2016 05:30:48 +0200
parents 732099b9085b b0aeac976aea
children a16240806984 b2f88758fe16
files src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java test/ProblemList.txt
diffstat 23 files changed, 584 insertions(+), 123 deletions(-) [+]
line wrap: on
line diff
--- a/make/mapfiles/libjava/mapfile-vers	Thu Mar 24 15:53:22 2016 -0700
+++ b/make/mapfiles/libjava/mapfile-vers	Sat Apr 02 05:30:48 2016 +0200
@@ -224,8 +224,7 @@
 		Java_java_lang_System_setOut0;
 		Java_java_lang_Thread_registerNatives;
 		Java_java_lang_Throwable_fillInStackTrace;
-                Java_java_lang_Throwable_getStackTraceDepth;
-                Java_java_lang_Throwable_getStackTraceElement;
+                Java_java_lang_Throwable_getStackTraceElements;
 		Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2;
 		Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
 		Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2;
--- a/make/mapfiles/libjava/reorder-sparc	Thu Mar 24 15:53:22 2016 -0700
+++ b/make/mapfiles/libjava/reorder-sparc	Sat Apr 02 05:30:48 2016 +0200
@@ -78,8 +78,7 @@
 text: .text%JNU_GetEnv;
 text: .text%Java_java_io_UnixFileSystem_checkAccess;
 text: .text%Java_java_lang_reflect_Array_newArray;
-text: .text%Java_java_lang_Throwable_getStackTraceDepth;
-text: .text%Java_java_lang_Throwable_getStackTraceElement;
+text: .text%Java_java_lang_Throwable_getStackTraceElements;
 text: .text%throwFileNotFoundException;
 text: .text%JNU_NotifyAll;
 # Test LoadFrame
--- a/make/mapfiles/libjava/reorder-sparcv9	Thu Mar 24 15:53:22 2016 -0700
+++ b/make/mapfiles/libjava/reorder-sparcv9	Sat Apr 02 05:30:48 2016 +0200
@@ -74,8 +74,7 @@
 text: .text%JNU_GetEnv;
 text: .text%Java_java_io_UnixFileSystem_checkAccess;
 text: .text%Java_java_lang_reflect_Array_newArray;
-text: .text%Java_java_lang_Throwable_getStackTraceDepth;
-text: .text%Java_java_lang_Throwable_getStackTraceElement;
+text: .text%Java_java_lang_Throwable_getStackTraceElements;
 text: .text%throwFileNotFoundException: OUTPUTDIR/io_util.o;
 text: .text%JNU_NotifyAll;
 # Test LoadFrame
--- a/make/mapfiles/libjava/reorder-x86	Thu Mar 24 15:53:22 2016 -0700
+++ b/make/mapfiles/libjava/reorder-x86	Sat Apr 02 05:30:48 2016 +0200
@@ -78,8 +78,7 @@
 text: .text%Java_sun_reflect_NativeMethodAccessorImpl_invoke0;
 text: .text%Java_java_io_FileInputStream_available;
 text: .text%Java_java_lang_reflect_Array_newArray;
-text: .text%Java_java_lang_Throwable_getStackTraceDepth;
-text: .text%Java_java_lang_Throwable_getStackTraceElement;
+text: .text%Java_java_lang_Throwable_getStackTraceElements;
 text: .text%Java_java_lang_System_identityHashCode;
 text: .text%JNU_NotifyAll;
 # Test LoadFrame
--- a/src/java.base/share/classes/java/lang/StackTraceElement.java	Thu Mar 24 15:53:22 2016 -0700
+++ b/src/java.base/share/classes/java/lang/StackTraceElement.java	Sat Apr 02 05:30:48 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, 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
@@ -112,6 +112,12 @@
         this.lineNumber     = lineNumber;
     }
 
+
+    /**
+     * Creates an empty stack frame element to be filled in by Throwable.
+     */
+    StackTraceElement() { }
+
     /**
      * Returns the name of the source file containing the execution point
      * represented by this stack trace element.  Generally, this corresponds
--- a/src/java.base/share/classes/java/lang/Throwable.java	Thu Mar 24 15:53:22 2016 -0700
+++ b/src/java.base/share/classes/java/lang/Throwable.java	Sat Apr 02 05:30:48 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -118,7 +118,7 @@
     private static final long serialVersionUID = -3042686055658047285L;
 
     /**
-     * Native code saves some indication of the stack backtrace in this slot.
+     * The JVM saves some indication of the stack backtrace in this slot.
      */
     private transient Object backtrace;
 
@@ -211,6 +211,11 @@
      */
     private StackTraceElement[] stackTrace = UNASSIGNED_STACK;
 
+    /**
+     * The JVM code sets the depth of the backtrace for later retrieval
+     */
+    private transient int depth;
+
     // Setting this static field introduces an acceptable
     // initialization dependency on a few java.util classes.
     private static final List<Throwable> SUPPRESSED_SENTINEL = Collections.emptyList();
@@ -828,10 +833,11 @@
             if (backtrace instanceof StackStreamFactory.StackTrace) {
                 stackTrace = ((StackStreamFactory.StackTrace)backtrace).getStackTraceElements();
             } else {
-                int depth = getStackTraceDepth();
                 stackTrace = new StackTraceElement[depth];
-                for (int i = 0; i < depth; i++)
-                    stackTrace[i] = getStackTraceElement(i);
+                for (int i = 0; i < depth; i++) {
+                    stackTrace[i] = new StackTraceElement();
+                }
+                getStackTraceElements(stackTrace);
             }
         } else if (stackTrace == null) {
             return UNASSIGNED_STACK;
@@ -884,23 +890,11 @@
     }
 
     /**
-     * Returns the number of elements in the stack trace (or 0 if the stack
-     * trace is unavailable).
-     *
-     * package-protection for use by SharedSecrets.
+     * Gets the stack trace elements.
+     * @param  elements
+     * @throws IndexOutOfBoundsException if {@code elements.length != depth }
      */
-    native int getStackTraceDepth();
-
-    /**
-     * Returns the specified element of the stack trace.
-     *
-     * package-protection for use by SharedSecrets.
-     *
-     * @param index index of the element to return.
-     * @throws IndexOutOfBoundsException if {@code index < 0 ||
-     *         index >= getStackTraceDepth() }
-     */
-    native StackTraceElement getStackTraceElement(int index);
+    private native void getStackTraceElements(StackTraceElement[] elements);
 
     /**
      * Reads a {@code Throwable} from a stream, enforcing
--- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Thu Mar 24 15:53:22 2016 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Sat Apr 02 05:30:48 2016 +0200
@@ -34,11 +34,11 @@
 
 import java.lang.invoke.MethodHandles.Lookup;
 import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.function.Function;
+import sun.security.action.GetPropertyAction;
 
 import static jdk.internal.org.objectweb.asm.Opcodes.*;
 
@@ -188,20 +188,14 @@
     private static final ProxyClassesDumper DUMPER;
 
     static {
-        // Poke the privileged block once, taking everything we need:
-        final Object[] values = new Object[4];
-        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
-            values[0] = System.getProperty("java.lang.invoke.stringConcat");
-            values[1] = Boolean.getBoolean("java.lang.invoke.stringConcat.cache");
-            values[2] = Boolean.getBoolean("java.lang.invoke.stringConcat.debug");
-            values[3] = System.getProperty("java.lang.invoke.stringConcat.dumpClasses");
-            return null;
-        });
-
-        final String strategy = (String)  values[0];
-        CACHE_ENABLE          = (Boolean) values[1];
-        DEBUG                 = (Boolean) values[2];
-        final String dumpPath = (String)  values[3];
+        final String strategy = AccessController.doPrivileged(
+                new GetPropertyAction("java.lang.invoke.stringConcat"));
+        CACHE_ENABLE = Boolean.parseBoolean(AccessController.doPrivileged(
+                new GetPropertyAction("java.lang.invoke.stringConcat.cache")));
+        DEBUG = Boolean.parseBoolean(AccessController.doPrivileged(
+                new GetPropertyAction("java.lang.invoke.stringConcat.debug")));
+        final String dumpPath = AccessController.doPrivileged(
+                new GetPropertyAction("java.lang.invoke.stringConcat.dumpClasses"));
 
         STRATEGY = (strategy == null) ? DEFAULT_STRATEGY : Strategy.valueOf(strategy);
         CACHE = CACHE_ENABLE ? new ConcurrentHashMap<>() : null;
--- a/src/java.base/share/native/include/jvm.h	Thu Mar 24 15:53:22 2016 -0700
+++ b/src/java.base/share/native/include/jvm.h	Sat Apr 02 05:30:48 2016 +0200
@@ -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
@@ -171,11 +171,8 @@
 JNIEXPORT void JNICALL
 JVM_FillInStackTrace(JNIEnv *env, jobject throwable);
 
-JNIEXPORT jint JNICALL
-JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable);
-
-JNIEXPORT jobject JNICALL
-JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index);
+JNIEXPORT void JNICALL
+JVM_GetStackTraceElements(JNIEnv *env, jobject throwable, jobjectArray elements);
 
 /*
  * java.lang.StackWalker
--- a/src/java.base/share/native/libjava/Throwable.c	Thu Mar 24 15:53:22 2016 -0700
+++ b/src/java.base/share/native/libjava/Throwable.c	Sat Apr 02 05:30:48 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -50,15 +50,9 @@
     return throwable;
 }
 
-JNIEXPORT jint JNICALL
-Java_java_lang_Throwable_getStackTraceDepth(JNIEnv *env, jobject throwable)
+JNIEXPORT void JNICALL
+Java_java_lang_Throwable_getStackTraceElements(JNIEnv *env,
+                                               jobject throwable, jobjectArray elements)
 {
-    return JVM_GetStackTraceDepth(env, throwable);
+    JVM_GetStackTraceElements(env, throwable, elements);
 }
-
-JNIEXPORT jobject JNICALL
-Java_java_lang_Throwable_getStackTraceElement(JNIEnv *env,
-                                              jobject throwable, jint index)
-{
-    return JVM_GetStackTraceElement(env, throwable, index);
-}
--- a/src/java.management/share/classes/javax/management/remote/JMXServiceURL.java	Thu Mar 24 15:53:22 2016 -0700
+++ b/src/java.management/share/classes/javax/management/remote/JMXServiceURL.java	Sat Apr 02 05:30:48 2016 +0200
@@ -34,10 +34,15 @@
 import java.io.ObjectInputStream;
 
 import java.io.Serializable;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.MalformedURLException;
+import java.net.NetworkInterface;
+import java.net.SocketException;
 import java.net.UnknownHostException;
 import java.util.BitSet;
+import java.util.Enumeration;
 import java.util.Locale;
 import java.util.StringTokenizer;
 
@@ -236,10 +241,13 @@
      * @param protocol the protocol part of the URL.  If null, defaults
      * to <code>jmxmp</code>.
      *
-     * @param host the host part of the URL.  If null, defaults to the
-     * local host name, as determined by
-     * <code>InetAddress.getLocalHost().getHostName()</code>.  If it
-     * is a numeric IPv6 address, it can optionally be enclosed in
+     * @param host the host part of the URL. If host is null and if
+     * local host name can be resolved to an IP, then host defaults
+     * to local host name as determined by
+     * <code>InetAddress.getLocalHost().getHostName()</code>. If host is null
+     * and if local host name cannot be resolved to an IP, then host
+     * defaults to numeric IP address of one of the active network interfaces.
+     * If host is a numeric IPv6 address, it can optionally be enclosed in
      * square brackets <code>[]</code>.
      *
      * @param port the port part of the URL.
@@ -260,10 +268,13 @@
      * @param protocol the protocol part of the URL.  If null, defaults
      * to <code>jmxmp</code>.
      *
-     * @param host the host part of the URL.  If null, defaults to the
-     * local host name, as determined by
-     * <code>InetAddress.getLocalHost().getHostName()</code>.  If it
-     * is a numeric IPv6 address, it can optionally be enclosed in
+     * @param host the host part of the URL. If host is null and if
+     * local host name can be resolved to an IP, then host defaults
+     * to local host name as determined by
+     * <code>InetAddress.getLocalHost().getHostName()</code>. If host is null
+     * and if local host name cannot be resolved to an IP, then host
+     * defaults to numeric IP address of one of the active network interfaces.
+     * If host is a numeric IPv6 address, it can optionally be enclosed in
      * square brackets <code>[]</code>.
      *
      * @param port the port part of the URL.
@@ -286,32 +297,45 @@
             InetAddress local;
             try {
                 local = InetAddress.getLocalHost();
-            } catch (UnknownHostException e) {
-                throw new MalformedURLException("Local host name unknown: " +
-                                                e);
-            }
+                host = local.getHostName();
 
-            host = local.getHostName();
-
-            /* We might have a hostname that violates DNS naming
-               rules, for example that contains an `_'.  While we
-               could be strict and throw an exception, this is rather
-               user-hostile.  Instead we use its numerical IP address.
-               We can only reasonably do this for the host==null case.
-               If we're given an explicit host name that is illegal we
-               have to reject it.  (Bug 5057532.)  */
-            try {
-                validateHost(host, port);
-            } catch (MalformedURLException e) {
-                if (logger.fineOn()) {
+                /* We might have a hostname that violates DNS naming
+                rules, for example that contains an `_'.  While we
+                could be strict and throw an exception, this is rather
+                user-hostile.  Instead we use its numerical IP address.
+                We can only reasonably do this for the host==null case.
+                If we're given an explicit host name that is illegal we
+                have to reject it.  (Bug 5057532.)  */
+                try {
+                    validateHost(host, port);
+                } catch (MalformedURLException e) {
+                   if (logger.fineOn()) {
                     logger.fine("JMXServiceURL",
                                 "Replacing illegal local host name " +
                                 host + " with numeric IP address " +
                                 "(see RFC 1034)", e);
                 }
                 host = local.getHostAddress();
-                /* Use the numeric address, which could be either IPv4
-                   or IPv6.  validateHost will accept either.  */
+                }
+            } catch (UnknownHostException e) {
+                try {
+                    /*
+                    If hostname cannot be resolved, we will try and use numeric
+                    IPv4/IPv6 address. If host=null while starting agent,
+                    we know that it will be started on all interfaces - 0.0.0.0.
+                    Hence we will use IP address of first active non-loopback
+                    interface
+                    */
+                    host = getActiveNetworkInterfaceIP();
+                    if (host == null) {
+                        throw new MalformedURLException("Unable"
+                                + " to resolve hostname or "
+                                + "get valid IP address");
+                    }
+                } catch (SocketException ex) {
+                    throw new MalformedURLException("Unable"
+                            + " to resolve hostname or get valid IP address");
+                }
             }
         }
 
@@ -340,6 +364,33 @@
         validate();
     }
 
+    private String getActiveNetworkInterfaceIP() throws SocketException {
+        Enumeration<NetworkInterface>
+                networkInterface = NetworkInterface.getNetworkInterfaces();
+        String ipv6AddrStr = null;
+        while (networkInterface.hasMoreElements()) {
+            NetworkInterface nic = networkInterface.nextElement();
+            if (nic.isUp() && !nic.isLoopback()) {
+                Enumeration<InetAddress> inet = nic.getInetAddresses();
+                while (inet.hasMoreElements()) {
+                    InetAddress addr = inet.nextElement();
+                    if (addr instanceof Inet4Address
+                            && !addr.isLinkLocalAddress()) {
+                        return addr.getHostAddress();
+                    }else if (addr instanceof Inet6Address
+                            && !addr.isLinkLocalAddress()) {
+                        /*
+                        We save last seen IPv6 address which we will return
+                        if we do not find any interface with IPv4 address.
+                        */
+                        ipv6AddrStr = addr.getHostAddress();
+                    }
+                }
+            }
+        }
+        return ipv6AddrStr;
+    }
+
     private static final String INVALID_INSTANCE_MSG =
             "Trying to deserialize an invalid instance of JMXServiceURL";
     private void readObject(ObjectInputStream  inputStream) throws IOException, ClassNotFoundException {
@@ -540,7 +591,9 @@
      * constructor that takes a separate host parameter, the result is
      * the string that was specified.  If that string was null, the
      * result is
-     * <code>InetAddress.getLocalHost().getHostName()</code>.</p>
+     * <code>InetAddress.getLocalHost().getHostName()</code> if local host name
+     * can be resolved to an IP. Else numeric IP address of an active
+     * network interface will be used.</p>
      *
      * <p>In either case, if the host was specified using the
      * <code>[...]</code> syntax for numeric IPv6 addresses, the
--- a/src/java.management/share/classes/sun/management/jdp/JdpBroadcaster.java	Thu Mar 24 15:53:22 2016 -0700
+++ b/src/java.management/share/classes/sun/management/jdp/JdpBroadcaster.java	Sat Apr 02 05:30:48 2016 +0200
@@ -99,30 +99,7 @@
                 throw new JdpException("Unable to bind to source address");
             }
             channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
-        } else {
-            Enumeration<NetworkInterface> nics = NetworkInterface.getNetworkInterfaces();
-            boolean succeed = false;
-
-            while (nics.hasMoreElements()) {
-                NetworkInterface nic = nics.nextElement();
-
-                if (nic.isUp() && nic.supportsMulticast()) {
-                    try {
-                        channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, nic);
-                        succeed = true;
-                    } catch (IOException ex) {
-                        // pass
-                    }
-                }
-
-            }
-
-            if (!succeed) {
-                throw new JdpException("Unable to bind to any interfaces.");
-            }
-
         }
-
     }
 
     /**
--- a/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c	Thu Mar 24 15:53:22 2016 -0700
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c	Sat Apr 02 05:30:48 2016 +0200
@@ -211,6 +211,47 @@
     return error;
 }
 
+/*
+ * Delete global references from the request which got put there before a
+ * invoke request was carried out. See fillInvokeRequest() and invoker invoke*()
+ * impls.
+ */
+static void
+deleteGlobalRefs(JNIEnv *env, InvokeRequest *request)
+{
+    void *cursor;
+    jint argIndex = 0;
+    jvalue *argument = request->arguments;
+    jbyte argumentTag = firstArgumentTypeTag(request->methodSignature, &cursor);
+
+    if (request->clazz != NULL) {
+        tossGlobalRef(env, &(request->clazz));
+    }
+    if (request->instance != NULL) {
+        tossGlobalRef(env, &(request->instance));
+    }
+    /* Delete global argument references */
+    while (argIndex < request->argumentCount) {
+        if ((argumentTag == JDWP_TAG(OBJECT)) ||
+            (argumentTag == JDWP_TAG(ARRAY))) {
+            if (argument->l != NULL) {
+                tossGlobalRef(env, &(argument->l));
+            }
+        }
+        argument++;
+        argIndex++;
+        argumentTag = nextArgumentTypeTag(&cursor);
+    }
+    /* Delete potentially saved return values */
+    if ((request->invokeType == INVOKE_CONSTRUCTOR) ||
+        (returnTypeTag(request->methodSignature) == JDWP_TAG(OBJECT)) ||
+        (returnTypeTag(request->methodSignature) == JDWP_TAG(ARRAY))) {
+        if (request->returnValue.l != NULL) {
+            tossGlobalRef(env, &(request->returnValue.l));
+        }
+    }
+}
+
 static jvmtiError
 fillInvokeRequest(JNIEnv *env, InvokeRequest *request,
                   jbyte invokeType, jbyte options, jint id,
@@ -736,6 +777,13 @@
         (void)outStream_writeObjectRef(env, &out, exc);
         outStream_sendReply(&out);
     }
+
+    /*
+     * At this time, there's no need to retain global references on
+     * arguments since the reply is processed. No one will deal with
+     * this request ID anymore, so we must call deleteGlobalRefs().
+     */
+    deleteGlobalRefs(env, request);
 }
 
 jboolean
--- a/test/ProblemList.txt	Thu Mar 24 15:53:22 2016 -0700
+++ b/test/ProblemList.txt	Sat Apr 02 05:30:48 2016 +0200
@@ -162,9 +162,6 @@
 # 8042215
 javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java			generic-all
 
-# 8147985
-sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java generic-all
-
 ############################################################################
 
 # jdk_net
@@ -382,6 +379,12 @@
 # 8067354
 com/sun/jdi/GetLocalVariables4Test.sh				windows-all
 
+# 8152586
+com/sun/jdi/InterfaceMethodsTest.java				generic-all
+
+# 8152586
+com/sun/jdi/InvokeTest.java					generic-all
+
 ############################################################################
 
 # jdk_util
--- a/test/com/sun/jdi/InterruptHangTest.java	Thu Mar 24 15:53:22 2016 -0700
+++ b/test/com/sun/jdi/InterruptHangTest.java	Sat Apr 02 05:30:48 2016 +0200
@@ -153,14 +153,17 @@
         timerThread = new Thread("test timer") {
                 public void run() {
                     int mySteps = 0;
+                    float timeoutFactor = Float.parseFloat(System.getProperty("test.timeout.factor", "1.0"));
+                    long sleepSeconds = (long)(20 * timeoutFactor);
+                    println("Timer watching for steps every " + sleepSeconds + " seconds");
                     while (true) {
                         try {
-                            Thread.sleep(20000);
+                            Thread.sleep(sleepSeconds * 1000);
                             synchronized(sync) {
-                                System.out.println("steps = " + nSteps);
+                                println("steps = " + nSteps);
                                 if (mySteps == nSteps) {
-                                    // no step for 10 secs
-                                    failure("failure: Debuggee appears to be hung");
+                                    // no step for a long time
+                                    failure("failure: Debuggee appears to be hung (no steps for " + sleepSeconds + "s)");
                                     vm().exit(-1);
                                     break;
                                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/jdi/OomDebugTest.java	Sat Apr 02 05:30:48 2016 +0200
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2016 Red Hat Inc.
+ *
+ * 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 4858370
+ *  @summary JDWP: Memory Leak (global references not deleted after invokeMethod).
+ *
+ *  @author Severin Gehwolf <sgehwolf@redhat.com>
+ *
+ *  @library ..
+ *  @run build TestScaffold VMConnection TargetListener TargetAdapter
+ *  @run compile -g OomDebugTest.java
+ *  @run main OomDebugTest OomDebugTestTarget test1
+ *  @run main OomDebugTest OomDebugTestTarget test2
+ *  @run main OomDebugTest OomDebugTestTarget test3
+ *  @run main OomDebugTest OomDebugTestTarget test4
+ *  @run main OomDebugTest OomDebugTestTarget test5
+ */
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.sun.jdi.ArrayReference;
+import com.sun.jdi.ArrayType;
+import com.sun.jdi.ClassType;
+import com.sun.jdi.Field;
+import com.sun.jdi.InvocationException;
+import com.sun.jdi.Method;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.ReferenceType;
+import com.sun.jdi.StackFrame;
+import com.sun.jdi.VMOutOfMemoryException;
+import com.sun.jdi.Value;
+import com.sun.jdi.event.BreakpointEvent;
+
+/***************** Target program **********************/
+
+class OomDebugTestTarget {
+
+    OomDebugTestTarget() {
+        System.out.println("DEBUG: invoked constructor");
+    }
+    static class FooCls {
+        @SuppressWarnings("unused")
+        private byte[] bytes = new byte[3000000];
+    };
+
+    FooCls fooCls = new FooCls();
+    byte[] byteArray = new byte[0];
+
+    void testMethod(FooCls foo) {
+        System.out.println("DEBUG: invoked 'void testMethod(FooCls)', foo == " + foo);
+    }
+
+    void testPrimitive(byte[] foo) {
+        System.out.println("DEBUG: invoked 'void testPrimitive(byte[])', foo == " + foo);
+    }
+
+    byte[] testPrimitiveArrRetval() {
+        System.out.println("DEBUG: invoked 'byte[] testPrimitiveArrRetval()'");
+        return new byte[3000000];
+    }
+
+    FooCls testFooClsRetval() {
+        System.out.println("DEBUG: invoked 'FooCls testFooClsRetval()'");
+        return new FooCls();
+    }
+
+    public void entry() {}
+
+    public static void main(String[] args){
+        System.out.println("DEBUG: OomDebugTestTarget.main");
+        new OomDebugTestTarget().entry();
+    }
+}
+
+/***************** Test program ************************/
+
+public class OomDebugTest extends TestScaffold {
+
+    private static final int TOTAL_TESTS = 1;
+    private ReferenceType targetClass;
+    private ObjectReference thisObject;
+    private int failedTests;
+    private final String testMethodName;
+
+    public OomDebugTest(String[] args) {
+        super(args);
+        if (args.length != 2) {
+            throw new RuntimeException("Test failed unexpectedly.");
+        }
+        testMethodName = args[1];
+    }
+
+    @Override
+    protected void runTests() throws Exception {
+        try {
+            /*
+             * Get to the top of entry()
+             * to determine targetClass and mainThread
+             */
+            BreakpointEvent bpe = startTo("OomDebugTestTarget", "entry", "()V");
+            targetClass = bpe.location().declaringType();
+
+            mainThread = bpe.thread();
+
+            StackFrame frame = mainThread.frame(0);
+            thisObject = frame.thisObject();
+            java.lang.reflect.Method m = findTestMethod();
+            m.invoke(this);
+        } catch (NoSuchMethodException e) {
+            e.printStackTrace();
+            failure();
+        } catch (SecurityException e) {
+            e.printStackTrace();
+            failure();
+        }
+    }
+
+    private java.lang.reflect.Method findTestMethod()
+            throws NoSuchMethodException, SecurityException {
+        return OomDebugTest.class.getDeclaredMethod(testMethodName);
+    }
+
+    private void failure() {
+        failedTests++;
+    }
+
+    /*
+     * Test case: Object reference as method parameter.
+     */
+    @SuppressWarnings("unused") // called via reflection
+    private void test1() throws Exception {
+        System.out.println("DEBUG: ------------> Running " + testMethodName);
+        try {
+            Field field = targetClass.fieldByName("fooCls");
+            ClassType clsType = (ClassType)field.type();
+            Method constructor = getConstructorForClass(clsType);
+            for (int i = 0; i < 15; i++) {
+                @SuppressWarnings({ "rawtypes", "unchecked" })
+                ObjectReference objRef = clsType.newInstance(mainThread,
+                                                             constructor,
+                                                             new ArrayList(0),
+                                                             ObjectReference.INVOKE_NONVIRTUAL);
+                invoke("testMethod", "(LOomDebugTestTarget$FooCls;)V", objRef);
+            }
+        } catch (InvocationException e) {
+            handleFailure(e);
+        }
+    }
+
+    /*
+     * Test case: Array reference as method parameter.
+     */
+    @SuppressWarnings("unused") // called via reflection
+    private void test2() throws Exception {
+        System.out.println("DEBUG: ------------> Running " + testMethodName);
+        try {
+            Field field = targetClass.fieldByName("byteArray");
+            ArrayType arrType = (ArrayType)field.type();
+
+            for (int i = 0; i < 15; i++) {
+                ArrayReference byteArrayVal = arrType.newInstance(3000000);
+                invoke("testPrimitive", "([B)V", byteArrayVal);
+            }
+        } catch (VMOutOfMemoryException e) {
+            defaultHandleOOMFailure(e);
+        }
+    }
+
+    /*
+     * Test case: Array reference as return value.
+     */
+    @SuppressWarnings("unused") // called via reflection
+    private void test3() throws Exception {
+        System.out.println("DEBUG: ------------> Running " + testMethodName);
+        try {
+            for (int i = 0; i < 15; i++) {
+                invoke("testPrimitiveArrRetval",
+                       "()[B",
+                       Collections.EMPTY_LIST,
+                       vm().mirrorOfVoid());
+            }
+        } catch (InvocationException e) {
+            handleFailure(e);
+        }
+    }
+
+    /*
+     * Test case: Object reference as return value.
+     */
+    @SuppressWarnings("unused") // called via reflection
+    private void test4() throws Exception {
+        System.out.println("DEBUG: ------------> Running " + testMethodName);
+        try {
+            for (int i = 0; i < 15; i++) {
+                invoke("testFooClsRetval",
+                       "()LOomDebugTestTarget$FooCls;",
+                       Collections.EMPTY_LIST,
+                       vm().mirrorOfVoid());
+            }
+        } catch (InvocationException e) {
+            handleFailure(e);
+        }
+    }
+
+    /*
+     * Test case: Constructor
+     */
+    @SuppressWarnings({ "unused", "unchecked", "rawtypes" }) // called via reflection
+    private void test5() throws Exception {
+        System.out.println("DEBUG: ------------> Running " + testMethodName);
+        try {
+            ClassType type = (ClassType)thisObject.type();
+            for (int i = 0; i < 15; i++) {
+                type.newInstance(mainThread,
+                                 findMethod(targetClass, "<init>", "()V"),
+                                 new ArrayList(0),
+                                 ObjectReference.INVOKE_NONVIRTUAL);
+            }
+        } catch (InvocationException e) {
+            handleFailure(e);
+        }
+    }
+
+    private Method getConstructorForClass(ClassType clsType) {
+        List<Method> methods = clsType.methodsByName("<init>");
+        if (methods.size() != 1) {
+            throw new RuntimeException("FAIL. Expected only one, the default, constructor");
+        }
+        return methods.get(0);
+    }
+
+    private void handleFailure(InvocationException e) {
+        // There is no good way to see the OOME diagnostic message in the target since the
+        // TestScaffold might throw an exception while trying to print the stack trace. I.e
+        // it might get a a VMDisconnectedException before the stack trace printing finishes.
+        System.err.println("FAILURE: InvocationException caused by OOM");
+        defaultHandleOOMFailure(e);
+    }
+
+    private void defaultHandleOOMFailure(Exception e) {
+        e.printStackTrace();
+        failure();
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    void invoke(String methodName, String methodSig, Value value)
+            throws Exception {
+        List args = new ArrayList(1);
+        args.add(value);
+        invoke(methodName, methodSig, args, value);
+    }
+
+    void invoke(String methodName,
+                String methodSig,
+                @SuppressWarnings("rawtypes") List args,
+                Value value) throws Exception {
+        Method method = findMethod(targetClass, methodName, methodSig);
+        if ( method == null) {
+            failure("FAILED: Can't find method: "
+                    + methodName  + " for class = " + targetClass);
+            return;
+        }
+        invoke(method, args, value);
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    void invoke(Method method, List args, Value value) throws Exception {
+        thisObject.invokeMethod(mainThread, method, args, 0);
+        System.out.println("DEBUG: Done invoking method via debugger.");
+    }
+
+    Value fieldValue(String fieldName) {
+        Field field = targetClass.fieldByName(fieldName);
+        return thisObject.getValue(field);
+    }
+
+    public static void main(String[] args) throws Exception {
+        System.setProperty("test.vm.opts", "-Xmx40m"); // Set debuggee VM option
+        OomDebugTest oomTest = new OomDebugTest(args);
+        oomTest.startTests();
+        if (oomTest.failedTests > 0) {
+            throw new RuntimeException(oomTest.failedTests
+                                       + " of " + TOTAL_TESTS + " test(s) failed.");
+        }
+        System.out.println("All " + TOTAL_TESTS + " tests passed.");
+    }
+
+}
--- a/test/com/sun/jdi/ShellScaffold.sh	Thu Mar 24 15:53:22 2016 -0700
+++ b/test/com/sun/jdi/ShellScaffold.sh	Sat Apr 02 05:30:48 2016 +0200
@@ -131,6 +131,9 @@
 
 # This can be increased if timing seems to be an issue.
 sleep_seconds=1
+if [ -n "$TIMEOUT_FACTOR" ] ; then
+  sleep_seconds=$(echo $TIMEOUT_FACTOR $sleep_seconds | awk '{printf "%d\n", int($1 * $2)}')
+fi
 
 echo "ShellScaffold.sh: Version" >& 2
 topPid=$$
--- a/test/com/sun/jdi/TestScaffold.java	Thu Mar 24 15:53:22 2016 -0700
+++ b/test/com/sun/jdi/TestScaffold.java	Sat Apr 02 05:30:48 2016 +0200
@@ -64,6 +64,7 @@
     boolean vmDisconnected = false;
     final String[] args;
     protected boolean testFailed = false;
+    protected long startTime;
 
     static private class ArgInfo {
         String targetVMArgs = "";
@@ -425,6 +426,7 @@
     abstract protected void runTests() throws Exception;
 
     final public void startTests() throws Exception {
+        startTime = System.currentTimeMillis();
         try {
             runTests();
         } finally {
@@ -433,7 +435,8 @@
     }
 
     protected void println(String str) {
-        System.err.println(str);
+        long elapsed = System.currentTimeMillis() - startTime;
+        System.err.println("[" + elapsed + "ms] " + str);
     }
 
     protected void print(String str) {
--- a/test/java/lang/management/ThreadMXBean/ThreadLists.java	Thu Mar 24 15:53:22 2016 -0700
+++ b/test/java/lang/management/ThreadMXBean/ThreadLists.java	Sat Apr 02 05:30:48 2016 +0200
@@ -35,6 +35,11 @@
 public class ThreadLists {
     public static void main(String args[]) {
 
+        // Bug id : JDK-8151797
+        // Use a lambda expression so that call-site cleaner thread is started
+        Runnable printLambda = () -> {System.out.println("Starting Test");};
+        printLambda.run();
+
         // get top-level thread group
         ThreadGroup top = Thread.currentThread().getThreadGroup();
         ThreadGroup parent;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/text/Format/DateFormat/DFSConstructorCloneTest.java	Sat Apr 02 05:30:48 2016 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8087104
+ * @summary Make sure that clone() method is not called from DateFormatSymbols constructor.
+ */
+import java.text.DateFormatSymbols;
+
+public class DFSymbolsCloneTest extends DateFormatSymbols {
+
+    private Foo foo;
+
+    public DFSymbolsCloneTest(Foo fooObj) {
+        if (fooObj == null) {
+            this.foo = new Foo();
+        } else {
+            this.foo = fooObj;
+        }
+    }
+
+    @Override
+    public Object clone() {
+        DFSymbolsCloneTest dfsclone = (DFSymbolsCloneTest) super.clone();
+        if (this.foo == null) {
+            throw new RuntimeException("Clone method should not be called from "
+                    + " Superclass(DateFormatSymbols) Constructor...");
+        } else {
+            dfsclone.foo = (Foo) this.foo.clone();
+        }
+        return dfsclone;
+    }
+
+    public static void main(String[] args) {
+        DFSymbolsCloneTest dfsctest = new DFSymbolsCloneTest(new Foo());
+    }
+}
+
+class Foo {
+
+    public Foo() {
+    }
+
+    @Override
+    protected Object clone() {
+        return new Foo();
+    }
+
+}
--- a/test/sun/management/jdp/JdpDefaultsTest.java	Thu Mar 24 15:53:22 2016 -0700
+++ b/test/sun/management/jdp/JdpDefaultsTest.java	Sat Apr 02 05:30:48 2016 +0200
@@ -57,7 +57,6 @@
                 "-Dcom.sun.management.jmxremote.autodiscovery=true",
                 "-Dcom.sun.management.jdp.pause=1",
                 "-Dcom.sun.management.jdp.name=" + jdpName,
-                "-Dcom.sun.management.jdp.address=224.0.23.178",
                 "-Djava.util.logging.SimpleFormatter.format='%1$tF %1$tT %4$-7s %5$s %n'",
                 testName
         };
--- a/test/sun/management/jdp/JdpTestCase.java	Thu Mar 24 15:53:22 2016 -0700
+++ b/test/sun/management/jdp/JdpTestCase.java	Sat Apr 02 05:30:48 2016 +0200
@@ -122,7 +122,7 @@
      */
     private void jdpPacketReceived(Map<String, String> payload) throws Exception {
         final String instanceName = payload.get("INSTANCE_NAME");
-        if (instanceName.equals(connection.instanceName)) {
+        if (instanceName != null && instanceName.equals(connection.instanceName)) {
             packetFromThisVMReceived(payload);
         } else {
             packetFromOtherVMReceived(payload);
--- a/test/sun/tools/jhsdb/BasicLauncherTest.java	Thu Mar 24 15:53:22 2016 -0700
+++ b/test/sun/tools/jhsdb/BasicLauncherTest.java	Sat Apr 02 05:30:48 2016 +0200
@@ -143,6 +143,7 @@
         launch("No deadlocks found", "jstack");
         launch("compiler detected", "jmap");
         launch("Java System Properties", "jinfo");
+        launch("java.threads", "jsnap");
 
         // The test throws RuntimeException on error.
         // IOException is thrown if LingeredApp can't start because of some bad
--- a/test/sun/tools/jhsdb/SAGetoptTest.java	Thu Mar 24 15:53:22 2016 -0700
+++ b/test/sun/tools/jhsdb/SAGetoptTest.java	Sat Apr 02 05:30:48 2016 +0200
@@ -153,5 +153,8 @@
 
         String[] optionSet6 = {"--exe", "--core", "bla_core"};
         badOptionsTest(6, optionSet6, "Argument is expected for 'exe'");
+
+        String[] optionSet7 = {"--exe"};
+        badOptionsTest(7, optionSet7, "Argument is expected for 'exe'");
     }
   }