Removed upstreamed patches
This commit is contained in:
parent
347e967ec7
commit
a0fefe5e20
@ -1,278 +0,0 @@
|
||||
# HG changeset patch
|
||||
# User vtewari
|
||||
# Date 1508189111 -3600
|
||||
# Mon Oct 16 22:25:11 2017 +0100
|
||||
# Node ID bcaa659478ccac2b2ad1a817e03cab777949775a
|
||||
# Parent 161fbe4c53ff12328565487e69a608e15f39bd49
|
||||
8075484, PR3473, RH1490713: SocketInputStream.socketRead0 can hang even with soTimeout set
|
||||
Reviewed-by: chegar, dsamersoff, msheppar, clanger
|
||||
|
||||
diff --git a/src/aix/native/java/net/aix_close.c b/src/aix/native/java/net/aix_close.c
|
||||
--- openjdk/jdk/src/aix/native/java/net/aix_close.c
|
||||
+++ openjdk/jdk/src/aix/native/java/net/aix_close.c
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2016, SAP SE 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
|
||||
@@ -328,6 +329,10 @@
|
||||
BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
|
||||
}
|
||||
|
||||
+int NET_NonBlockingRead(int s, void* buf, size_t len) {
|
||||
+ BLOCKING_IO_RETURN_INT(s, recv(s, buf, len, MSG_NONBLOCK));
|
||||
+}
|
||||
+
|
||||
int NET_ReadV(int s, const struct iovec * vector, int count) {
|
||||
BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
|
||||
}
|
||||
@@ -429,8 +434,8 @@
|
||||
* Auto restarts with adjusted timeout if interrupted by
|
||||
* signal other than our wakeup signal.
|
||||
*/
|
||||
-int NET_Timeout(int s, long timeout) {
|
||||
- long prevtime = 0, newtime;
|
||||
+int NET_Timeout0(int s, long timeout, long currentTime) {
|
||||
+ long prevtime = currentTime, newtime;
|
||||
struct timeval t;
|
||||
fdEntry_t *fdEntry = getFdEntry(s);
|
||||
|
||||
@@ -442,14 +447,6 @@
|
||||
return -1;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Pick up current time as may need to adjust timeout
|
||||
- */
|
||||
- if (timeout > 0) {
|
||||
- gettimeofday(&t, NULL);
|
||||
- prevtime = t.tv_sec * 1000 + t.tv_usec / 1000;
|
||||
- }
|
||||
-
|
||||
for(;;) {
|
||||
struct pollfd pfd;
|
||||
int rv;
|
||||
diff --git a/src/solaris/native/java/net/SocketInputStream.c b/src/solaris/native/java/net/SocketInputStream.c
|
||||
--- openjdk/jdk/src/solaris/native/java/net/SocketInputStream.c
|
||||
+++ openjdk/jdk/src/solaris/native/java/net/SocketInputStream.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 1997, 2012, 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
|
||||
@@ -52,6 +52,42 @@
|
||||
IO_fd_fdID = NET_GetFileDescriptorID(env);
|
||||
}
|
||||
|
||||
+#if !defined(__solaris__)
|
||||
+static int NET_ReadWithTimeout(JNIEnv *env, int fd, char *bufP, int len, long timeout) {
|
||||
+ int result = 0;
|
||||
+ long prevtime = NET_GetCurrentTime(), newtime;
|
||||
+ while (timeout > 0) {
|
||||
+ result = NET_TimeoutWithCurrentTime(fd, timeout, prevtime);
|
||||
+ if (result <= 0) {
|
||||
+ if (result == 0) {
|
||||
+ JNU_ThrowByName(env, "java/net/SocketTimeoutException", "Read timed out");
|
||||
+ } else if (result == -1) {
|
||||
+ if (errno == EBADF) {
|
||||
+ JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
|
||||
+ } else if (errno == ENOMEM) {
|
||||
+ JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed");
|
||||
+ } else {
|
||||
+ JNU_ThrowByNameWithMessageAndLastError
|
||||
+ (env, "java/net/SocketException", "select/poll failed");
|
||||
+ }
|
||||
+ }
|
||||
+ return -1;
|
||||
+ }
|
||||
+ result = NET_NonBlockingRead(fd, bufP, len);
|
||||
+ if (result == -1 && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) {
|
||||
+ newtime = NET_GetCurrentTime();
|
||||
+ timeout -= newtime - prevtime;
|
||||
+ if (timeout > 0) {
|
||||
+ prevtime = newtime;
|
||||
+ }
|
||||
+ } else {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return result;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Class: java_net_SocketInputStream
|
||||
* Method: socketRead0
|
||||
@@ -99,6 +135,7 @@
|
||||
bufP = BUF;
|
||||
}
|
||||
|
||||
+#if defined(__solaris__)
|
||||
if (timeout) {
|
||||
nread = NET_Timeout(fd, timeout);
|
||||
if (nread <= 0) {
|
||||
@@ -126,7 +163,19 @@
|
||||
}
|
||||
|
||||
nread = NET_Read(fd, bufP, len);
|
||||
-
|
||||
+#else
|
||||
+ if (timeout) {
|
||||
+ nread = NET_ReadWithTimeout(env, fd, bufP, len, timeout);
|
||||
+ if ((*env)->ExceptionCheck(env)) {
|
||||
+ if (bufP != BUF) {
|
||||
+ free(bufP);
|
||||
+ }
|
||||
+ return nread;
|
||||
+ }
|
||||
+ } else {
|
||||
+ nread = NET_Read(fd, bufP, len);
|
||||
+ }
|
||||
+#endif
|
||||
if (nread <= 0) {
|
||||
if (nread < 0) {
|
||||
|
||||
diff --git a/src/solaris/native/java/net/bsd_close.c b/src/solaris/native/java/net/bsd_close.c
|
||||
--- openjdk/jdk/src/solaris/native/java/net/bsd_close.c
|
||||
+++ openjdk/jdk/src/solaris/native/java/net/bsd_close.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2001, 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
|
||||
@@ -292,6 +292,10 @@
|
||||
BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
|
||||
}
|
||||
|
||||
+int NET_NonBlockingRead(int s, void* buf, size_t len) {
|
||||
+ BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, MSG_DONTWAIT));
|
||||
+}
|
||||
+
|
||||
int NET_ReadV(int s, const struct iovec * vector, int count) {
|
||||
BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
|
||||
}
|
||||
@@ -344,8 +348,8 @@
|
||||
* Auto restarts with adjusted timeout if interrupted by
|
||||
* signal other than our wakeup signal.
|
||||
*/
|
||||
-int NET_Timeout(int s, long timeout) {
|
||||
- long prevtime = 0, newtime;
|
||||
+int NET_Timeout0(int s, long timeout, long currentTime) {
|
||||
+ long prevtime = currentTime, newtime;
|
||||
struct timeval t, *tp = &t;
|
||||
fd_set fds;
|
||||
fd_set* fdsp = NULL;
|
||||
@@ -366,9 +370,6 @@
|
||||
*/
|
||||
if (timeout > 0) {
|
||||
/* Timed */
|
||||
- struct timeval now;
|
||||
- gettimeofday(&now, NULL);
|
||||
- prevtime = now.tv_sec * 1000 + now.tv_usec / 1000;
|
||||
t.tv_sec = timeout / 1000;
|
||||
t.tv_usec = (timeout % 1000) * 1000;
|
||||
} else if (timeout < 0) {
|
||||
diff --git a/src/solaris/native/java/net/linux_close.c b/src/solaris/native/java/net/linux_close.c
|
||||
--- openjdk/jdk/src/solaris/native/java/net/linux_close.c
|
||||
+++ openjdk/jdk/src/solaris/native/java/net/linux_close.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2001, 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
|
||||
@@ -273,6 +273,10 @@
|
||||
BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
|
||||
}
|
||||
|
||||
+int NET_NonBlockingRead(int s, void* buf, size_t len) {
|
||||
+ BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, MSG_DONTWAIT) );
|
||||
+}
|
||||
+
|
||||
int NET_ReadV(int s, const struct iovec * vector, int count) {
|
||||
BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
|
||||
}
|
||||
@@ -324,8 +328,8 @@
|
||||
* Auto restarts with adjusted timeout if interrupted by
|
||||
* signal other than our wakeup signal.
|
||||
*/
|
||||
-int NET_Timeout(int s, long timeout) {
|
||||
- long prevtime = 0, newtime;
|
||||
+int NET_Timeout0(int s, long timeout, long currentTime) {
|
||||
+ long prevtime = currentTime, newtime;
|
||||
struct timeval t;
|
||||
fdEntry_t *fdEntry = getFdEntry(s);
|
||||
|
||||
@@ -337,14 +341,6 @@
|
||||
return -1;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Pick up current time as may need to adjust timeout
|
||||
- */
|
||||
- if (timeout > 0) {
|
||||
- gettimeofday(&t, NULL);
|
||||
- prevtime = t.tv_sec * 1000 + t.tv_usec / 1000;
|
||||
- }
|
||||
-
|
||||
for(;;) {
|
||||
struct pollfd pfd;
|
||||
int rv;
|
||||
diff --git a/src/solaris/native/java/net/net_util_md.c b/src/solaris/native/java/net/net_util_md.c
|
||||
--- openjdk/jdk/src/solaris/native/java/net/net_util_md.c
|
||||
+++ openjdk/jdk/src/solaris/native/java/net/net_util_md.c
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <netdb.h>
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
+#include <sys/time.h>
|
||||
|
||||
#ifndef _ALLBSD_SOURCE
|
||||
#include <values.h>
|
||||
@@ -1661,3 +1662,20 @@
|
||||
|
||||
return timeout;
|
||||
}
|
||||
+
|
||||
+#if !defined(__solaris__)
|
||||
+long NET_GetCurrentTime() {
|
||||
+ struct timeval time;
|
||||
+ gettimeofday(&time, NULL);
|
||||
+ return (time.tv_sec * 1000 + time.tv_usec / 1000);
|
||||
+}
|
||||
+
|
||||
+int NET_TimeoutWithCurrentTime(int s, long timeout, long currentTime) {
|
||||
+ return NET_Timeout0(s, timeout, currentTime);
|
||||
+}
|
||||
+
|
||||
+int NET_Timeout(int s, long timeout) {
|
||||
+ long currentTime = (timeout > 0) ? NET_GetCurrentTime() : 0;
|
||||
+ return NET_Timeout0(s, timeout, currentTime);
|
||||
+}
|
||||
+#endif
|
||||
diff --git a/src/solaris/native/java/net/net_util_md.h b/src/solaris/native/java/net/net_util_md.h
|
||||
--- openjdk/jdk/src/solaris/native/java/net/net_util_md.h
|
||||
+++ openjdk/jdk/src/solaris/native/java/net/net_util_md.h
|
||||
@@ -47,9 +47,13 @@
|
||||
close subroutine does not return until the select call returns.
|
||||
...
|
||||
*/
|
||||
-#if defined(__linux__) || defined(MACOSX) || defined (_AIX)
|
||||
+#if !defined(__solaris__)
|
||||
extern int NET_Timeout(int s, long timeout);
|
||||
+extern int NET_Timeout0(int s, long timeout, long currentTime);
|
||||
extern int NET_Read(int s, void* buf, size_t len);
|
||||
+extern int NET_NonBlockingRead(int s, void* buf, size_t len);
|
||||
+extern int NET_TimeoutWithCurrentTime(int s, long timeout, long currentTime);
|
||||
+extern long NET_GetCurrentTime();
|
||||
extern int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
|
||||
struct sockaddr *from, int *fromlen);
|
||||
extern int NET_ReadV(int s, const struct iovec * vector, int count);
|
@ -1,669 +0,0 @@
|
||||
# HG changeset patch
|
||||
# User sgehwolf
|
||||
# Date 1458555849 -3600
|
||||
# Mon Mar 21 11:24:09 2016 +0100
|
||||
# Node ID 9f6a0864a734ae3fd0eb198768db7cdee53ba0ed
|
||||
# Parent 1179be40f1e3b59a890e96a5a9d3ff6fc18a2846
|
||||
8153711, PR3313: [REDO] JDWP: Memory Leak: GlobalRefs never deleted when processing invokeMethod command
|
||||
Summary: Delete global references in invoker_completeInvokeRequest()
|
||||
Reviewed-by: sspitsyn, dsamersoff
|
||||
|
||||
diff --git a/src/share/back/invoker.c b/src/share/back/invoker.c
|
||||
--- openjdk/jdk/src/share/back/invoker.c
|
||||
+++ openjdk/jdk/src/share/back/invoker.c
|
||||
@@ -211,6 +211,62 @@
|
||||
return error;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Delete saved global references - if any - for:
|
||||
+ * - a potentially thrown Exception
|
||||
+ * - a returned refernce/array value
|
||||
+ * See invoker_doInvoke() and invoke* methods where global references
|
||||
+ * are being saved.
|
||||
+ */
|
||||
+static void
|
||||
+deletePotentiallySavedGlobalRefs(JNIEnv *env, InvokeRequest *request)
|
||||
+{
|
||||
+ /* Delete potentially saved return value */
|
||||
+ 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));
|
||||
+ }
|
||||
+ }
|
||||
+ /* Delete potentially saved exception */
|
||||
+ if (request->exception != NULL) {
|
||||
+ tossGlobalRef(env, &(request->exception));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Delete global argument references from the request which got put there before a
|
||||
+ * invoke request was carried out. See fillInvokeRequest().
|
||||
+ */
|
||||
+static void
|
||||
+deleteGlobalArgumentRefs(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);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static jvmtiError
|
||||
fillInvokeRequest(JNIEnv *env, InvokeRequest *request,
|
||||
jbyte invokeType, jbyte options, jint id,
|
||||
@@ -320,6 +376,8 @@
|
||||
invokeConstructor(JNIEnv *env, InvokeRequest *request)
|
||||
{
|
||||
jobject object;
|
||||
+
|
||||
+ JDI_ASSERT_MSG(request->clazz, "Request clazz null");
|
||||
object = JNI_FUNC_PTR(env,NewObjectA)(env, request->clazz,
|
||||
request->method,
|
||||
request->arguments);
|
||||
@@ -336,6 +394,7 @@
|
||||
case JDWP_TAG(OBJECT):
|
||||
case JDWP_TAG(ARRAY): {
|
||||
jobject object;
|
||||
+ JDI_ASSERT_MSG(request->clazz, "Request clazz null");
|
||||
object = JNI_FUNC_PTR(env,CallStaticObjectMethodA)(env,
|
||||
request->clazz,
|
||||
request->method,
|
||||
@@ -424,6 +483,7 @@
|
||||
case JDWP_TAG(OBJECT):
|
||||
case JDWP_TAG(ARRAY): {
|
||||
jobject object;
|
||||
+ JDI_ASSERT_MSG(request->instance, "Request instance null");
|
||||
object = JNI_FUNC_PTR(env,CallObjectMethodA)(env,
|
||||
request->instance,
|
||||
request->method,
|
||||
@@ -511,6 +571,8 @@
|
||||
case JDWP_TAG(OBJECT):
|
||||
case JDWP_TAG(ARRAY): {
|
||||
jobject object;
|
||||
+ JDI_ASSERT_MSG(request->clazz, "Request clazz null");
|
||||
+ JDI_ASSERT_MSG(request->instance, "Request instance null");
|
||||
object = JNI_FUNC_PTR(env,CallNonvirtualObjectMethodA)(env,
|
||||
request->instance,
|
||||
request->clazz,
|
||||
@@ -607,6 +669,8 @@
|
||||
JNIEnv *env;
|
||||
jboolean startNow;
|
||||
InvokeRequest *request;
|
||||
+ jbyte options;
|
||||
+ jbyte invokeType;
|
||||
|
||||
JDI_ASSERT(thread);
|
||||
|
||||
@@ -623,6 +687,9 @@
|
||||
if (startNow) {
|
||||
request->started = JNI_TRUE;
|
||||
}
|
||||
+ options = request->options;
|
||||
+ invokeType = request->invokeType;
|
||||
+
|
||||
debugMonitorExit(invokerLock);
|
||||
|
||||
if (!startNow) {
|
||||
@@ -637,7 +704,7 @@
|
||||
|
||||
JNI_FUNC_PTR(env,ExceptionClear)(env);
|
||||
|
||||
- switch (request->invokeType) {
|
||||
+ switch (invokeType) {
|
||||
case INVOKE_CONSTRUCTOR:
|
||||
invokeConstructor(env, request);
|
||||
break;
|
||||
@@ -645,7 +712,7 @@
|
||||
invokeStatic(env, request);
|
||||
break;
|
||||
case INVOKE_INSTANCE:
|
||||
- if (request->options & JDWP_INVOKE_OPTIONS(NONVIRTUAL) ) {
|
||||
+ if (options & JDWP_INVOKE_OPTIONS(NONVIRTUAL) ) {
|
||||
invokeNonvirtual(env, request);
|
||||
} else {
|
||||
invokeVirtual(env, request);
|
||||
@@ -723,12 +790,23 @@
|
||||
}
|
||||
|
||||
/*
|
||||
+ * 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 deleteGlobalArgumentRefs().
|
||||
+ *
|
||||
+ * We cannot delete saved exception or return value references
|
||||
+ * since otherwise a deleted handle would escape when writing
|
||||
+ * the response to the stream. Instead, we clean those refs up
|
||||
+ * after writing the respone.
|
||||
+ */
|
||||
+ deleteGlobalArgumentRefs(env, request);
|
||||
+
|
||||
+ /*
|
||||
* Give up the lock before I/O operation
|
||||
*/
|
||||
debugMonitorExit(invokerLock);
|
||||
eventHandler_unlock();
|
||||
|
||||
-
|
||||
if (!detached) {
|
||||
outStream_initReply(&out, id);
|
||||
(void)outStream_writeValue(env, &out, tag, returnValue);
|
||||
@@ -736,6 +814,16 @@
|
||||
(void)outStream_writeObjectRef(env, &out, exc);
|
||||
outStream_sendReply(&out);
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * Delete potentially saved global references of return value
|
||||
+ * and exception
|
||||
+ */
|
||||
+ eventHandler_lock(); // for proper lock order
|
||||
+ debugMonitorEnter(invokerLock);
|
||||
+ deletePotentiallySavedGlobalRefs(env, request);
|
||||
+ debugMonitorExit(invokerLock);
|
||||
+ eventHandler_unlock();
|
||||
}
|
||||
|
||||
jboolean
|
||||
diff --git a/test/com/sun/jdi/oom/@debuggeeVMOptions b/test/com/sun/jdi/oom/@debuggeeVMOptions
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ openjdk/jdk/test/com/sun/jdi/oom/@debuggeeVMOptions
|
||||
@@ -0,0 +1,1 @@
|
||||
+-Xmx40m
|
||||
\ No newline at end of file
|
||||
diff --git a/test/com/sun/jdi/oom/OomDebugTest.java b/test/com/sun/jdi/oom/OomDebugTest.java
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ openjdk/jdk/test/com/sun/jdi/oom/OomDebugTest.java
|
||||
@@ -0,0 +1,417 @@
|
||||
+/*
|
||||
+ * 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 8153711
|
||||
+ * @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 shell OomDebugTestSetup.sh
|
||||
+ * @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.io.File;
|
||||
+import java.io.FileInputStream;
|
||||
+import java.io.FileNotFoundException;
|
||||
+import java.io.FileOutputStream;
|
||||
+import java.io.IOException;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Arrays;
|
||||
+import java.util.Collections;
|
||||
+import java.util.HashSet;
|
||||
+import java.util.List;
|
||||
+import java.util.Properties;
|
||||
+import java.util.Set;
|
||||
+
|
||||
+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;
|
||||
+import com.sun.jdi.event.ExceptionEvent;
|
||||
+
|
||||
+/***************** 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 String[] ALL_TESTS = new String[] {
|
||||
+ "test1", "test2", "test3", "test4", "test5"
|
||||
+ };
|
||||
+ private static final Set<String> ALL_TESTS_SET = new HashSet<String>();
|
||||
+ static {
|
||||
+ ALL_TESTS_SET.addAll(Arrays.asList(ALL_TESTS));
|
||||
+ }
|
||||
+ private static final String TEST_CLASSES = System.getProperty("test.classes", ".");
|
||||
+ private static final File RESULT_FILE = new File(TEST_CLASSES, "results.properties");
|
||||
+ private static final String LAST_TEST = ALL_TESTS[ALL_TESTS.length - 1];
|
||||
+ private ReferenceType targetClass;
|
||||
+ private ObjectReference thisObject;
|
||||
+ private int failedTests;
|
||||
+ private final String testMethod;
|
||||
+
|
||||
+ public OomDebugTest(String[] args) {
|
||||
+ super(args);
|
||||
+ if (args.length != 2) {
|
||||
+ throw new RuntimeException("Wrong number of command-line arguments specified.");
|
||||
+ }
|
||||
+ this.testMethod = args[1];
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected void runTests() throws Exception {
|
||||
+ try {
|
||||
+ addListener(new TargetAdapter() {
|
||||
+
|
||||
+ @Override
|
||||
+ public void exceptionThrown(ExceptionEvent event) {
|
||||
+ String name = event.exception().referenceType().name();
|
||||
+ System.err.println("DEBUG: Exception thrown in debuggee was: " + name);
|
||||
+ }
|
||||
+ });
|
||||
+ /*
|
||||
+ * 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();
|
||||
+ }
|
||||
+ /*
|
||||
+ * resume the target, listening for events
|
||||
+ */
|
||||
+ listenUntilVMDisconnect();
|
||||
+ }
|
||||
+
|
||||
+ private java.lang.reflect.Method findTestMethod()
|
||||
+ throws NoSuchMethodException, SecurityException {
|
||||
+ return OomDebugTest.class.getDeclaredMethod(testMethod);
|
||||
+ }
|
||||
+
|
||||
+ 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 test1");
|
||||
+ 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);
|
||||
+ if (objRef.isCollected()) {
|
||||
+ System.out.println("DEBUG: Object got GC'ed before we can use it. NO-OP.");
|
||||
+ continue;
|
||||
+ }
|
||||
+ 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 test2");
|
||||
+ try {
|
||||
+ Field field = targetClass.fieldByName("byteArray");
|
||||
+ ArrayType arrType = (ArrayType)field.type();
|
||||
+
|
||||
+ for (int i = 0; i < 15; i++) {
|
||||
+ ArrayReference byteArrayVal = arrType.newInstance(3000000);
|
||||
+ if (byteArrayVal.isCollected()) {
|
||||
+ System.out.println("DEBUG: Object got GC'ed before we can use it. NO-OP.");
|
||||
+ continue;
|
||||
+ }
|
||||
+ 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 test3");
|
||||
+ 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 test4");
|
||||
+ 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 test5");
|
||||
+ 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 thrown. Trying to determine cause...");
|
||||
+ 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);
|
||||
+ }
|
||||
+
|
||||
+ // Determine the pass/fail status on some heuristic and don't fail the
|
||||
+ // test if < 3 of the total number of tests (currently 5) fail. This also
|
||||
+ // has the nice side effect that all tests are first attempted and only
|
||||
+ // all tests ran an overall pass/fail status is determined.
|
||||
+ private static void determineOverallTestStatus(OomDebugTest oomTest)
|
||||
+ throws IOException, FileNotFoundException {
|
||||
+ Properties resultProps = new Properties();
|
||||
+ if (!RESULT_FILE.exists()) {
|
||||
+ RESULT_FILE.createNewFile();
|
||||
+ }
|
||||
+ FileInputStream fin = null;
|
||||
+ try {
|
||||
+ fin = new FileInputStream(RESULT_FILE);
|
||||
+ resultProps.load(fin);
|
||||
+ resultProps.put(oomTest.testMethod,
|
||||
+ Integer.toString(oomTest.failedTests));
|
||||
+ } finally {
|
||||
+ if (fin != null) {
|
||||
+ fin.close();
|
||||
+ }
|
||||
+ }
|
||||
+ System.out.println("DEBUG: Finished running test '"
|
||||
+ + oomTest.testMethod + "'.");
|
||||
+ if (LAST_TEST.equals(oomTest.testMethod)) {
|
||||
+ System.out.println("DEBUG: Determining overall test status.");
|
||||
+ Set<String> actualTestsRun = new HashSet<String>();
|
||||
+ int totalTests = ALL_TESTS.length;
|
||||
+ int failedTests = 0;
|
||||
+ for (Object key: resultProps.keySet()) {
|
||||
+ actualTestsRun.add((String)key);
|
||||
+ Object propVal = resultProps.get(key);
|
||||
+ int value = Integer.parseInt((String)propVal);
|
||||
+ failedTests += value;
|
||||
+ }
|
||||
+ if (!ALL_TESTS_SET.equals(actualTestsRun)) {
|
||||
+ String errorMsg = "Test failed! Expected to run tests '"
|
||||
+ + ALL_TESTS_SET + "', but only these were run '"
|
||||
+ + actualTestsRun + "'";
|
||||
+ throw new RuntimeException(errorMsg);
|
||||
+ }
|
||||
+ if (failedTests >= 3) {
|
||||
+ String errorMsg = "Test failed. Expected < 3 sub-tests to fail "
|
||||
+ + "for a pass. Got " + failedTests
|
||||
+ + " failed tests out of " + totalTests + ".";
|
||||
+ throw new RuntimeException(errorMsg);
|
||||
+ }
|
||||
+ RESULT_FILE.delete();
|
||||
+ System.out.println("All " + totalTests + " tests passed.");
|
||||
+ } else {
|
||||
+ System.out.println("DEBUG: More tests to run. Continuing.");
|
||||
+ FileOutputStream fout = null;
|
||||
+ try {
|
||||
+ fout = new FileOutputStream(RESULT_FILE);
|
||||
+ resultProps.store(fout, "Storing results after test "
|
||||
+ + oomTest.testMethod);
|
||||
+ } finally {
|
||||
+ if (fout != null) {
|
||||
+ fout.close();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static void main(String[] args) throws Exception {
|
||||
+ System.setProperty("test.vm.opts", "-Xmx40m"); // Set debuggee VM option
|
||||
+ OomDebugTest oomTest = new OomDebugTest(args);
|
||||
+ try {
|
||||
+ oomTest.startTests();
|
||||
+ } catch (Throwable e) {
|
||||
+ System.out.println("DEBUG: Got exception for test run. " + e);
|
||||
+ e.printStackTrace();
|
||||
+ oomTest.failure();
|
||||
+ }
|
||||
+ determineOverallTestStatus(oomTest);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/test/com/sun/jdi/oom/OomDebugTestSetup.sh b/test/com/sun/jdi/oom/OomDebugTestSetup.sh
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ openjdk/jdk/test/com/sun/jdi/oom/OomDebugTestSetup.sh
|
||||
@@ -0,0 +1,46 @@
|
||||
+#!/bin/sh
|
||||
+#
|
||||
+# 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.
|
||||
+#
|
||||
+
|
||||
+
|
||||
+if [ "${TESTSRC}" = "" ]
|
||||
+then
|
||||
+ echo "TESTSRC not set. Test cannot execute. Failed."
|
||||
+ exit 1
|
||||
+fi
|
||||
+echo "TESTSRC=${TESTSRC}"
|
||||
+
|
||||
+if [ "${TESTJAVA}" = "" ]
|
||||
+then
|
||||
+ echo "TESTJAVA not set. Test cannot execute. Failed."
|
||||
+ exit 1
|
||||
+fi
|
||||
+echo "TESTJAVA=${TESTJAVA}"
|
||||
+
|
||||
+if [ "${TESTCLASSES}" = "" ]
|
||||
+then
|
||||
+ echo "TESTCLASSES not set. Test cannot execute. Failed."
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+cp ${TESTSRC}/@debuggeeVMOptions ${TESTCLASSES}/
|
@ -1,54 +0,0 @@
|
||||
# HG changeset patch
|
||||
# User roland
|
||||
# Date 1469615613 -7200
|
||||
# Wed Jul 27 12:33:33 2016 +0200
|
||||
# Node ID fd29eff8b797daa41a68394ced7fe80c9e8c96e9
|
||||
# Parent ee9bffb3bd390b2ad805c7b59d7d2ab8a68a4367
|
||||
8162384, PR3122: Performance regression: bimorphic inlining may be bypassed by type speculation
|
||||
Summary: when speculation fails at a call fallback to profile data at the call site
|
||||
Reviewed-by: kvn
|
||||
|
||||
diff -r ee9bffb3bd39 -r fd29eff8b797 src/share/vm/opto/doCall.cpp
|
||||
--- openjdk/hotspot/src/share/vm/opto/doCall.cpp Mon Aug 01 16:33:54 2016 +0100
|
||||
+++ openjdk/hotspot/src/share/vm/opto/doCall.cpp Wed Jul 27 12:33:33 2016 +0200
|
||||
@@ -205,16 +205,22 @@
|
||||
|
||||
int morphism = profile.morphism();
|
||||
if (speculative_receiver_type != NULL) {
|
||||
- // We have a speculative type, we should be able to resolve
|
||||
- // the call. We do that before looking at the profiling at
|
||||
- // this invoke because it may lead to bimorphic inlining which
|
||||
- // a speculative type should help us avoid.
|
||||
- receiver_method = callee->resolve_invoke(jvms->method()->holder(),
|
||||
- speculative_receiver_type);
|
||||
- if (receiver_method == NULL) {
|
||||
+ if (!too_many_traps(caller, bci, Deoptimization::Reason_speculate_class_check)) {
|
||||
+ // We have a speculative type, we should be able to resolve
|
||||
+ // the call. We do that before looking at the profiling at
|
||||
+ // this invoke because it may lead to bimorphic inlining which
|
||||
+ // a speculative type should help us avoid.
|
||||
+ receiver_method = callee->resolve_invoke(jvms->method()->holder(),
|
||||
+ speculative_receiver_type);
|
||||
+ if (receiver_method == NULL) {
|
||||
+ speculative_receiver_type = NULL;
|
||||
+ } else {
|
||||
+ morphism = 1;
|
||||
+ }
|
||||
+ } else {
|
||||
+ // speculation failed before. Use profiling at the call
|
||||
+ // (could allow bimorphic inlining for instance).
|
||||
speculative_receiver_type = NULL;
|
||||
- } else {
|
||||
- morphism = 1;
|
||||
}
|
||||
}
|
||||
if (receiver_method == NULL &&
|
||||
@@ -252,7 +258,7 @@
|
||||
Deoptimization::Reason_bimorphic :
|
||||
(speculative_receiver_type == NULL ? Deoptimization::Reason_class_check : Deoptimization::Reason_speculate_class_check);
|
||||
if ((morphism == 1 || (morphism == 2 && next_hit_cg != NULL)) &&
|
||||
- !too_many_traps(jvms->method(), jvms->bci(), reason)
|
||||
+ !too_many_traps(caller, bci, reason)
|
||||
) {
|
||||
// Generate uncommon trap for class check failure path
|
||||
// in case of monomorphic or bimorphic virtual call site.
|
@ -1,48 +0,0 @@
|
||||
# HG changeset patch
|
||||
# User jcm
|
||||
# Date 1484137609 28800
|
||||
# Wed Jan 11 04:26:49 2017 -0800
|
||||
# Node ID 1faf7c17089922f6f72b580253725f2ecb6ba2f8
|
||||
# Parent 3d07e14d65bc223dbfe94be9224e4aa8c6e63762
|
||||
8164293, PR3412, RH1459641: HotSpot leaking memory in long-running requests
|
||||
Summary: Applied RMs in sweep_code_cache and related codes.
|
||||
Reviewed-by: kvn, thartmann
|
||||
|
||||
diff --git a/src/share/vm/code/nmethod.cpp b/src/share/vm/code/nmethod.cpp
|
||||
--- openjdk/hotspot/src/share/vm/code/nmethod.cpp
|
||||
+++ openjdk/hotspot/src/share/vm/code/nmethod.cpp
|
||||
@@ -1172,6 +1172,7 @@
|
||||
// Clear ICStubs of all compiled ICs
|
||||
void nmethod::clear_ic_stubs() {
|
||||
assert_locked_or_safepoint(CompiledIC_lock);
|
||||
+ ResourceMark rm;
|
||||
RelocIterator iter(this);
|
||||
while(iter.next()) {
|
||||
if (iter.type() == relocInfo::virtual_call_type) {
|
||||
diff --git a/src/share/vm/runtime/sweeper.cpp b/src/share/vm/runtime/sweeper.cpp
|
||||
--- openjdk/hotspot/src/share/vm/runtime/sweeper.cpp
|
||||
+++ openjdk/hotspot/src/share/vm/runtime/sweeper.cpp
|
||||
@@ -319,6 +319,7 @@
|
||||
}
|
||||
|
||||
void NMethodSweeper::sweep_code_cache() {
|
||||
+ ResourceMark rm;
|
||||
Ticks sweep_start_counter = Ticks::now();
|
||||
|
||||
_flushed_count = 0;
|
||||
@@ -626,6 +627,7 @@
|
||||
// state of the code cache if it's requested.
|
||||
void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) {
|
||||
if (PrintMethodFlushing) {
|
||||
+ ResourceMark rm;
|
||||
stringStream s;
|
||||
// Dump code cache state into a buffer before locking the tty,
|
||||
// because log_state() will use locks causing lock conflicts.
|
||||
@@ -643,6 +645,7 @@
|
||||
}
|
||||
|
||||
if (LogCompilation && (xtty != NULL)) {
|
||||
+ ResourceMark rm;
|
||||
stringStream s;
|
||||
// Dump code cache state into a buffer before locking the tty,
|
||||
// because log_state() will use locks causing lock conflicts.
|
@ -1,77 +0,0 @@
|
||||
# HG changeset patch
|
||||
# User ysuenaga
|
||||
# Date 1487123491 18000
|
||||
# Tue Feb 14 20:51:31 2017 -0500
|
||||
# Node ID 15922b2f31db4857ec84efdf533c41b19e68030b
|
||||
# Parent 652fe741b8f2bfdacba66d772cc89fe7ec6dea66
|
||||
8173941, PR3326: SA does not work if executable is DSO
|
||||
Reviewed-by: aph, dsamersoff
|
||||
|
||||
diff --git a/agent/src/os/linux/elfmacros.h b/agent/src/os/linux/elfmacros.h
|
||||
--- openjdk/hotspot/agent/src/os/linux/elfmacros.h
|
||||
+++ openjdk/hotspot/agent/src/os/linux/elfmacros.h
|
||||
@@ -33,6 +33,7 @@
|
||||
#define ELF_NHDR Elf64_Nhdr
|
||||
#define ELF_DYN Elf64_Dyn
|
||||
#define ELF_ADDR Elf64_Addr
|
||||
+#define ELF_AUXV Elf64_auxv_t
|
||||
|
||||
#define ELF_ST_TYPE ELF64_ST_TYPE
|
||||
|
||||
@@ -45,6 +46,7 @@
|
||||
#define ELF_NHDR Elf32_Nhdr
|
||||
#define ELF_DYN Elf32_Dyn
|
||||
#define ELF_ADDR Elf32_Addr
|
||||
+#define ELF_AUXV Elf32_auxv_t
|
||||
|
||||
#define ELF_ST_TYPE ELF32_ST_TYPE
|
||||
|
||||
diff --git a/agent/src/os/linux/ps_core.c b/agent/src/os/linux/ps_core.c
|
||||
--- openjdk/hotspot/agent/src/os/linux/ps_core.c
|
||||
+++ openjdk/hotspot/agent/src/os/linux/ps_core.c
|
||||
@@ -642,6 +642,18 @@
|
||||
if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true) {
|
||||
return false;
|
||||
}
|
||||
+ } else if (notep->n_type == NT_AUXV) {
|
||||
+ // Get first segment from entry point
|
||||
+ ELF_AUXV *auxv = (ELF_AUXV *)descdata;
|
||||
+ while (auxv->a_type != AT_NULL) {
|
||||
+ if (auxv->a_type == AT_ENTRY) {
|
||||
+ // Set entry point address to address of dynamic section.
|
||||
+ // We will adjust it in read_exec_segments().
|
||||
+ ph->core->dynamic_addr = auxv->a_un.a_val;
|
||||
+ break;
|
||||
+ }
|
||||
+ auxv++;
|
||||
+ }
|
||||
}
|
||||
p = descdata + ROUNDUP(notep->n_descsz, 4);
|
||||
}
|
||||
@@ -826,7 +838,13 @@
|
||||
|
||||
// from PT_DYNAMIC we want to read address of first link_map addr
|
||||
case PT_DYNAMIC: {
|
||||
- ph->core->dynamic_addr = exec_php->p_vaddr;
|
||||
+ if (exec_ehdr->e_type == ET_EXEC) {
|
||||
+ ph->core->dynamic_addr = exec_php->p_vaddr;
|
||||
+ } else { // ET_DYN
|
||||
+ // dynamic_addr has entry point of executable.
|
||||
+ // Thus we should substract it.
|
||||
+ ph->core->dynamic_addr += exec_php->p_vaddr - exec_ehdr->e_entry;
|
||||
+ }
|
||||
print_debug("address of _DYNAMIC is 0x%lx\n", ph->core->dynamic_addr);
|
||||
break;
|
||||
}
|
||||
@@ -1024,8 +1042,9 @@
|
||||
goto err;
|
||||
}
|
||||
|
||||
- if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
|
||||
- print_debug("executable file is not a valid ELF ET_EXEC file\n");
|
||||
+ if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true ||
|
||||
+ ((exec_ehdr.e_type != ET_EXEC) && (exec_ehdr.e_type != ET_DYN))) {
|
||||
+ print_debug("executable file is not a valid ELF file\n");
|
||||
goto err;
|
||||
}
|
||||
|
@ -1,282 +0,0 @@
|
||||
# HG changeset patch
|
||||
# User gromero
|
||||
# Date 1495057954 14400
|
||||
# Wed May 17 17:52:34 2017 -0400
|
||||
# Node ID 74c81011375b5f432df155dcd7b3c9a668b45740
|
||||
# Parent 4d9931ebf8617b1b06adbc1beee6ed1b58661a8b
|
||||
8175813: PPC64: "mbind: Invalid argument" when -XX:+UseNUMA is used
|
||||
|
||||
diff --git a/src/os/linux/vm/os_linux.cpp b/src/os/linux/vm/os_linux.cpp
|
||||
--- openjdk/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
+++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
@@ -2736,8 +2736,9 @@
|
||||
bool os::numa_topology_changed() { return false; }
|
||||
|
||||
size_t os::numa_get_groups_num() {
|
||||
- int max_node = Linux::numa_max_node();
|
||||
- return max_node > 0 ? max_node + 1 : 1;
|
||||
+ // Return just the number of nodes in which it's possible to allocate memory
|
||||
+ // (in numa terminology, configured nodes).
|
||||
+ return Linux::numa_num_configured_nodes();
|
||||
}
|
||||
|
||||
int os::numa_get_group_id() {
|
||||
@@ -2751,11 +2752,33 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int os::Linux::get_existing_num_nodes() {
|
||||
+ size_t node;
|
||||
+ size_t highest_node_number = Linux::numa_max_node();
|
||||
+ int num_nodes = 0;
|
||||
+
|
||||
+ // Get the total number of nodes in the system including nodes without memory.
|
||||
+ for (node = 0; node <= highest_node_number; node++) {
|
||||
+ if (isnode_in_existing_nodes(node)) {
|
||||
+ num_nodes++;
|
||||
+ }
|
||||
+ }
|
||||
+ return num_nodes;
|
||||
+}
|
||||
+
|
||||
size_t os::numa_get_leaf_groups(int *ids, size_t size) {
|
||||
- for (size_t i = 0; i < size; i++) {
|
||||
- ids[i] = i;
|
||||
- }
|
||||
- return size;
|
||||
+ size_t highest_node_number = Linux::numa_max_node();
|
||||
+ size_t i = 0;
|
||||
+
|
||||
+ // Map all node ids in which is possible to allocate memory. Also nodes are
|
||||
+ // not always consecutively available, i.e. available from 0 to the highest
|
||||
+ // node number.
|
||||
+ for (size_t node = 0; node <= highest_node_number; node++) {
|
||||
+ if (Linux::isnode_in_configured_nodes(node)) {
|
||||
+ ids[i++] = node;
|
||||
+ }
|
||||
+ }
|
||||
+ return i;
|
||||
}
|
||||
|
||||
bool os::get_page_info(char *start, page_info* info) {
|
||||
@@ -2825,18 +2848,28 @@
|
||||
libnuma_dlsym(handle, "numa_node_to_cpus")));
|
||||
set_numa_max_node(CAST_TO_FN_PTR(numa_max_node_func_t,
|
||||
libnuma_dlsym(handle, "numa_max_node")));
|
||||
+ set_numa_num_configured_nodes(CAST_TO_FN_PTR(numa_num_configured_nodes_func_t,
|
||||
+ libnuma_dlsym(handle, "numa_num_configured_nodes")));
|
||||
set_numa_available(CAST_TO_FN_PTR(numa_available_func_t,
|
||||
libnuma_dlsym(handle, "numa_available")));
|
||||
set_numa_tonode_memory(CAST_TO_FN_PTR(numa_tonode_memory_func_t,
|
||||
libnuma_dlsym(handle, "numa_tonode_memory")));
|
||||
set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t,
|
||||
- libnuma_dlsym(handle, "numa_interleave_memory")));
|
||||
+ libnuma_dlsym(handle, "numa_interleave_memory")));
|
||||
set_numa_set_bind_policy(CAST_TO_FN_PTR(numa_set_bind_policy_func_t,
|
||||
- libnuma_dlsym(handle, "numa_set_bind_policy")));
|
||||
-
|
||||
+ libnuma_dlsym(handle, "numa_set_bind_policy")));
|
||||
+ set_numa_bitmask_isbitset(CAST_TO_FN_PTR(numa_bitmask_isbitset_func_t,
|
||||
+ libnuma_dlsym(handle, "numa_bitmask_isbitset")));
|
||||
+ set_numa_distance(CAST_TO_FN_PTR(numa_distance_func_t,
|
||||
+ libnuma_dlsym(handle, "numa_distance")));
|
||||
|
||||
if (numa_available() != -1) {
|
||||
set_numa_all_nodes((unsigned long*)libnuma_dlsym(handle, "numa_all_nodes"));
|
||||
+ set_numa_all_nodes_ptr((struct bitmask **)libnuma_dlsym(handle, "numa_all_nodes_ptr"));
|
||||
+ set_numa_nodes_ptr((struct bitmask **)libnuma_dlsym(handle, "numa_nodes_ptr"));
|
||||
+ // Create an index -> node mapping, since nodes are not always consecutive
|
||||
+ _nindex_to_node = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<int>(0, true);
|
||||
+ rebuild_nindex_to_node_map();
|
||||
// Create a cpu -> node mapping
|
||||
_cpu_to_node = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<int>(0, true);
|
||||
rebuild_cpu_to_node_map();
|
||||
@@ -2847,6 +2880,17 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
+void os::Linux::rebuild_nindex_to_node_map() {
|
||||
+ int highest_node_number = Linux::numa_max_node();
|
||||
+
|
||||
+ nindex_to_node()->clear();
|
||||
+ for (int node = 0; node <= highest_node_number; node++) {
|
||||
+ if (Linux::isnode_in_existing_nodes(node)) {
|
||||
+ nindex_to_node()->append(node);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
// rebuild_cpu_to_node_map() constructs a table mapping cpud id to node id.
|
||||
// The table is later used in get_node_by_cpu().
|
||||
void os::Linux::rebuild_cpu_to_node_map() {
|
||||
@@ -2866,16 +2910,46 @@
|
||||
|
||||
cpu_to_node()->clear();
|
||||
cpu_to_node()->at_grow(cpu_num - 1);
|
||||
- size_t node_num = numa_get_groups_num();
|
||||
-
|
||||
+
|
||||
+ size_t node_num = get_existing_num_nodes();
|
||||
+
|
||||
+ int distance = 0;
|
||||
+ int closest_distance = INT_MAX;
|
||||
+ int closest_node = 0;
|
||||
unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size, mtInternal);
|
||||
for (size_t i = 0; i < node_num; i++) {
|
||||
- if (numa_node_to_cpus(i, cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) {
|
||||
+ // Check if node is configured (not a memory-less node). If it is not, find
|
||||
+ // the closest configured node.
|
||||
+ if (!isnode_in_configured_nodes(nindex_to_node()->at(i))) {
|
||||
+ closest_distance = INT_MAX;
|
||||
+ // Check distance from all remaining nodes in the system. Ignore distance
|
||||
+ // from itself and from another non-configured node.
|
||||
+ for (size_t m = 0; m < node_num; m++) {
|
||||
+ if (m != i && isnode_in_configured_nodes(nindex_to_node()->at(m))) {
|
||||
+ distance = numa_distance(nindex_to_node()->at(i), nindex_to_node()->at(m));
|
||||
+ // If a closest node is found, update. There is always at least one
|
||||
+ // configured node in the system so there is always at least one node
|
||||
+ // close.
|
||||
+ if (distance != 0 && distance < closest_distance) {
|
||||
+ closest_distance = distance;
|
||||
+ closest_node = nindex_to_node()->at(m);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ // Current node is already a configured node.
|
||||
+ closest_node = nindex_to_node()->at(i);
|
||||
+ }
|
||||
+
|
||||
+ // Get cpus from the original node and map them to the closest node. If node
|
||||
+ // is a configured node (not a memory-less node), then original node and
|
||||
+ // closest node are the same.
|
||||
+ if (numa_node_to_cpus(nindex_to_node()->at(i), cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) {
|
||||
for (size_t j = 0; j < cpu_map_valid_size; j++) {
|
||||
if (cpu_map[j] != 0) {
|
||||
for (size_t k = 0; k < BitsPerCLong; k++) {
|
||||
if (cpu_map[j] & (1UL << k)) {
|
||||
- cpu_to_node()->at_put(j * BitsPerCLong + k, i);
|
||||
+ cpu_to_node()->at_put(j * BitsPerCLong + k, closest_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2893,14 +2967,20 @@
|
||||
}
|
||||
|
||||
GrowableArray<int>* os::Linux::_cpu_to_node;
|
||||
+GrowableArray<int>* os::Linux::_nindex_to_node;
|
||||
os::Linux::sched_getcpu_func_t os::Linux::_sched_getcpu;
|
||||
os::Linux::numa_node_to_cpus_func_t os::Linux::_numa_node_to_cpus;
|
||||
os::Linux::numa_max_node_func_t os::Linux::_numa_max_node;
|
||||
+os::Linux::numa_num_configured_nodes_func_t os::Linux::_numa_num_configured_nodes;
|
||||
os::Linux::numa_available_func_t os::Linux::_numa_available;
|
||||
os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory;
|
||||
os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory;
|
||||
os::Linux::numa_set_bind_policy_func_t os::Linux::_numa_set_bind_policy;
|
||||
+os::Linux::numa_bitmask_isbitset_func_t os::Linux::_numa_bitmask_isbitset;
|
||||
+os::Linux::numa_distance_func_t os::Linux::_numa_distance;
|
||||
unsigned long* os::Linux::_numa_all_nodes;
|
||||
+struct bitmask* os::Linux::_numa_all_nodes_ptr;
|
||||
+struct bitmask* os::Linux::_numa_nodes_ptr;
|
||||
|
||||
bool os::pd_uncommit_memory(char* addr, size_t size) {
|
||||
uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,
|
||||
diff --git a/src/os/linux/vm/os_linux.hpp b/src/os/linux/vm/os_linux.hpp
|
||||
--- openjdk/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
+++ openjdk/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
@@ -67,6 +67,7 @@
|
||||
static bool _supports_fast_thread_cpu_time;
|
||||
|
||||
static GrowableArray<int>* _cpu_to_node;
|
||||
+ static GrowableArray<int>* _nindex_to_node;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -94,7 +95,9 @@
|
||||
static void set_is_floating_stack() { _is_floating_stack = true; }
|
||||
|
||||
static void rebuild_cpu_to_node_map();
|
||||
+ static void rebuild_nindex_to_node_map();
|
||||
static GrowableArray<int>* cpu_to_node() { return _cpu_to_node; }
|
||||
+ static GrowableArray<int>* nindex_to_node() { return _nindex_to_node; }
|
||||
|
||||
static size_t find_large_page_size();
|
||||
static size_t setup_large_page_size();
|
||||
@@ -243,28 +246,41 @@
|
||||
typedef int (*sched_getcpu_func_t)(void);
|
||||
typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);
|
||||
typedef int (*numa_max_node_func_t)(void);
|
||||
+ typedef int (*numa_num_configured_nodes_func_t)(void);
|
||||
typedef int (*numa_available_func_t)(void);
|
||||
typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node);
|
||||
typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask);
|
||||
typedef void (*numa_set_bind_policy_func_t)(int policy);
|
||||
+ typedef int (*numa_bitmask_isbitset_func_t)(struct bitmask *bmp, unsigned int n);
|
||||
+ typedef int (*numa_distance_func_t)(int node1, int node2);
|
||||
|
||||
static sched_getcpu_func_t _sched_getcpu;
|
||||
static numa_node_to_cpus_func_t _numa_node_to_cpus;
|
||||
static numa_max_node_func_t _numa_max_node;
|
||||
+ static numa_num_configured_nodes_func_t _numa_num_configured_nodes;
|
||||
static numa_available_func_t _numa_available;
|
||||
static numa_tonode_memory_func_t _numa_tonode_memory;
|
||||
static numa_interleave_memory_func_t _numa_interleave_memory;
|
||||
static numa_set_bind_policy_func_t _numa_set_bind_policy;
|
||||
+ static numa_bitmask_isbitset_func_t _numa_bitmask_isbitset;
|
||||
+ static numa_distance_func_t _numa_distance;
|
||||
static unsigned long* _numa_all_nodes;
|
||||
+ static struct bitmask* _numa_all_nodes_ptr;
|
||||
+ static struct bitmask* _numa_nodes_ptr;
|
||||
|
||||
static void set_sched_getcpu(sched_getcpu_func_t func) { _sched_getcpu = func; }
|
||||
static void set_numa_node_to_cpus(numa_node_to_cpus_func_t func) { _numa_node_to_cpus = func; }
|
||||
static void set_numa_max_node(numa_max_node_func_t func) { _numa_max_node = func; }
|
||||
+ static void set_numa_num_configured_nodes(numa_num_configured_nodes_func_t func) { _numa_num_configured_nodes = func; }
|
||||
static void set_numa_available(numa_available_func_t func) { _numa_available = func; }
|
||||
static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; }
|
||||
static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; }
|
||||
static void set_numa_set_bind_policy(numa_set_bind_policy_func_t func) { _numa_set_bind_policy = func; }
|
||||
+ static void set_numa_bitmask_isbitset(numa_bitmask_isbitset_func_t func) { _numa_bitmask_isbitset = func; }
|
||||
+ static void set_numa_distance(numa_distance_func_t func) { _numa_distance = func; }
|
||||
static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; }
|
||||
+ static void set_numa_all_nodes_ptr(struct bitmask **ptr) { _numa_all_nodes_ptr = *ptr; }
|
||||
+ static void set_numa_nodes_ptr(struct bitmask **ptr) { _numa_nodes_ptr = *ptr; }
|
||||
static int sched_getcpu_syscall(void);
|
||||
public:
|
||||
static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; }
|
||||
@@ -272,6 +288,9 @@
|
||||
return _numa_node_to_cpus != NULL ? _numa_node_to_cpus(node, buffer, bufferlen) : -1;
|
||||
}
|
||||
static int numa_max_node() { return _numa_max_node != NULL ? _numa_max_node() : -1; }
|
||||
+ static int numa_num_configured_nodes() {
|
||||
+ return _numa_num_configured_nodes != NULL ? _numa_num_configured_nodes() : -1;
|
||||
+ }
|
||||
static int numa_available() { return _numa_available != NULL ? _numa_available() : -1; }
|
||||
static int numa_tonode_memory(void *start, size_t size, int node) {
|
||||
return _numa_tonode_memory != NULL ? _numa_tonode_memory(start, size, node) : -1;
|
||||
@@ -286,7 +305,25 @@
|
||||
_numa_set_bind_policy(policy);
|
||||
}
|
||||
}
|
||||
+ static int numa_distance(int node1, int node2) {
|
||||
+ return _numa_distance != NULL ? _numa_distance(node1, node2) : -1;
|
||||
+ }
|
||||
static int get_node_by_cpu(int cpu_id);
|
||||
+ static int get_existing_num_nodes();
|
||||
+ // Check if numa node is configured (non-zero memory node).
|
||||
+ static bool isnode_in_configured_nodes(unsigned int n) {
|
||||
+ if (_numa_bitmask_isbitset != NULL && _numa_all_nodes_ptr != NULL) {
|
||||
+ return _numa_bitmask_isbitset(_numa_all_nodes_ptr, n);
|
||||
+ } else
|
||||
+ return 0;
|
||||
+ }
|
||||
+ // Check if numa node exists in the system (including zero memory nodes).
|
||||
+ static bool isnode_in_existing_nodes(unsigned int n) {
|
||||
+ if (_numa_bitmask_isbitset != NULL && _numa_nodes_ptr != NULL) {
|
||||
+ return _numa_bitmask_isbitset(_numa_nodes_ptr, n);
|
||||
+ } else
|
||||
+ return 0;
|
||||
+ }
|
||||
};
|
||||
|
||||
|
@ -963,7 +963,7 @@ URL: http://openjdk.java.net/
|
||||
Source0: %{project}-%{repo}-%{revision}.tar.xz
|
||||
|
||||
# Shenandoah HotSpot
|
||||
Source1: aarch64-port-jdk8u-shenandoah-aarch64-shenandoah-jdk8u151-b12.tar.xz
|
||||
Source1: aarch64-port-jdk8u-shenandoah-aarch64-shenandoah-jdk8u161-b14.tar.xz
|
||||
|
||||
# Custom README for -src subpackage
|
||||
Source2: README.src
|
||||
@ -1075,25 +1075,9 @@ Patch526: 6260348-pr3066.patch
|
||||
# 8061305, PR3335, RH1423421: Javadoc crashes when method name ends with "Property"
|
||||
Patch538: 8061305-pr3335-rh1423421.patch
|
||||
|
||||
# Patches upstream and appearing in 8u151
|
||||
# 8075484, PR3473, RH1490713: SocketInputStream.socketRead0 can hang even with soTimeout set
|
||||
Patch561: 8075484-pr3473-rh1490713.patch
|
||||
|
||||
# Patches upstream and appearing in 8u152
|
||||
# 8153711, PR3313, RH1284948: [REDO] JDWP: Memory Leak: GlobalRefs never deleted when processing invokeMethod command
|
||||
Patch535: 8153711-pr3313-rh1284948.patch
|
||||
# 8162384, PR3122, RH1358661: Performance regression: bimorphic inlining may be bypassed by type speculation
|
||||
Patch532: 8162384-pr3122-rh1358661.patch
|
||||
# 8173941, PR3326: SA does not work if executable is DSO
|
||||
Patch547: 8173941-pr3326.patch
|
||||
# 8175813, PR3394, RH1448880: PPC64: "mbind: Invalid argument" when -XX:+UseNUMA is used
|
||||
Patch550: 8175813-pr3394-rh1448880.patch
|
||||
# 8175887, PR3415: C1 value numbering handling of Unsafe.get*Volatile is incorrect
|
||||
Patch554: 8175887-pr3415.patch
|
||||
|
||||
# Patches upstream and appearing in 8u161
|
||||
# 8164293, PR3412, RH1459641: HotSpot leaking memory in long-running requests
|
||||
Patch555: 8164293-pr3412-rh1459641.patch
|
||||
|
||||
# Patches upstream and appearing in 8u162
|
||||
# 8181055, PR3394, RH1448880: PPC64: "mbind: Invalid argument" still seen after 8175813
|
||||
@ -1507,16 +1491,10 @@ sh %{SOURCE12}
|
||||
%patch523
|
||||
%patch526
|
||||
%patch528
|
||||
%patch532
|
||||
%patch535
|
||||
%patch538
|
||||
%patch547
|
||||
%patch550
|
||||
%patch551
|
||||
%patch553
|
||||
%patch555
|
||||
%patch560
|
||||
%patch561
|
||||
|
||||
# PPC64 updates
|
||||
%patch556
|
||||
@ -2156,7 +2134,14 @@ require "copy_jdk_configs.lua"
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Jan 24 2017 jvanek <jvanek@redhat.com> - 1:1.8.0.161-0.b14
|
||||
* Wed Jan 24 2018 jvanek <jvanek@redhat.com> - 1:1.8.0.161-0.b14
|
||||
- updated to u161, rmeoved upstreamed patches
|
||||
- removed patch555 8164293-pr3412-rh1459641.patch
|
||||
- removed patch550 8175813-pr3394-rh1448880.patch
|
||||
- removed patch547 8173941-pr3326.patch
|
||||
- removed patch532 8162384-pr3122-rh1358661.patch
|
||||
- removed patch535 8153711-pr3313-rh1284948.patch
|
||||
- removed patch561 8075484-pr3473-rh1490713.patch
|
||||
|
||||
* Mon Nov 13 2017 jvanek <jvanek@redhat.com> - 1:1.8.0.151-1.b12
|
||||
- added ownership of etc dirs
|
||||
|
Loading…
Reference in New Issue
Block a user