# HG changeset patch # User andrew # Date 1554840382 -3600 # Tue Apr 09 21:06:22 2019 +0100 # Node ID d2e46b6237304bd9a868269c2d8adde21e27c49a # Parent b666c47935f8eb82d370ef0f315e62dfe1262ceb # Parent 2d94aac71d3337c7c3284bdb101b7ea15ef6d5f5 Merge jdk8u212-b02 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -1344,6 +1344,11 @@ e2c2448a1ca75333879e055655f11525decc2c39 jdk8u201-b08 1e8639cc8075159196f52d1c6a2cf8d250369389 aarch64-shenandoah-jdk8u201-b12 06dccf7653c0a740a6cf607449f5ff7b20369828 aarch64-shenandoah-jdk8u201-b13 +48947e4db9f3b88fd0ec55801e969a3bd6cb74a9 jdk8u201-b09 +bd988b43db1b5ca6ee545097e79ddc5a4c8b5c87 jdk8u201-b79 +b9347a42530a741b7028e0cce47ce0bdd70697a3 jdk8u201-b25 +fb760c9d9649ab7d107b777a41f1424eebfb4883 jdk8u201-b26 +48947e4db9f3b88fd0ec55801e969a3bd6cb74a9 jdk8u201-ga 79b4c0a88c00226dcd14496652adf84d53b5cb9c jdk8u202-b01 9ce27f0a4683a2083d3aed59a40d6a3ccfc8e397 jdk8u202-b02 c0836eee40e5cfc7b3eebbb7a53bfcd98bc66278 jdk8u202-b03 @@ -1352,3 +1357,9 @@ 2fa6434658660b4341be233828362e533782f036 jdk8u202-b06 32c99b1faf57d7ed59e026339a4d7eb8f86b2d83 jdk8u202-b07 68c8235102ca6ddbba63bb7c56f46c17f7badcdb aarch64-shenandoah-jdk8u202-b08 +818b1963f7a227a2368a4f363d5500dd226a529e jdk8u202-b08 +1083b49a881011f43667ebebc280d519f077f9e6 jdk8u202-b25 +7a69774c67cb79a79ccb2ac2d6d258a11e22aa6f jdk8u202-b26 +818b1963f7a227a2368a4f363d5500dd226a529e jdk8u202-ga +9ce27f0a4683a2083d3aed59a40d6a3ccfc8e397 jdk8u212-b00 +9ee244aee077ffad50d1b183a61d9f5fc39a1285 jdk8u212-b01 diff --git a/THIRD_PARTY_README b/THIRD_PARTY_README --- a/THIRD_PARTY_README +++ b/THIRD_PARTY_README @@ -1096,33 +1096,6 @@ OF SUCH DAMAGE. --- end of LICENSE --- -%% This notice is provided with respect to FontConfig 2.5, which may be -included with JRE 8, JDK 8, and OpenJDK 8 source distributions on -Linux and Solaris. - ---- begin of LICENSE --- - -Copyright © 2001,2003 Keith Packard - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that the -above copyright notice appear in all copies and that both that copyright -notice and this permission notice appear in supporting documentation, and that -the name of Keith Packard not be used in advertising or publicity pertaining -to distribution of the software without specific, written prior permission. -Keith Packard makes no representations about the suitability of this software -for any purpose. It is provided "as is" without express or implied warranty. - -KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL KEITH -PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ---- end of LICENSE --- - ------------------------------------------------------------------------------- %% This notice is provided with respect to freebXML Registry 3.0 & 3.1, diff --git a/agent/src/os/linux/libproc_impl.c b/agent/src/os/linux/libproc_impl.c --- a/agent/src/os/linux/libproc_impl.c +++ b/agent/src/os/linux/libproc_impl.c @@ -29,54 +29,51 @@ #include <thread_db.h> #include "libproc_impl.h" -static const char* alt_root = NULL; -static int alt_root_len = -1; - #define SA_ALTROOT "SA_ALTROOT" -static void init_alt_root() { - if (alt_root_len == -1) { - alt_root = getenv(SA_ALTROOT); - if (alt_root) { - alt_root_len = strlen(alt_root); - } else { - alt_root_len = 0; - } - } -} - int pathmap_open(const char* name) { - int fd; - char alt_path[PATH_MAX + 1]; + static const char *alt_root = NULL; + static int alt_root_initialized = 0; - init_alt_root(); + int fd; + char alt_path[PATH_MAX + 1], *alt_path_end; + const char *s; - if (alt_root_len > 0) { - strcpy(alt_path, alt_root); - strcat(alt_path, name); - fd = open(alt_path, O_RDONLY); - if (fd >= 0) { - print_debug("path %s substituted for %s\n", alt_path, name); - return fd; - } + if (!alt_root_initialized) { + alt_root_initialized = -1; + alt_root = getenv(SA_ALTROOT); + } + + if (alt_root == NULL) { + return open(name, O_RDONLY); + } + + strcpy(alt_path, alt_root); + alt_path_end = alt_path + strlen(alt_path); - if (strrchr(name, '/')) { - strcpy(alt_path, alt_root); - strcat(alt_path, strrchr(name, '/')); - fd = open(alt_path, O_RDONLY); - if (fd >= 0) { - print_debug("path %s substituted for %s\n", alt_path, name); - return fd; - } - } - } else { - fd = open(name, O_RDONLY); - if (fd >= 0) { - return fd; - } - } + // Strip path items one by one and try to open file with alt_root prepended + s = name; + while (1) { + strcat(alt_path, s); + s += 1; + + fd = open(alt_path, O_RDONLY); + if (fd >= 0) { + print_debug("path %s substituted for %s\n", alt_path, name); + return fd; + } - return -1; + // Linker always put full path to solib to process, so we can rely + // on presence of /. If slash is not present, it means, that SOlib doesn't + // physically exist (e.g. linux-gate.so) and we fail opening it anyway + if ((s = strchr(s, '/')) == NULL) { + break; + } + + *alt_path_end = 0; + } + + return -1; } static bool _libsaproc_debug; diff --git a/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java b/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java --- a/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java +++ b/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java @@ -113,7 +113,8 @@ private String coreFilename; private void doUsage() { - System.out.println("Usage: java CLHSDB [[pid] | [path-to-java-executable [path-to-corefile]] | help ]"); + // With JDK-8059038 launchers for this class exist. Print usage for those launchers. + System.out.println("Usage: clhsdb [[pid] | [path-to-java-executable [path-to-corefile]] | help | -help ]"); System.out.println(" pid: attach to the process whose id is 'pid'"); System.out.println(" path-to-java-executable: Debug a core file produced by this program"); System.out.println(" path-to-corefile: Debug this corefile. The default is 'core'"); diff --git a/agent/src/share/classes/sun/jvm/hotspot/HSDB.java b/agent/src/share/classes/sun/jvm/hotspot/HSDB.java --- a/agent/src/share/classes/sun/jvm/hotspot/HSDB.java +++ b/agent/src/share/classes/sun/jvm/hotspot/HSDB.java @@ -82,7 +82,8 @@ private String coreFilename; private void doUsage() { - System.out.println("Usage: java HSDB [[pid] | [path-to-java-executable [path-to-corefile]] | help ]"); + // With JDK-8059038 launchers for this class exist. Print usage for those launchers. + System.out.println("Usage: hsdb [[pid] | [path-to-java-executable [path-to-corefile]] | help | -help ]"); System.out.println(" pid: attach to the process whose id is 'pid'"); System.out.println(" path-to-java-executable: Debug a core file produced by this program"); System.out.println(" path-to-corefile: Debug this corefile. The default is 'core'"); diff --git a/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java --- a/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java +++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java @@ -58,31 +58,21 @@ if (pc == null) { return null; } + + /* Typically we have about ten loaded objects here. So no reason to do + sort/binary search here. Linear search gives us acceptable performance.*/ + List objs = getLoadObjectList(); - Object[] arr = objs.toArray(); - // load objects are sorted by base address, do binary search - int mid = -1; - int low = 0; - int high = arr.length - 1; - while (low <= high) { - mid = (low + high) >> 1; - LoadObject midVal = (LoadObject) arr[mid]; - long cmp = pc.minus(midVal.getBase()); - if (cmp < 0) { - high = mid - 1; - } else if (cmp > 0) { - long size = midVal.getSize(); - if (cmp >= size) { - low = mid + 1; - } else { - return (LoadObject) arr[mid]; - } - } else { // match found - return (LoadObject) arr[mid]; - } + for (int i = 0; i < objs.size(); i++) { + LoadObject ob = (LoadObject) objs.get(i); + Address base = ob.getBase(); + long size = ob.getSize(); + if ( pc.greaterThanOrEqual(base) && pc.lessThan(base.addOffsetTo(size))) { + return ob; + } } - // no match found. + return null; } diff --git a/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js b/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js --- a/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js @@ -371,19 +371,23 @@ return sa.dbg.lookup(dso, sym); } -// returns the ClosestSymbol or null -function closestSymbolFor(addr) { - if (sa.cdbg == null) { +function loadObjectContainingPC(addr) { + if (sa.cdbg == null) { // no CDebugger support, return null return null; - } else { - var dso = sa.cdbg.loadObjectContainingPC(addr); - if (dso != null) { - return dso.closestSymbolToPC(addr); - } else { - return null; - } - } + } + + return sa.cdbg.loadObjectContainingPC(addr); +} + +// returns the ClosestSymbol or null +function closestSymbolFor(addr) { + var dso = loadObjectContainingPC(addr); + if (dso != null) { + return dso.closestSymbolToPC(addr); + } + + return null; } // Address-to-symbol @@ -884,21 +888,29 @@ // returns description of given pointer as a String function whatis(addr) { - addr = any2addr(addr); - var ptrLoc = findPtr(addr); - if (ptrLoc.isUnknown()) { - var vmType = vmTypeof(addr); - if (vmType != null) { - return "pointer to " + vmType.name; - } else { - var sym = closestSymbolFor(addr); - if (sym != null) { - return sym.name + '+' + sym.offset; - } else { - return ptrLoc.toString(); - } - } - } else { - return ptrLoc.toString(); - } + addr = any2addr(addr); + var ptrLoc = findPtr(addr); + if (!ptrLoc.isUnknown()) { + return ptrLoc.toString(); + } + + var vmType = vmTypeof(addr); + if (vmType != null) { + return "pointer to " + vmType.name; + } + + var dso = loadObjectContainingPC(addr); + if (dso == null) { + return ptrLoc.toString(); + } + + var sym = dso.closestSymbolToPC(addr); + if (sym != null) { + return sym.name + '+' + sym.offset; + } + + var s = dso.getName(); + var p = s.lastIndexOf("/"); + var base = dso.getBase(); + return s.substring(p+1, s.length) + '+' + addr.minus(base); } diff --git a/make/aix/makefiles/buildtree.make b/make/aix/makefiles/buildtree.make --- a/make/aix/makefiles/buildtree.make +++ b/make/aix/makefiles/buildtree.make @@ -1,6 +1,7 @@ # # Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. # Copyright 2012, 2013 SAP AG. All rights reserved. +# Copyright 2019 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 @@ -215,6 +216,10 @@ echo "SA_BUILD_VERSION = $(HS_BUILD_VER)"; \ echo "HOTSPOT_BUILD_USER = $(HOTSPOT_BUILD_USER)"; \ echo "HOTSPOT_VM_DISTRO = $(HOTSPOT_VM_DISTRO)"; \ + echo "VENDOR = $(COMPANY_NAME)"; \ + echo "VENDOR_URL = $(VENDOR_URL)"; \ + echo "VENDOR_URL_BUG = $(VENDOR_URL_BUG)"; \ + echo "VENDOR_URL_VM_BUG = $(VENDOR_URL_VM_BUG)"; \ echo "OPENJDK = $(OPENJDK)"; \ echo "$(LP64_SETTING/$(DATA_MODE))"; \ echo; \ diff --git a/make/aix/makefiles/vm.make b/make/aix/makefiles/vm.make --- a/make/aix/makefiles/vm.make +++ b/make/aix/makefiles/vm.make @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. # Copyright 2012, 2013 SAP AG. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # @@ -101,7 +101,8 @@ # This is VERY important! The version define must only be supplied to vm_version.o # If not, ccache will not re-use the cache at all, since the version string might contain # a time and date. -CXXFLAGS/vm_version.o += ${JRE_VERSION} +CXXFLAGS/vm_version.o += ${JRE_VERSION} ${VERSION_CFLAGS} +CXXFLAGS/arguments.o += ${VERSION_CFLAGS} CXXFLAGS/BYFILE = $(CXXFLAGS/$@) diff --git a/make/bsd/makefiles/buildtree.make b/make/bsd/makefiles/buildtree.make --- a/make/bsd/makefiles/buildtree.make +++ b/make/bsd/makefiles/buildtree.make @@ -1,5 +1,6 @@ # # Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright 2019 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 @@ -221,6 +222,10 @@ echo "SA_BUILD_VERSION = $(HS_BUILD_VER)"; \ echo "HOTSPOT_BUILD_USER = $(HOTSPOT_BUILD_USER)"; \ echo "HOTSPOT_VM_DISTRO = $(HOTSPOT_VM_DISTRO)"; \ + echo "VENDOR = $(COMPANY_NAME)"; \ + echo "VENDOR_URL = $(VENDOR_URL)"; \ + echo "VENDOR_URL_BUG = $(VENDOR_URL_BUG)"; \ + echo "VENDOR_URL_VM_BUG = $(VENDOR_URL_VM_BUG)"; \ echo "OPENJDK = $(OPENJDK)"; \ echo "$(LP64_SETTING/$(DATA_MODE))"; \ echo; \ diff --git a/make/bsd/makefiles/vm.make b/make/bsd/makefiles/vm.make --- a/make/bsd/makefiles/vm.make +++ b/make/bsd/makefiles/vm.make @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2019, 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 @@ -100,7 +100,8 @@ # This is VERY important! The version define must only be supplied to vm_version.o # If not, ccache will not re-use the cache at all, since the version string might contain # a time and date. -CXXFLAGS/vm_version.o += ${JRE_VERSION} +CXXFLAGS/vm_version.o += ${JRE_VERSION} ${VERSION_CFLAGS} +CXXFLAGS/arguments.o += ${VERSION_CFLAGS} CXXFLAGS/BYFILE = $(CXXFLAGS/$@) diff --git a/make/linux/Makefile b/make/linux/Makefile --- a/make/linux/Makefile +++ b/make/linux/Makefile @@ -227,20 +227,7 @@ @echo " $(TARGETS_SHARK)" @echo " $(TARGETS_MINIMAL1)" -checks: check_os_version check_j2se_version - -# We do not want people accidentally building on old systems (e.g. Linux 2.2.x, -# Solaris 2.5.1, 2.6). -# Disable this check by setting DISABLE_HOTSPOT_OS_VERSION_CHECK=ok. - -SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 3% 4% -OS_VERSION := $(shell uname -r) -EMPTY_IF_NOT_SUPPORTED = $(filter $(SUPPORTED_OS_VERSION),$(OS_VERSION)) - -check_os_version: -ifeq ($(DISABLE_HOTSPOT_OS_VERSION_CHECK)$(EMPTY_IF_NOT_SUPPORTED),) - $(QUIETLY) >&2 echo "*** This OS is not supported:" `uname -a`; exit 1; -endif +checks: check_j2se_version # jvmti.make requires XSLT (J2SE 1.4.x or newer): XSLT_CHECK = $(REMOTE) $(RUN.JAVAP) javax.xml.transform.TransformerFactory diff --git a/make/linux/makefiles/buildtree.make b/make/linux/makefiles/buildtree.make --- a/make/linux/makefiles/buildtree.make +++ b/make/linux/makefiles/buildtree.make @@ -1,5 +1,6 @@ # # Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright 2019 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 @@ -221,6 +222,10 @@ echo "SA_BUILD_VERSION = $(HS_BUILD_VER)"; \ echo "HOTSPOT_BUILD_USER = $(HOTSPOT_BUILD_USER)"; \ echo "HOTSPOT_VM_DISTRO = $(HOTSPOT_VM_DISTRO)"; \ + echo "VENDOR = $(COMPANY_NAME)"; \ + echo "VENDOR_URL = $(VENDOR_URL)"; \ + echo "VENDOR_URL_BUG = $(VENDOR_URL_BUG)"; \ + echo "VENDOR_URL_VM_BUG = $(VENDOR_URL_VM_BUG)"; \ echo "OPENJDK = $(OPENJDK)"; \ echo "$(LP64_SETTING/$(DATA_MODE))"; \ echo; \ diff --git a/make/linux/makefiles/saproc.make b/make/linux/makefiles/saproc.make --- a/make/linux/makefiles/saproc.make +++ b/make/linux/makefiles/saproc.make @@ -59,6 +59,11 @@ SA_DEBUG_CFLAGS = -g endif +# Optimize saproc lib at level -O3 unless it's a slowdebug build +ifneq ($(BUILD_FLAVOR), debug) + SA_OPT_FLAGS = $(OPT_CFLAGS) +endif + # if $(AGENT_DIR) does not exist, we don't build SA # also, we don't build SA on Itanium or zero. @@ -95,6 +100,7 @@ $(SASRCFILES) \ $(SA_LFLAGS) \ $(SA_DEBUG_CFLAGS) \ + $(SA_OPT_FLAGS) \ $(EXTRA_CFLAGS) \ -o $@ \ -lthread_db -ldl diff --git a/make/linux/makefiles/vm.make b/make/linux/makefiles/vm.make --- a/make/linux/makefiles/vm.make +++ b/make/linux/makefiles/vm.make @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2019, 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 @@ -102,7 +102,8 @@ # This is VERY important! The version define must only be supplied to vm_version.o # If not, ccache will not re-use the cache at all, since the version string might contain # a time and date. -CXXFLAGS/vm_version.o += ${JRE_VERSION} +CXXFLAGS/vm_version.o += ${JRE_VERSION} ${VERSION_CFLAGS} +CXXFLAGS/arguments.o += ${VERSION_CFLAGS} CXXFLAGS/BYFILE = $(CXXFLAGS/$@) diff --git a/make/openjdk_distro b/make/openjdk_distro --- a/make/openjdk_distro +++ b/make/openjdk_distro @@ -1,5 +1,6 @@ # # Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. +# Copyright 2019 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 @@ -28,5 +29,4 @@ # Don't put quotes (fail windows build). HOTSPOT_VM_DISTRO=OpenJDK -COMPANY_NAME= PRODUCT_NAME=OpenJDK diff --git a/make/solaris/makefiles/buildtree.make b/make/solaris/makefiles/buildtree.make --- a/make/solaris/makefiles/buildtree.make +++ b/make/solaris/makefiles/buildtree.make @@ -1,5 +1,6 @@ # # Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright 2019 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 @@ -208,6 +209,10 @@ echo "SA_BUILD_VERSION = $(HS_BUILD_VER)"; \ echo "HOTSPOT_BUILD_USER = $(HOTSPOT_BUILD_USER)"; \ echo "HOTSPOT_VM_DISTRO = $(HOTSPOT_VM_DISTRO)"; \ + echo "VENDOR = $(COMPANY_NAME)"; \ + echo "VENDOR_URL = $(VENDOR_URL)"; \ + echo "VENDOR_URL_BUG = $(VENDOR_URL_BUG)"; \ + echo "VENDOR_URL_VM_BUG = $(VENDOR_URL_VM_BUG)"; \ echo "OPENJDK = $(OPENJDK)"; \ echo "$(LP64_SETTING/$(DATA_MODE))"; \ echo; \ diff --git a/make/solaris/makefiles/vm.make b/make/solaris/makefiles/vm.make --- a/make/solaris/makefiles/vm.make +++ b/make/solaris/makefiles/vm.make @@ -1,5 +1,5 @@ # -# Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2019, 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 @@ -88,7 +88,8 @@ # This is VERY important! The version define must only be supplied to vm_version.o # If not, ccache will not re-use the cache at all, since the version string might contain # a time and date. -CXXFLAGS/vm_version.o += ${JRE_VERSION} +CXXFLAGS/vm_version.o += ${JRE_VERSION} ${VERSION_CFLAGS} +CXXFLAGS/arguments.o += ${VERSION_CFLAGS} CXXFLAGS/BYFILE = $(CXXFLAGS/$@) diff --git a/make/windows/build.make b/make/windows/build.make --- a/make/windows/build.make +++ b/make/windows/build.make @@ -1,5 +1,6 @@ # # Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright 2019 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 @@ -279,6 +280,10 @@ @ echo HS_COMPANY=$(COMPANY_NAME) >> $@ @ echo HS_FILEDESC=$(HS_FILEDESC) >> $@ @ echo HOTSPOT_VM_DISTRO=$(HOTSPOT_VM_DISTRO) >> $@ + @ echo VENDOR=$(VENDOR) >> $@ + @ echo VENDOR_URL=$(VENDOR_URL) >> $@ + @ echo VENDOR_URL_BUG=$(VENDOR_URL_BUG) >> $@ + @ echo VENDOR_URL_VM_BUG=$(VENDOR_URL_VM_BUG) >> $@ @ if "$(OPENJDK)" NEQ "" echo OPENJDK=$(OPENJDK) >> $@ @ echo HS_COPYRIGHT=$(HOTSPOT_VM_COPYRIGHT) >> $@ @ echo HS_NAME=$(PRODUCT_NAME) $(JDK_MKTG_VERSION) >> $@ diff --git a/make/windows/makefiles/sa.make b/make/windows/makefiles/sa.make --- a/make/windows/makefiles/sa.make +++ b/make/windows/makefiles/sa.make @@ -99,27 +99,38 @@ checkAndBuildSA:: $(SAWINDBG) -# These do not need to be optimized (don't run a lot of code) and it -# will be useful to have the assertion checks in place +!if "$(BUILD_FLAVOR)" == "debug" +SA_EXTRA_CFLAGS = -Od -D "_DEBUG" +!if "$(BUILDARCH)" == "i486" +SA_EXTRA_CFLAGS = $(SA_EXTRA_CFLAGS) -RTC1 +!endif +!elseif "$(BUILD_FLAVOR)" == "fastdebug" +SA_EXTRA_CFLAGS = -O2 -D "_DEBUG" +!else +SA_EXTRA_CFLAGS = -O2 +!endif !if "$(BUILDARCH)" == "ia64" -SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -Od -D "WIN32" -D "WIN64" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -YX -FD -c +SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -D "WIN32" -D "WIN64" -D "_WINDOWS" -D "_CONSOLE" -D "_MBCS" -YX -FD -c !elseif "$(BUILDARCH)" == "amd64" -SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -Od -D "WIN32" -D "WIN64" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -YX -FD -c +SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -D "WIN32" -D "WIN64" -D "_WINDOWS" -D "_CONSOLE" -D "_MBCS" -YX -FD -c !if "$(COMPILER_NAME)" == "VS2005" # On amd64, VS2005 compiler requires bufferoverflowU.lib on the link command line, # otherwise we get missing __security_check_cookie externals at link time. SA_LD_FLAGS = bufferoverflowU.lib !endif !else -SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 -Gm $(GX_OPTION) -Od -D "WIN32" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -YX -FD -GZ -c +SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 -Gm $(GX_OPTION) -D "WIN32" -D "_WINDOWS" -D "_CONSOLE" -D "_MBCS" -YX -FD -c !if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1" -SA_CFLAGS = $(SA_CFLAGS) -ZI +# -ZI is incompatible with -O2 used for release/fastdebug builds. +# Using -Zi instead. +SA_CFLAGS = $(SA_CFLAGS) -Zi !endif !endif !if "$(MT)" != "" SA_LD_FLAGS = -manifest $(SA_LD_FLAGS) !endif +SA_CFLAGS = $(SA_CFLAGS) $(SA_EXTRA_CFLAGS) SASRCFILES = $(AGENT_DIR)/src/os/win32/windbg/sawindbg.cpp \ $(AGENT_DIR)/src/share/native/sadis.c diff --git a/make/windows/makefiles/vm.make b/make/windows/makefiles/vm.make --- a/make/windows/makefiles/vm.make +++ b/make/windows/makefiles/vm.make @@ -1,5 +1,6 @@ # # Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright 2019 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 @@ -61,6 +62,10 @@ CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_BUILD_TARGET=\"$(BUILD_FLAVOR)\"" CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_BUILD_USER=\"$(BuildUser)\"" CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_VM_DISTRO=\"$(HOTSPOT_VM_DISTRO)\"" +CXX_FLAGS=$(CXX_FLAGS) /D "VENDOR=\"$(COMPANY_NAME)\"" +CXX_FLAGS=$(CXX_FLAGS) /D "VENDOR_URL=\"$(VENDOR_URL)\"" +CXX_FLAGS=$(CXX_FLAGS) /D "VENDOR_URL_BUG=\"$(VENDOR_URL_BUG)\"" +CXX_FLAGS=$(CXX_FLAGS) /D "VENDOR_URL_VM_BUG=\"$(VENDOR_URL_VM_BUG)\"" CXX_FLAGS=$(CXX_FLAGS) $(CXX_INCLUDE_DIRS) diff --git a/src/cpu/ppc/vm/assembler_ppc.hpp b/src/cpu/ppc/vm/assembler_ppc.hpp --- a/src/cpu/ppc/vm/assembler_ppc.hpp +++ b/src/cpu/ppc/vm/assembler_ppc.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012, 2013 SAP AG. All rights reserved. + * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, SAP SE. 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 @@ -1838,7 +1838,7 @@ inline void vperm( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c); inline void vsel( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c); inline void vsl( VectorRegister d, VectorRegister a, VectorRegister b); - inline void vsldoi( VectorRegister d, VectorRegister a, VectorRegister b, int si4); + inline void vsldoi( VectorRegister d, VectorRegister a, VectorRegister b, int ui4); inline void vslo( VectorRegister d, VectorRegister a, VectorRegister b); inline void vsr( VectorRegister d, VectorRegister a, VectorRegister b); inline void vsro( VectorRegister d, VectorRegister a, VectorRegister b); diff --git a/src/cpu/ppc/vm/assembler_ppc.inline.hpp b/src/cpu/ppc/vm/assembler_ppc.inline.hpp --- a/src/cpu/ppc/vm/assembler_ppc.inline.hpp +++ b/src/cpu/ppc/vm/assembler_ppc.inline.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012, 2014 SAP AG. All rights reserved. + * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, SAP SE. 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 @@ -657,7 +657,7 @@ inline void Assembler::vperm( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c){ emit_int32( VPERM_OPCODE | vrt(d) | vra(a) | vrb(b) | vrc(c)); } inline void Assembler::vsel( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c){ emit_int32( VSEL_OPCODE | vrt(d) | vra(a) | vrb(b) | vrc(c)); } inline void Assembler::vsl( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSL_OPCODE | vrt(d) | vra(a) | vrb(b)); } -inline void Assembler::vsldoi( VectorRegister d, VectorRegister a, VectorRegister b, int si4) { emit_int32( VSLDOI_OPCODE| vrt(d) | vra(a) | vrb(b) | vsldoi_shb(simm(si4,4))); } +inline void Assembler::vsldoi( VectorRegister d, VectorRegister a, VectorRegister b, int ui4) { emit_int32( VSLDOI_OPCODE| vrt(d) | vra(a) | vrb(b) | vsldoi_shb(uimm(ui4,4))); } inline void Assembler::vslo( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSLO_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vsr( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSR_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vsro( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSRO_OPCODE | vrt(d) | vra(a) | vrb(b)); } diff --git a/src/cpu/ppc/vm/macroAssembler_ppc.cpp b/src/cpu/ppc/vm/macroAssembler_ppc.cpp --- a/src/cpu/ppc/vm/macroAssembler_ppc.cpp +++ b/src/cpu/ppc/vm/macroAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012, 2017 SAP AG. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, SAP SE. 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 @@ -3570,12 +3570,12 @@ vspltisw(VR0, -1); vsldoi(mask_32bit, zeroes, VR0, 4); - vsldoi(mask_64bit, zeroes, VR0, -8); + vsldoi(mask_64bit, zeroes, VR0, 8); // Get the initial value into v8 vxor(VR8, VR8, VR8); mtvrd(VR8, crc); - vsldoi(VR8, zeroes, VR8, -8); // shift into bottom 32 bits + vsldoi(VR8, zeroes, VR8, 8); // shift into bottom 32 bits li (rLoaded, 0); @@ -3924,7 +3924,7 @@ addi(barretConstants, barretConstants, 16); lvx(const2, barretConstants); - vsldoi(VR1, VR0, VR0, -8); + vsldoi(VR1, VR0, VR0, 8); vxor(VR0, VR0, VR1); // xor two 64 bit results together // shift left one bit diff --git a/src/cpu/ppc/vm/stubGenerator_ppc.cpp b/src/cpu/ppc/vm/stubGenerator_ppc.cpp --- a/src/cpu/ppc/vm/stubGenerator_ppc.cpp +++ b/src/cpu/ppc/vm/stubGenerator_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012, 2014 SAP AG. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, SAP SE. 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 @@ -2023,7 +2023,7 @@ __ vspltisb (vTmp2, -16); __ vrld (keyPerm, keyPerm, vTmp2); __ vrld (keyPerm, keyPerm, vTmp2); - __ vsldoi (keyPerm, keyPerm, keyPerm, -8); + __ vsldoi (keyPerm, keyPerm, keyPerm, 8); // load the 1st round key to vKey1 __ li (keypos, 0); @@ -2223,7 +2223,7 @@ __ vspltisb (vTmp2, -16); __ vrld (keyPerm, keyPerm, vTmp2); __ vrld (keyPerm, keyPerm, vTmp2); - __ vsldoi (keyPerm, keyPerm, keyPerm, -8); + __ vsldoi (keyPerm, keyPerm, keyPerm, 8); __ cmpwi (CCR0, keylen, 44); __ beq (CCR0, L_do44); diff --git a/src/cpu/ppc/vm/templateInterpreter_ppc.hpp b/src/cpu/ppc/vm/templateInterpreter_ppc.hpp --- a/src/cpu/ppc/vm/templateInterpreter_ppc.hpp +++ b/src/cpu/ppc/vm/templateInterpreter_ppc.hpp @@ -34,7 +34,7 @@ // Run with +PrintInterpreter to get the VM to print out the size. // Max size with JVMTI - const static int InterpreterCodeSize = 210*K; + const static int InterpreterCodeSize = 220*K; #endif // CPU_PPC_VM_TEMPLATEINTERPRETER_PPC_HPP diff --git a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @@ -579,7 +579,7 @@ __ and3(Rscratch, divisor - 1, Rscratch); } __ add(Rdividend, Rscratch, Rscratch); - __ sra(Rscratch, log2_intptr(divisor), Rresult); + __ sra(Rscratch, log2_int(divisor), Rresult); return; } else { if (divisor == 2) { diff --git a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp --- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp +++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp @@ -294,11 +294,11 @@ bool LIRGenerator::strength_reduce_multiply(LIR_Opr left, int c, LIR_Opr result, LIR_Opr tmp) { assert(left != result, "should be different registers"); if (is_power_of_2(c + 1)) { - __ shift_left(left, log2_intptr(c + 1), result); + __ shift_left(left, log2_int(c + 1), result); __ sub(result, left, result); return true; } else if (is_power_of_2(c - 1)) { - __ shift_left(left, log2_intptr(c - 1), result); + __ shift_left(left, log2_int(c - 1), result); __ add(result, left, result); return true; } diff --git a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -2695,7 +2695,7 @@ Register dreg = result->as_register(); if (right->is_constant()) { - int divisor = right->as_constant_ptr()->as_jint(); + jint divisor = right->as_constant_ptr()->as_jint(); assert(divisor > 0 && is_power_of_2(divisor), "must be"); if (code == lir_idiv) { assert(lreg == rax, "must be rax,"); @@ -2707,7 +2707,7 @@ __ andl(rdx, divisor - 1); __ addl(lreg, rdx); } - __ sarl(lreg, log2_intptr(divisor)); + __ sarl(lreg, log2_jint(divisor)); move_regs(lreg, dreg); } else if (code == lir_irem) { Label done; diff --git a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @@ -237,12 +237,12 @@ if (tmp->is_valid()) { if (is_power_of_2(c + 1)) { __ move(left, tmp); - __ shift_left(left, log2_intptr(c + 1), left); + __ shift_left(left, log2_jint(c + 1), left); __ sub(left, tmp, result); return true; } else if (is_power_of_2(c - 1)) { __ move(left, tmp); - __ shift_left(left, log2_intptr(c - 1), left); + __ shift_left(left, log2_jint(c - 1), left); __ add(left, tmp, result); return true; } diff --git a/src/cpu/x86/vm/interp_masm_x86_32.cpp b/src/cpu/x86/vm/interp_masm_x86_32.cpp --- a/src/cpu/x86/vm/interp_masm_x86_32.cpp +++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, 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 @@ -1445,5 +1445,7 @@ incrementl(scratch, increment); movl(counter_addr, scratch); andl(scratch, mask); - jcc(cond, *where); + if (where != NULL) { + jcc(cond, *where); + } } diff --git a/src/cpu/x86/vm/interp_masm_x86_64.cpp b/src/cpu/x86/vm/interp_masm_x86_64.cpp --- a/src/cpu/x86/vm/interp_masm_x86_64.cpp +++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2018, 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 @@ -1507,5 +1507,7 @@ incrementl(scratch, increment); movl(counter_addr, scratch); andl(scratch, mask); - jcc(cond, *where); + if (where != NULL) { + jcc(cond, *where); + } } diff --git a/src/cpu/x86/vm/templateTable_x86_32.cpp b/src/cpu/x86/vm/templateTable_x86_32.cpp --- a/src/cpu/x86/vm/templateTable_x86_32.cpp +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, 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 @@ -1640,15 +1640,16 @@ // Increment the MDO backedge counter const Address mdo_backedge_counter(rbx, in_bytes(MethodData::backedge_counter_offset()) + in_bytes(InvocationCounter::counter_offset())); - __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, - rax, false, Assembler::zero, &backedge_counter_overflow); + __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, rax, false, Assembler::zero, + UseOnStackReplacement ? &backedge_counter_overflow : NULL); __ jmp(dispatch); } __ bind(no_mdo); // Increment backedge counter in MethodCounters* __ movptr(rcx, Address(rcx, Method::method_counters_offset())); __ increment_mask_and_jump(Address(rcx, be_offset), increment, mask, - rax, false, Assembler::zero, &backedge_counter_overflow); + rax, false, Assembler::zero, + UseOnStackReplacement ? &backedge_counter_overflow : NULL); } else { // increment counter __ movptr(rcx, Address(rcx, Method::method_counters_offset())); diff --git a/src/cpu/x86/vm/templateTable_x86_64.cpp b/src/cpu/x86/vm/templateTable_x86_64.cpp --- a/src/cpu/x86/vm/templateTable_x86_64.cpp +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2018, 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 @@ -1686,15 +1686,16 @@ // Increment the MDO backedge counter const Address mdo_backedge_counter(rbx, in_bytes(MethodData::backedge_counter_offset()) + in_bytes(InvocationCounter::counter_offset())); - __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, - rax, false, Assembler::zero, &backedge_counter_overflow); + __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, rax, false, Assembler::zero, + UseOnStackReplacement ? &backedge_counter_overflow : NULL); __ jmp(dispatch); } __ bind(no_mdo); // Increment backedge counter in MethodCounters* __ movptr(rcx, Address(rcx, Method::method_counters_offset())); __ increment_mask_and_jump(Address(rcx, be_offset), increment, mask, - rax, false, Assembler::zero, &backedge_counter_overflow); + rax, false, Assembler::zero, + UseOnStackReplacement ? &backedge_counter_overflow : NULL); } else { // increment counter __ movptr(rcx, Address(rcx, Method::method_counters_offset())); diff --git a/src/os/aix/vm/os_aix.cpp b/src/os/aix/vm/os_aix.cpp --- a/src/os/aix/vm/os_aix.cpp +++ b/src/os/aix/vm/os_aix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright 2012, 2014 SAP AG. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -5142,7 +5142,7 @@ // or -1 on failure (e.g. can't fork a new process). // Unlike system(), this function can be called from signal handler. It // doesn't block SIGINT et al. -int os::fork_and_exec(char* cmd) { +int os::fork_and_exec(char* cmd, bool use_vfork_if_available) { char * argv[4] = {"sh", "-c", cmd, NULL}; pid_t pid = fork(); diff --git a/src/os/bsd/vm/os_bsd.cpp b/src/os/bsd/vm/os_bsd.cpp --- a/src/os/bsd/vm/os_bsd.cpp +++ b/src/os/bsd/vm/os_bsd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2019, 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 @@ -4716,7 +4716,7 @@ // or -1 on failure (e.g. can't fork a new process). // Unlike system(), this function can be called from signal handler. It // doesn't block SIGINT et al. -int os::fork_and_exec(char* cmd) { +int os::fork_and_exec(char* cmd, bool use_vfork_if_available) { const char * argv[4] = {"sh", "-c", cmd, NULL}; // fork() in BsdThreads/NPTL is not async-safe. It needs to run diff --git a/src/os/linux/vm/os_linux.cpp b/src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp +++ b/src/os/linux/vm/os_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2019, 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 @@ -724,6 +724,10 @@ } } +void os::Linux::expand_stack_to(address bottom) { + _expand_stack_to(bottom); +} + bool os::Linux::manually_expand_stack(JavaThread * t, address addr) { assert(t!=NULL, "just checking"); assert(t->osthread()->expanding_stack(), "expand should be set"); @@ -6344,10 +6348,16 @@ // or -1 on failure (e.g. can't fork a new process). // Unlike system(), this function can be called from signal handler. It // doesn't block SIGINT et al. -int os::fork_and_exec(char* cmd) { +int os::fork_and_exec(char* cmd, bool use_vfork_if_available) { const char * argv[4] = {"sh", "-c", cmd, NULL}; - pid_t pid = fork(); + pid_t pid ; + + if (use_vfork_if_available) { + pid = vfork(); + } else { + pid = fork(); + } if (pid < 0) { // fork failed diff --git a/src/os/linux/vm/os_linux.hpp b/src/os/linux/vm/os_linux.hpp --- a/src/os/linux/vm/os_linux.hpp +++ b/src/os/linux/vm/os_linux.hpp @@ -249,6 +249,8 @@ static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime); private: + static void expand_stack_to(address bottom); + 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); diff --git a/src/os/posix/vm/os_posix.cpp b/src/os/posix/vm/os_posix.cpp --- a/src/os/posix/vm/os_posix.cpp +++ b/src/os/posix/vm/os_posix.cpp @@ -604,7 +604,11 @@ strncpy(buffer, "none", size); const struct { - int i; + // NB: i is an unsigned int here because SA_RESETHAND is on some + // systems 0x80000000, which is implicitly unsigned. Assignining + // it to an int field would be an overflow in unsigned-to-signed + // conversion. + unsigned int i; const char* s; } flaginfo [] = { { SA_NOCLDSTOP, "SA_NOCLDSTOP" }, diff --git a/src/os/solaris/vm/os_solaris.cpp b/src/os/solaris/vm/os_solaris.cpp --- a/src/os/solaris/vm/os_solaris.cpp +++ b/src/os/solaris/vm/os_solaris.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, 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 @@ -6153,7 +6153,7 @@ // or -1 on failure (e.g. can't fork a new process). // Unlike system(), this function can be called from signal handler. It // doesn't block SIGINT et al. -int os::fork_and_exec(char* cmd) { +int os::fork_and_exec(char* cmd, bool use_vfork_if_available) { char * argv[4]; argv[0] = (char *)"sh"; argv[1] = (char *)"-c"; diff --git a/src/os/windows/vm/os_windows.cpp b/src/os/windows/vm/os_windows.cpp --- a/src/os/windows/vm/os_windows.cpp +++ b/src/os/windows/vm/os_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, 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 @@ -1757,7 +1757,13 @@ if (is_workstation) { st->print("10"); } else { - st->print("Server 2016"); + // distinguish Windows Server 2016 and 2019 by build number + // Windows server 2019 GA 10/2018 build number is 17763 + if (build_number > 17762) { + st->print("Server 2019"); + } else { + st->print("Server 2016"); + } } break; @@ -5034,7 +5040,7 @@ // Run the specified command in a separate process. Return its exit value, // or -1 on failure (e.g. can't create a new process). -int os::fork_and_exec(char* cmd) { +int os::fork_and_exec(char* cmd, bool use_vfork_if_available) { STARTUPINFO si; PROCESS_INFORMATION pi; diff --git a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp --- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp @@ -892,6 +892,27 @@ void os::workaround_expand_exec_shield_cs_limit() { #if defined(IA32) size_t page_size = os::vm_page_size(); + + /* + * JDK-8197429 + * + * Expand the stack mapping to the end of the initial stack before + * attempting to install the codebuf. This is needed because newer + * Linux kernels impose a distance of a megabyte between stack + * memory and other memory regions. If we try to install the + * codebuf before expanding the stack the installation will appear + * to succeed but we'll get a segfault later if we expand the stack + * in Java code. + * + */ + if (os::is_primordial_thread()) { + address limit = Linux::initial_thread_stack_bottom(); + if (! DisablePrimordialThreadGuardPages) { + limit += (StackYellowPages + StackRedPages) * page_size; + } + os::Linux::expand_stack_to(limit); + } + /* * Take the highest VA the OS will give us and exec * @@ -910,6 +931,16 @@ char* hint = (char*) (Linux::initial_thread_stack_bottom() - ((StackYellowPages + StackRedPages + 1) * page_size)); char* codebuf = os::attempt_reserve_memory_at(page_size, hint); + + if (codebuf == NULL) { + // JDK-8197429: There may be a stack gap of one megabyte between + // the limit of the stack and the nearest memory region: this is a + // Linux kernel workaround for CVE-2017-1000364. If we failed to + // map our codebuf, try again at an address one megabyte lower. + hint -= 1 * M; + codebuf = os::attempt_reserve_memory_at(page_size, hint); + } + if ( (codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true)) ) { return; // No matter, we tried, best effort. } diff --git a/src/share/vm/adlc/adlparse.cpp b/src/share/vm/adlc/adlparse.cpp --- a/src/share/vm/adlc/adlparse.cpp +++ b/src/share/vm/adlc/adlparse.cpp @@ -2868,7 +2868,8 @@ const char* param = NULL; inst._parameters.reset(); while ((param = inst._parameters.iter()) != NULL) { - OperandForm* opForm = (OperandForm*) inst._localNames[param]; + OpClassForm* opForm = inst._localNames[param]->is_opclass(); + assert(opForm != NULL, "sanity"); encoding->add_parameter(opForm->_ident, param); } @@ -3338,7 +3339,8 @@ const char* param = NULL; inst._parameters.reset(); while ((param = inst._parameters.iter()) != NULL) { - OperandForm* opForm = (OperandForm*) inst._localNames[param]; + OpClassForm* opForm = inst._localNames[param]->is_opclass(); + assert(opForm != NULL, "sanity"); encoding->add_parameter(opForm->_ident, param); } diff --git a/src/share/vm/adlc/dfa.cpp b/src/share/vm/adlc/dfa.cpp --- a/src/share/vm/adlc/dfa.cpp +++ b/src/share/vm/adlc/dfa.cpp @@ -757,19 +757,27 @@ } int Expr::compute_min(const Expr *c1, const Expr *c2) { - int result = c1->_min_value + c2->_min_value; - assert( result >= 0, "Invalid cost computation"); + int v1 = c1->_min_value; + int v2 = c2->_min_value; + assert(0 <= v2 && v2 <= Expr::Max, "sanity"); + assert(v1 <= Expr::Max - v2, "Invalid cost computation"); - return result; + return v1 + v2; } + int Expr::compute_max(const Expr *c1, const Expr *c2) { - int result = c1->_max_value + c2->_max_value; - if( result < 0 ) { // check for overflow - result = Expr::Max; + int v1 = c1->_max_value; + int v2 = c2->_max_value; + + // Check for overflow without producing UB. If v2 is positive + // and not larger than Max, the subtraction cannot underflow. + assert(0 <= v2 && v2 <= Expr::Max, "sanity"); + if (v1 > Expr::Max - v2) { + return Expr::Max; } - return result; + return v1 + v2; } void Expr::print() const { diff --git a/src/share/vm/adlc/formssel.cpp b/src/share/vm/adlc/formssel.cpp --- a/src/share/vm/adlc/formssel.cpp +++ b/src/share/vm/adlc/formssel.cpp @@ -907,7 +907,8 @@ const char *name; const char *kill_name = NULL; for (_parameters.reset(); (name = _parameters.iter()) != NULL;) { - OperandForm *opForm = (OperandForm*)_localNames[name]; + OpClassForm *opForm = _localNames[name]->is_opclass(); + assert(opForm != NULL, "sanity"); Effect* e = NULL; { @@ -924,7 +925,8 @@ // complex so simply enforce the restriction during parse. if (kill_name != NULL && e->isa(Component::TEMP) && !e->isa(Component::DEF)) { - OperandForm* kill = (OperandForm*)_localNames[kill_name]; + OpClassForm* kill = _localNames[kill_name]->is_opclass(); + assert(kill != NULL, "sanity"); globalAD->syntax_err(_linenum, "%s: %s %s must be at the end of the argument list\n", _ident, kill->_ident, kill_name); } else if (e->isa(Component::KILL) && !e->isa(Component::USE)) { @@ -2329,7 +2331,8 @@ // Add parameters that "do not appear in match rule". const char *name; for (_parameters.reset(); (name = _parameters.iter()) != NULL;) { - OperandForm *opForm = (OperandForm*)_localNames[name]; + OpClassForm *opForm = _localNames[name]->is_opclass(); + assert(opForm != NULL, "sanity"); if ( _components.operand_position(name) == -1 ) { _components.insert(name, opForm->_ident, Component::INVALID, false); diff --git a/src/share/vm/asm/assembler.hpp b/src/share/vm/asm/assembler.hpp --- a/src/share/vm/asm/assembler.hpp +++ b/src/share/vm/asm/assembler.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, 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 @@ -172,6 +172,14 @@ Label() { init(); } + + ~Label() { + assert(is_bound() || is_unused(), "Label was never bound to a location, but it was used as a jmp target"); + } + + void reset() { + init(); //leave _patch_overflow because it points to CodeBuffer. + } }; // A union type for code which has to assemble both constant and diff --git a/src/share/vm/c1/c1_LIRAssembler.cpp b/src/share/vm/c1/c1_LIRAssembler.cpp --- a/src/share/vm/c1/c1_LIRAssembler.cpp +++ b/src/share/vm/c1/c1_LIRAssembler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, 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 @@ -135,6 +135,9 @@ LIR_Assembler::~LIR_Assembler() { + // The unwind handler label may be unbound if this destructor is invoked because of a bail-out. + // Reset it here to avoid an assertion. + _unwind_handler_entry.reset(); } diff --git a/src/share/vm/c1/c1_LIRGenerator.cpp b/src/share/vm/c1/c1_LIRGenerator.cpp --- a/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/src/share/vm/c1/c1_LIRGenerator.cpp @@ -2392,6 +2392,10 @@ // We can have generate one runtime check here. Let's start with // the offset check. + // Allocate temp register to src and load it here, otherwise + // control flow below may confuse register allocator. + LIR_Opr src_reg = new_register(T_OBJECT); + __ move(src.result(), src_reg); if (gen_offset_check) { // if (offset != referent_offset) -> continue // If offset is an int then we can do the comparison with the @@ -2414,14 +2418,14 @@ if (gen_source_check) { // offset is a const and equals referent offset // if (source == null) -> continue - __ cmp(lir_cond_equal, src.result(), LIR_OprFact::oopConst(NULL)); + __ cmp(lir_cond_equal, src_reg, LIR_OprFact::oopConst(NULL)); __ branch(lir_cond_equal, T_OBJECT, Lcont->label()); } LIR_Opr src_klass = new_register(T_OBJECT); if (gen_type_check) { // We have determined that offset == referent_offset && src != null. // if (src->_klass->_reference_type == REF_NONE) -> continue - __ move(new LIR_Address(src.result(), oopDesc::klass_offset_in_bytes(), T_ADDRESS), src_klass); + __ move(new LIR_Address(src_reg, oopDesc::klass_offset_in_bytes(), T_ADDRESS), src_klass); LIR_Address* reference_type_addr = new LIR_Address(src_klass, in_bytes(InstanceKlass::reference_type_offset()), T_BYTE); LIR_Opr reference_type = new_register(T_INT); __ move(reference_type_addr, reference_type); diff --git a/src/share/vm/code/dependencies.cpp b/src/share/vm/code/dependencies.cpp --- a/src/share/vm/code/dependencies.cpp +++ b/src/share/vm/code/dependencies.cpp @@ -525,7 +525,7 @@ xtty->object("x", arg.metadata_value()); } } else { - char xn[10]; sprintf(xn, "x%d", j); + char xn[12]; sprintf(xn, "x%d", j); if (arg.is_oop()) { xtty->object(xn, arg.oop_value()); } else { diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, 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 @@ -9541,6 +9541,7 @@ case CMSCollector::InitialMarking: initialize(true /* fullGC */ , cause /* cause of the GC */, + true /* allMemoryPoolsAffected */, true /* recordGCBeginTime */, true /* recordPreGCUsage */, false /* recordPeakUsage */, @@ -9553,6 +9554,7 @@ case CMSCollector::FinalMarking: initialize(true /* fullGC */ , cause /* cause of the GC */, + true /* allMemoryPoolsAffected */, false /* recordGCBeginTime */, false /* recordPreGCUsage */, false /* recordPeakUsage */, @@ -9565,6 +9567,7 @@ case CMSCollector::Sweeping: initialize(true /* fullGC */ , cause /* cause of the GC */, + true /* allMemoryPoolsAffected */, false /* recordGCBeginTime */, false /* recordPreGCUsage */, true /* recordPeakUsage */, diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, 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 @@ -4008,7 +4008,8 @@ log_gc_header(); TraceCollectorStats tcs(g1mm()->incremental_collection_counters()); - TraceMemoryManagerStats tms(false /* fullGC */, gc_cause()); + TraceMemoryManagerStats tms(false /* fullGC */, gc_cause(), + yc_type() == Mixed /* allMemoryPoolsAffected */); // If the secondary_free_list is not empty, append it to the // free_list. No need to wait for the cleanup operation to finish; diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahUtils.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahUtils.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahUtils.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates. + * Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved. * * 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 @@ -48,6 +48,7 @@ sh->shenandoahPolicy()->record_cycle_start(); sh->heuristics()->record_cycle_start(); _trace_cycle.initialize(false, sh->gc_cause(), + /* allMemoryPoolsAffected */ true, /* recordGCBeginTime = */ true, /* recordPreGCUsage = */ true, /* recordPeakUsage = */ true, @@ -72,6 +73,7 @@ // pause events. Create this pseudo level 0 event to push real events to level 1. sh->gc_timer()->register_gc_phase_start("Shenandoah", Ticks::now()); _trace_pause.initialize(true, sh->gc_cause(), + /* allMemoryPoolsAffected */ true, /* recordGCBeginTime = */ true, /* recordPreGCUsage = */ false, /* recordPeakUsage = */ false, diff --git a/src/share/vm/memory/metaspace.cpp b/src/share/vm/memory/metaspace.cpp --- a/src/share/vm/memory/metaspace.cpp +++ b/src/share/vm/memory/metaspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, 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 @@ -1422,7 +1422,15 @@ return value; } -bool MetaspaceGC::inc_capacity_until_GC(size_t v, size_t* new_cap_until_GC, size_t* old_cap_until_GC) { +// Try to increase the _capacity_until_GC limit counter by v bytes. +// Returns true if it succeeded. It may fail if either another thread +// concurrently increased the limit or the new limit would be larger +// than MaxMetaspaceSize. +// On success, optionally returns new and old metaspace capacity in +// new_cap_until_GC and old_cap_until_GC respectively. +// On error, optionally sets can_retry to indicate whether if there is +// actually enough space remaining to satisfy the request. +bool MetaspaceGC::inc_capacity_until_GC(size_t v, size_t* new_cap_until_GC, size_t* old_cap_until_GC, bool* can_retry) { assert_is_size_aligned(v, Metaspace::commit_alignment()); size_t capacity_until_GC = (size_t) _capacity_until_GC; @@ -1433,6 +1441,17 @@ new_value = align_size_down(max_uintx, Metaspace::commit_alignment()); } + if (new_value > MaxMetaspaceSize) { + if (can_retry != NULL) { + *can_retry = false; + } + return false; + } + + if (can_retry != NULL) { + *can_retry = true; + } + intptr_t expected = (intptr_t) capacity_until_GC; intptr_t actual = Atomic::cmpxchg_ptr((intptr_t) new_value, &_capacity_until_GC, expected); @@ -1520,7 +1539,7 @@ const double min_tmp = used_after_gc / maximum_used_percentage; size_t minimum_desired_capacity = - (size_t)MIN2(min_tmp, double(max_uintx)); + (size_t)MIN2(min_tmp, double(MaxMetaspaceSize)); // Don't shrink less than the initial generation size minimum_desired_capacity = MAX2(minimum_desired_capacity, MetaspaceSize); @@ -1579,7 +1598,7 @@ const double maximum_free_percentage = MaxMetaspaceFreeRatio / 100.0; const double minimum_used_percentage = 1.0 - maximum_free_percentage; const double max_tmp = used_after_gc / minimum_used_percentage; - size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx)); + size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(MaxMetaspaceSize)); maximum_desired_capacity = MAX2(maximum_desired_capacity, MetaspaceSize); if (PrintGCDetails && Verbose) { @@ -3448,6 +3467,7 @@ size_t before = 0; size_t after = 0; + bool can_retry = true; MetaWord* res; bool incremented; @@ -3455,9 +3475,9 @@ // the HWM, an allocation is still attempted. This is because another thread must then // have incremented the HWM and therefore the allocation might still succeed. do { - incremented = MetaspaceGC::inc_capacity_until_GC(delta_bytes, &after, &before); + incremented = MetaspaceGC::inc_capacity_until_GC(delta_bytes, &after, &before, &can_retry); res = allocate(word_size, mdtype); - } while (!incremented && res == NULL); + } while (!incremented && res == NULL && can_retry); if (incremented) { tracer()->report_gc_threshold(before, after, diff --git a/src/share/vm/memory/metaspace.hpp b/src/share/vm/memory/metaspace.hpp --- a/src/share/vm/memory/metaspace.hpp +++ b/src/share/vm/memory/metaspace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, 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 @@ -259,7 +259,7 @@ // Debugging support void verify(); - static void print_compressed_class_space(outputStream* st, const char* requested_addr = 0); + static void print_compressed_class_space(outputStream* st, const char* requested_addr = 0) NOT_LP64({}); class AllocRecordClosure : public StackObj { public: @@ -416,7 +416,8 @@ static size_t capacity_until_GC(); static bool inc_capacity_until_GC(size_t v, size_t* new_cap_until_GC = NULL, - size_t* old_cap_until_GC = NULL); + size_t* old_cap_until_GC = NULL, + bool* can_retry = NULL); static size_t dec_capacity_until_GC(size_t v); static bool should_concurrent_collect() { return _should_concurrent_collect; } diff --git a/src/share/vm/opto/addnode.cpp b/src/share/vm/opto/addnode.cpp --- a/src/share/vm/opto/addnode.cpp +++ b/src/share/vm/opto/addnode.cpp @@ -345,8 +345,8 @@ const Type *AddINode::add_ring( const Type *t0, const Type *t1 ) const { const TypeInt *r0 = t0->is_int(); // Handy access const TypeInt *r1 = t1->is_int(); - int lo = r0->_lo + r1->_lo; - int hi = r0->_hi + r1->_hi; + int lo = java_add(r0->_lo, r1->_lo); + int hi = java_add(r0->_hi, r1->_hi); if( !(r0->is_con() && r1->is_con()) ) { // Not both constants, compute approximate result if( (r0->_lo & r1->_lo) < 0 && lo >= 0 ) { @@ -463,8 +463,8 @@ const Type *AddLNode::add_ring( const Type *t0, const Type *t1 ) const { const TypeLong *r0 = t0->is_long(); // Handy access const TypeLong *r1 = t1->is_long(); - jlong lo = r0->_lo + r1->_lo; - jlong hi = r0->_hi + r1->_hi; + jlong lo = java_add(r0->_lo, r1->_lo); + jlong hi = java_add(r0->_hi, r1->_hi); if( !(r0->is_con() && r1->is_con()) ) { // Not both constants, compute approximate result if( (r0->_lo & r1->_lo) < 0 && lo >= 0 ) { diff --git a/src/share/vm/opto/divnode.cpp b/src/share/vm/opto/divnode.cpp --- a/src/share/vm/opto/divnode.cpp +++ b/src/share/vm/opto/divnode.cpp @@ -131,7 +131,7 @@ } // Add rounding to the shift to handle the sign bit - int l = log2_intptr(d-1)+1; + int l = log2_jint(d-1)+1; if (needs_rounding) { // Divide-by-power-of-2 can be made into a shift, but you have to do // more math for the rounding. You need to add 0 for positive diff --git a/src/share/vm/opto/loopTransform.cpp b/src/share/vm/opto/loopTransform.cpp --- a/src/share/vm/opto/loopTransform.cpp +++ b/src/share/vm/opto/loopTransform.cpp @@ -1314,8 +1314,8 @@ limit = new (C) Opaque2Node( C, limit ); register_new_node( limit, opaq_ctrl ); } - if (stride_con > 0 && ((limit_type->_lo - stride_con) < limit_type->_lo) || - stride_con < 0 && ((limit_type->_hi - stride_con) > limit_type->_hi)) { + if (stride_con > 0 && (java_subtract(limit_type->_lo, stride_con) < limit_type->_lo) || + stride_con < 0 && (java_subtract(limit_type->_hi, stride_con) > limit_type->_hi)) { // No underflow. new_limit = new (C) SubINode(limit, stride); } else { diff --git a/src/share/vm/opto/mulnode.cpp b/src/share/vm/opto/mulnode.cpp --- a/src/share/vm/opto/mulnode.cpp +++ b/src/share/vm/opto/mulnode.cpp @@ -171,7 +171,6 @@ return mul_ring(t1,t2); // Local flavor of type multiplication } - //============================================================================= //------------------------------Ideal------------------------------------------ // Check for power-of-2 multiply, then try the regular MulNode::Ideal @@ -186,42 +185,43 @@ } // Now we have a constant Node on the right and the constant in con - if( con == 0 ) return NULL; // By zero is handled by Value call - if( con == 1 ) return NULL; // By one is handled by Identity call + if (con == 0) return NULL; // By zero is handled by Value call + if (con == 1) return NULL; // By one is handled by Identity call // Check for negative constant; if so negate the final result bool sign_flip = false; - if( con < 0 ) { - con = -con; + + unsigned int abs_con = uabs(con); + if (abs_con != (unsigned int)con) { sign_flip = true; } // Get low bit; check for being the only bit Node *res = NULL; - jint bit1 = con & -con; // Extract low bit - if( bit1 == con ) { // Found a power of 2? - res = new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ); + unsigned int bit1 = abs_con & (0-abs_con); // Extract low bit + if (bit1 == abs_con) { // Found a power of 2? + res = new (phase->C) LShiftINode(in(1), phase->intcon(log2_uint(bit1))); } else { // Check for constant with 2 bits set - jint bit2 = con-bit1; - bit2 = bit2 & -bit2; // Extract 2nd bit - if( bit2 + bit1 == con ) { // Found all bits in con? - Node *n1 = phase->transform( new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ) ); - Node *n2 = phase->transform( new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(bit2)) ) ); - res = new (phase->C) AddINode( n2, n1 ); + unsigned int bit2 = abs_con-bit1; + bit2 = bit2 & (0-bit2); // Extract 2nd bit + if (bit2 + bit1 == abs_con) { // Found all bits in con? + Node *n1 = phase->transform( new (phase->C) LShiftINode(in(1), phase->intcon(log2_uint(bit1)))); + Node *n2 = phase->transform( new (phase->C) LShiftINode(in(1), phase->intcon(log2_uint(bit2)))); + res = new (phase->C) AddINode(n2, n1); - } else if (is_power_of_2(con+1)) { + } else if (is_power_of_2(abs_con+1)) { // Sleezy: power-of-2 -1. Next time be generic. - jint temp = (jint) (con + 1); - Node *n1 = phase->transform( new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(temp)) ) ); - res = new (phase->C) SubINode( n1, in(1) ); + unsigned int temp = abs_con + 1; + Node *n1 = phase->transform(new (phase->C) LShiftINode(in(1), phase->intcon(log2_uint(temp)))); + res = new (phase->C) SubINode(n1, in(1)); } else { return MulNode::Ideal(phase, can_reshape); } } - if( sign_flip ) { // Need to negate result? + if (sign_flip) { // Need to negate result? res = phase->transform(res);// Transform, before making the zero con res = new (phase->C) SubINode(phase->intcon(0),res); } @@ -246,13 +246,13 @@ double d = (double)hi1; // Compute all endpoints & check for overflow - int32 A = lo0*lo1; + int32 A = java_multiply(lo0, lo1); if( (double)A != a*c ) return TypeInt::INT; // Overflow? - int32 B = lo0*hi1; + int32 B = java_multiply(lo0, hi1); if( (double)B != a*d ) return TypeInt::INT; // Overflow? - int32 C = hi0*lo1; + int32 C = java_multiply(hi0, lo1); if( (double)C != b*c ) return TypeInt::INT; // Overflow? - int32 D = hi0*hi1; + int32 D = java_multiply(hi0, hi1); if( (double)D != b*d ) return TypeInt::INT; // Overflow? if( A < B ) { lo0 = A; hi0 = B; } // Sort range endpoints @@ -282,42 +282,42 @@ } // Now we have a constant Node on the right and the constant in con - if( con == CONST64(0) ) return NULL; // By zero is handled by Value call - if( con == CONST64(1) ) return NULL; // By one is handled by Identity call + if (con == CONST64(0)) return NULL; // By zero is handled by Value call + if (con == CONST64(1)) return NULL; // By one is handled by Identity call // Check for negative constant; if so negate the final result bool sign_flip = false; - if( con < 0 ) { - con = -con; + julong abs_con = uabs(con); + if (abs_con != (julong)con) { sign_flip = true; } // Get low bit; check for being the only bit Node *res = NULL; - jlong bit1 = con & -con; // Extract low bit - if( bit1 == con ) { // Found a power of 2? - res = new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ); + julong bit1 = abs_con & (0-abs_con); // Extract low bit + if (bit1 == abs_con) { // Found a power of 2? + res = new (phase->C) LShiftLNode(in(1), phase->intcon(log2_long(bit1))); } else { // Check for constant with 2 bits set - jlong bit2 = con-bit1; - bit2 = bit2 & -bit2; // Extract 2nd bit - if( bit2 + bit1 == con ) { // Found all bits in con? - Node *n1 = phase->transform( new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ) ); - Node *n2 = phase->transform( new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(bit2)) ) ); - res = new (phase->C) AddLNode( n2, n1 ); + julong bit2 = abs_con-bit1; + bit2 = bit2 & (0-bit2); // Extract 2nd bit + if (bit2 + bit1 == abs_con) { // Found all bits in con? + Node *n1 = phase->transform(new (phase->C) LShiftLNode(in(1), phase->intcon(log2_long(bit1)))); + Node *n2 = phase->transform(new (phase->C) LShiftLNode(in(1), phase->intcon(log2_long(bit2)))); + res = new (phase->C) AddLNode(n2, n1); - } else if (is_power_of_2_long(con+1)) { + } else if (is_power_of_2_long(abs_con+1)) { // Sleezy: power-of-2 -1. Next time be generic. - jlong temp = (jlong) (con + 1); - Node *n1 = phase->transform( new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(temp)) ) ); - res = new (phase->C) SubLNode( n1, in(1) ); + julong temp = abs_con + 1; + Node *n1 = phase->transform( new (phase->C) LShiftLNode(in(1), phase->intcon(log2_long(temp)))); + res = new (phase->C) SubLNode(n1, in(1)); } else { return MulNode::Ideal(phase, can_reshape); } } - if( sign_flip ) { // Need to negate result? + if (sign_flip) { // Need to negate result? res = phase->transform(res);// Transform, before making the zero con res = new (phase->C) SubLNode(phase->longcon(0),res); } @@ -342,13 +342,13 @@ double d = (double)hi1; // Compute all endpoints & check for overflow - jlong A = lo0*lo1; + jlong A = java_multiply(lo0, lo1); if( (double)A != a*c ) return TypeLong::LONG; // Overflow? - jlong B = lo0*hi1; + jlong B = java_multiply(lo0, hi1); if( (double)B != a*d ) return TypeLong::LONG; // Overflow? - jlong C = hi0*lo1; + jlong C = java_multiply(hi0, lo1); if( (double)C != b*c ) return TypeLong::LONG; // Overflow? - jlong D = hi0*hi1; + jlong D = java_multiply(hi0, hi1); if( (double)D != b*d ) return TypeLong::LONG; // Overflow? if( A < B ) { lo0 = A; hi0 = B; } // Sort range endpoints @@ -446,7 +446,7 @@ // Masking off high bits which are always zero is useless. const TypeInt* t1 = phase->type( in(1) )->isa_int(); if (t1 != NULL && t1->_lo >= 0) { - jint t1_support = right_n_bits(1 + log2_intptr(t1->_hi)); + jint t1_support = right_n_bits(1 + log2_jint(t1->_hi)); if ((t1_support & con) == t1_support) return in1; } @@ -584,7 +584,8 @@ // Masking off high bits which are always zero is useless. const TypeLong* t1 = phase->type( in(1) )->isa_long(); if (t1 != NULL && t1->_lo >= 0) { - jlong t1_support = ((jlong)1 << (1 + log2_long(t1->_hi))) - 1; + int bit_count = log2_long(t1->_hi) + 1; + jlong t1_support = jlong(max_julong >> (BitsPerJavaLong - bit_count)); if ((t1_support & con) == t1_support) return usr; } @@ -812,7 +813,7 @@ // Check for ((x & ((CONST64(1)<<(64-c0))-1)) << c0) which ANDs off high bits // before shifting them away. - const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) - CONST64(1); + const jlong bits_mask = jlong(max_julong >> con); if( add1_op == Op_AndL && phase->type(add1->in(2)) == TypeLong::make( bits_mask ) ) return new (phase->C) LShiftLNode( add1->in(1), in(2) ); @@ -1264,7 +1265,7 @@ if ( con == 0 ) return NULL; // let Identity() handle a 0 shift count // note: mask computation below does not work for 0 shift count // We'll be wanting the right-shift amount as a mask of that many bits - const jlong mask = (((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) -1); + const jlong mask = jlong(max_julong >> con); // Check for ((x << z) + Y) >>> z. Replace with x + con>>>z // The idiom for rounding to a power of 2 is "(Q+(2^z-1)) >>> z". diff --git a/src/share/vm/opto/subnode.cpp b/src/share/vm/opto/subnode.cpp --- a/src/share/vm/opto/subnode.cpp +++ b/src/share/vm/opto/subnode.cpp @@ -266,8 +266,8 @@ const Type *SubINode::sub( const Type *t1, const Type *t2 ) const { const TypeInt *r0 = t1->is_int(); // Handy access const TypeInt *r1 = t2->is_int(); - int32 lo = r0->_lo - r1->_hi; - int32 hi = r0->_hi - r1->_lo; + int32 lo = java_subtract(r0->_lo, r1->_hi); + int32 hi = java_subtract(r0->_hi, r1->_lo); // We next check for 32-bit overflow. // If that happens, we just assume all integers are possible. @@ -375,8 +375,8 @@ const Type *SubLNode::sub( const Type *t1, const Type *t2 ) const { const TypeLong *r0 = t1->is_long(); // Handy access const TypeLong *r1 = t2->is_long(); - jlong lo = r0->_lo - r1->_hi; - jlong hi = r0->_hi - r1->_lo; + jlong lo = java_subtract(r0->_lo, r1->_hi); + jlong hi = java_subtract(r0->_hi, r1->_lo); // We next check for 32-bit overflow. // If that happens, we just assume all integers are possible. diff --git a/src/share/vm/opto/type.cpp b/src/share/vm/opto/type.cpp --- a/src/share/vm/opto/type.cpp +++ b/src/share/vm/opto/type.cpp @@ -1330,8 +1330,8 @@ // The new type narrows the old type, so look for a "death march". // See comments on PhaseTransform::saturate. - juint nrange = _hi - _lo; - juint orange = ohi - olo; + juint nrange = (juint)_hi - _lo; + juint orange = (juint)ohi - olo; if (nrange < max_juint - 1 && nrange > (orange >> 1) + (SMALLINT*2)) { // Use the new type only if the range shrinks a lot. // We do not want the optimizer computing 2^31 point by point. @@ -1364,7 +1364,7 @@ //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypeInt::hash(void) const { - return _lo+_hi+_widen+(int)Type::Int; + return java_add(java_add(_lo, _hi), java_add(_widen, (int)Type::Int)); } //------------------------------is_finite-------------------------------------- @@ -1545,7 +1545,7 @@ // If neither endpoint is extremal yet, push out the endpoint // which is closer to its respective limit. if (_lo >= 0 || // easy common case - (julong)(_lo - min) >= (julong)(max - _hi)) { + ((julong)_lo - min) >= ((julong)max - _hi)) { // Try to widen to an unsigned range type of 32/63 bits: if (max >= max_juint && _hi < max_juint) return make(_lo, max_juint, WidenMax); @@ -2315,7 +2315,7 @@ //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypePtr::hash(void) const { - return _ptr + _offset; + return java_add(_ptr, _offset); } //------------------------------dump2------------------------------------------ @@ -2912,12 +2912,8 @@ // Type-specific hashing function. int TypeOopPtr::hash(void) const { return - (const_oop() ? const_oop()->hash() : 0) + - _klass_is_exact + - _instance_id + - hash_speculative() + - _inline_depth + - TypePtr::hash(); + java_add(java_add(java_add(const_oop() ? const_oop()->hash() : 0, _klass_is_exact), + java_add(_instance_id , hash_speculative())), java_add(_inline_depth , TypePtr::hash())); } //------------------------------dump2------------------------------------------ @@ -3648,7 +3644,7 @@ //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypeInstPtr::hash(void) const { - int hash = klass()->hash() + TypeOopPtr::hash(); + int hash = java_add(klass()->hash(), TypeOopPtr::hash()); return hash; } @@ -4549,7 +4545,7 @@ //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypeKlassPtr::hash(void) const { - return klass()->hash() + TypePtr::hash(); + return java_add(klass()->hash(), TypePtr::hash()); } //------------------------------singleton-------------------------------------- diff --git a/src/share/vm/prims/whitebox.cpp b/src/share/vm/prims/whitebox.cpp --- a/src/share/vm/prims/whitebox.cpp +++ b/src/share/vm/prims/whitebox.cpp @@ -171,7 +171,7 @@ WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) { CollectorPolicy * p = Universe::heap()->collector_policy(); gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap " - SIZE_FORMAT" Maximum heap " SIZE_FORMAT " Min alignment " SIZE_FORMAT " Max alignment " SIZE_FORMAT, + SIZE_FORMAT " Maximum heap " SIZE_FORMAT " Space alignment " SIZE_FORMAT " Heap alignment " SIZE_FORMAT, p->min_heap_byte_size(), p->initial_heap_byte_size(), p->max_heap_byte_size(), p->space_alignment(), p->heap_alignment()); } @@ -371,6 +371,13 @@ return (jlong)(uintptr_t)os::malloc(size, mtTest, stack); WB_END +// Alloc memory with pseudo call stack and specific memory type. +WB_ENTRY(jlong, WB_NMTMallocWithPseudoStackAndType(JNIEnv* env, jobject o, jlong size, jint pseudo_stack, jint type)) + address pc = (address)(size_t)pseudo_stack; + NativeCallStack stack(&pc, 1); + return (jlong)(uintptr_t)os::malloc(size, (MEMFLAGS)type, stack); +WB_END + // Free the memory allocated by NMTAllocTest WB_ENTRY(void, WB_NMTFree(JNIEnv* env, jobject o, jlong mem)) os::free((void*)(uintptr_t)mem, mtTest); @@ -1081,6 +1088,7 @@ #if INCLUDE_NMT {CC"NMTMalloc", CC"(J)J", (void*)&WB_NMTMalloc }, {CC"NMTMallocWithPseudoStack", CC"(JI)J", (void*)&WB_NMTMallocWithPseudoStack}, + {CC"NMTMallocWithPseudoStackAndType", CC"(JII)J", (void*)&WB_NMTMallocWithPseudoStackAndType}, {CC"NMTFree", CC"(J)V", (void*)&WB_NMTFree }, {CC"NMTReserveMemory", CC"(J)J", (void*)&WB_NMTReserveMemory }, {CC"NMTCommitMemory", CC"(JJ)V", (void*)&WB_NMTCommitMemory }, diff --git a/src/share/vm/runtime/advancedThresholdPolicy.cpp b/src/share/vm/runtime/advancedThresholdPolicy.cpp --- a/src/share/vm/runtime/advancedThresholdPolicy.cpp +++ b/src/share/vm/runtime/advancedThresholdPolicy.cpp @@ -47,8 +47,8 @@ int count = CICompilerCount; if (CICompilerCountPerCPU) { // Simple log n seems to grow too slowly for tiered, try something faster: log n * log log n - int log_cpu = log2_intptr(os::active_processor_count()); - int loglog_cpu = log2_intptr(MAX2(log_cpu, 1)); + int log_cpu = log2_int(os::active_processor_count()); + int loglog_cpu = log2_int(MAX2(log_cpu, 1)); count = MAX2(log_cpu * loglog_cpu, 1) * 3 / 2; } @@ -131,7 +131,8 @@ } double AdvancedThresholdPolicy::weight(Method* method) { - return (method->rate() + 1) * ((method->invocation_count() + 1) * (method->backedge_count() + 1)); + return (double)(method->rate() + 1) * + (method->invocation_count() + 1) * (method->backedge_count() + 1); } // Apply heuristics and return true if x should be compiled before y diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp +++ b/src/share/vm/runtime/arguments.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, 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 @@ -68,7 +68,11 @@ #endif // INCLUDE_ALL_GCS // Note: This is a special bug reporting site for the JVM -#define DEFAULT_VENDOR_URL_BUG "http://bugreport.java.com/bugreport/crash.jsp" +#ifdef VENDOR_URL_VM_BUG +# define DEFAULT_VENDOR_URL_BUG VENDOR_URL_VM_BUG +#else +# define DEFAULT_VENDOR_URL_BUG "http://bugreport.java.com/bugreport/crash.jsp" +#endif #define DEFAULT_JAVA_LAUNCHER "generic" // Disable options not supported in this release, with a warning if they diff --git a/src/share/vm/runtime/compilationPolicy.cpp b/src/share/vm/runtime/compilationPolicy.cpp --- a/src/share/vm/runtime/compilationPolicy.cpp +++ b/src/share/vm/runtime/compilationPolicy.cpp @@ -181,7 +181,7 @@ // Example: if CICompilerCountPerCPU is true, then we get // max(log2(8)-1,1) = 2 compiler threads on an 8-way machine. // May help big-app startup time. - _compiler_count = MAX2(log2_intptr(os::active_processor_count())-1,1); + _compiler_count = MAX2(log2_int(os::active_processor_count())-1,1); FLAG_SET_ERGO(intx, CICompilerCount, _compiler_count); } else { _compiler_count = CICompilerCount; diff --git a/src/share/vm/runtime/fprofiler.cpp b/src/share/vm/runtime/fprofiler.cpp --- a/src/share/vm/runtime/fprofiler.cpp +++ b/src/share/vm/runtime/fprofiler.cpp @@ -775,7 +775,7 @@ } void ThreadProfiler::vm_update(TickPosition where) { - vm_update(NULL, where); + vm_update("", where); } void ThreadProfiler::vm_update(const char* name, TickPosition where) { diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp +++ b/src/share/vm/runtime/globals.hpp @@ -780,8 +780,8 @@ "Time out and warn or fail after SafepointTimeoutDelay " \ "milliseconds if failed to reach safepoint") \ \ - develop(bool, DieOnSafepointTimeout, false, \ - "Die upon failure to reach safepoint (see SafepointTimeout)") \ + diagnostic(bool, AbortVMOnSafepointTimeout, false, \ + "Abort upon failure to reach safepoint (see SafepointTimeout)") \ \ /* 50 retries * (5 * current_retry_count) millis = ~6.375 seconds */ \ /* typically, at most a few retries are needed */ \ diff --git a/src/share/vm/runtime/os.cpp b/src/share/vm/runtime/os.cpp --- a/src/share/vm/runtime/os.cpp +++ b/src/share/vm/runtime/os.cpp @@ -1284,7 +1284,7 @@ } void os::set_memory_serialize_page(address page) { - int count = log2_intptr(sizeof(class JavaThread)) - log2_intptr(64); + int count = log2_intptr(sizeof(class JavaThread)) - log2_int(64); _mem_serialize_page = (volatile int32_t *)page; // We initialize the serialization page shift count here // We assume a cache line size of 64 bytes diff --git a/src/share/vm/runtime/os.hpp b/src/share/vm/runtime/os.hpp --- a/src/share/vm/runtime/os.hpp +++ b/src/share/vm/runtime/os.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, 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 @@ -527,7 +527,7 @@ static char* do_you_want_to_debug(const char* message); // run cmd in a separate process and return its exit code; or -1 on failures - static int fork_and_exec(char *cmd); + static int fork_and_exec(char *cmd, bool use_vfork_if_available = false); // os::exit() is merged with vm_exit() // static void exit(int num); diff --git a/src/share/vm/runtime/safepoint.cpp b/src/share/vm/runtime/safepoint.cpp --- a/src/share/vm/runtime/safepoint.cpp +++ b/src/share/vm/runtime/safepoint.cpp @@ -794,9 +794,9 @@ tty->print_cr("# SafepointSynchronize::begin: (End of list)"); } - // To debug the long safepoint, specify both DieOnSafepointTimeout & + // To debug the long safepoint, specify both AbortVMOnSafepointTimeout & // ShowMessageBoxOnError. - if (DieOnSafepointTimeout) { + if (AbortVMOnSafepointTimeout) { char msg[1024]; VM_Operation *op = VMThread::vm_operation(); sprintf(msg, "Safepoint sync time longer than " INTX_FORMAT "ms detected when executing %s.", diff --git a/src/share/vm/runtime/simpleThresholdPolicy.cpp b/src/share/vm/runtime/simpleThresholdPolicy.cpp --- a/src/share/vm/runtime/simpleThresholdPolicy.cpp +++ b/src/share/vm/runtime/simpleThresholdPolicy.cpp @@ -139,7 +139,7 @@ } int count = CICompilerCount; if (CICompilerCountPerCPU) { - count = MAX2(log2_intptr(os::active_processor_count()), 1) * 3 / 2; + count = MAX2(log2_int(os::active_processor_count()), 1) * 3 / 2; } set_c1_count(MAX2(count / 3, 1)); set_c2_count(MAX2(count - c1_count(), 1)); diff --git a/src/share/vm/runtime/vm_version.cpp b/src/share/vm/runtime/vm_version.cpp --- a/src/share/vm/runtime/vm_version.cpp +++ b/src/share/vm/runtime/vm_version.cpp @@ -143,7 +143,7 @@ const char* Abstract_VM_Version::vm_vendor() { #ifdef VENDOR - return XSTR(VENDOR); + return VENDOR; #else return JDK_Version::is_gte_jdk17x_version() ? "Oracle Corporation" : "Sun Microsystems Inc."; diff --git a/src/share/vm/services/memReporter.cpp b/src/share/vm/services/memReporter.cpp --- a/src/share/vm/services/memReporter.cpp +++ b/src/share/vm/services/memReporter.cpp @@ -572,9 +572,15 @@ void MemDetailDiffReporter::diff_malloc_site(const MallocSite* early, const MallocSite* current) const { - assert(early->flags() == current->flags(), "Must be the same memory type"); - diff_malloc_site(current->call_stack(), current->size(), current->count(), - early->size(), early->count(), early->flags()); + if (early->flags() != current->flags()) { + // If malloc site type changed, treat it as deallocation of old type and + // allocation of new type. + old_malloc_site(early); + new_malloc_site(current); + } else { + diff_malloc_site(current->call_stack(), current->size(), current->count(), + early->size(), early->count(), early->flags()); + } } void MemDetailDiffReporter::diff_malloc_site(const NativeCallStack* stack, size_t current_size, diff --git a/src/share/vm/services/memoryManager.cpp b/src/share/vm/services/memoryManager.cpp --- a/src/share/vm/services/memoryManager.cpp +++ b/src/share/vm/services/memoryManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, 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 @@ -49,13 +49,15 @@ (void)const_cast<instanceOop&>(_memory_mgr_obj = instanceOop(NULL)); } -void MemoryManager::add_pool(MemoryPool* pool) { - assert(_num_pools < MemoryManager::max_num_pools, "_num_pools exceeds the max"); - if (_num_pools < MemoryManager::max_num_pools) { - _pools[_num_pools] = pool; +int MemoryManager::add_pool(MemoryPool* pool) { + int index = _num_pools; + assert(index < MemoryManager::max_num_pools, "_num_pools exceeds the max"); + if (index < MemoryManager::max_num_pools) { + _pools[index] = pool; _num_pools++; } pool->add_manager(this); + return index; } MemoryManager* MemoryManager::get_code_cache_memory_manager() { @@ -225,6 +227,15 @@ delete _current_gc_stat; } +void GCMemoryManager::add_pool(MemoryPool* pool) { + add_pool(pool, true); +} + +void GCMemoryManager::add_pool(MemoryPool* pool, bool always_affected_by_gc) { + int index = MemoryManager::add_pool(pool); + _pool_always_affected_by_gc[index] = always_affected_by_gc; +} + void GCMemoryManager::initialize_gc_stat_info() { assert(MemoryService::num_memory_pools() > 0, "should have one or more memory pools"); _last_gc_stat = new(ResourceObj::C_HEAP, mtGC) GCStatInfo(MemoryService::num_memory_pools()); @@ -274,7 +285,8 @@ void GCMemoryManager::gc_end(bool recordPostGCUsage, bool recordAccumulatedGCTime, bool recordGCEndTime, bool countCollection, - GCCause::Cause cause) { + GCCause::Cause cause, + bool allMemoryPoolsAffected) { if (recordAccumulatedGCTime) { _accumulated_timer.stop(); } @@ -312,8 +324,11 @@ MemoryUsage usage = pool->get_memory_usage(); // Compare with GC usage threshold - pool->set_last_collection_usage(usage); - LowMemoryDetector::detect_after_gc_memory(pool); + if (allMemoryPoolsAffected || pool_always_affected_by_gc(i)) { + // Compare with GC usage threshold + pool->set_last_collection_usage(usage); + LowMemoryDetector::detect_after_gc_memory(pool); + } } } diff --git a/src/share/vm/services/memoryManager.hpp b/src/share/vm/services/memoryManager.hpp --- a/src/share/vm/services/memoryManager.hpp +++ b/src/share/vm/services/memoryManager.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, 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 @@ -41,11 +41,12 @@ class OopClosure; class MemoryManager : public CHeapObj<mtInternal> { -private: +protected: enum { max_num_pools = 10 }; +private: MemoryPool* _pools[max_num_pools]; int _num_pools; @@ -77,7 +78,7 @@ return _pools[index]; } - void add_pool(MemoryPool* pool); + int add_pool(MemoryPool* pool); bool is_manager(instanceHandle mh) { return oopDesc::equals(mh(), _memory_mgr_obj); } @@ -180,10 +181,20 @@ GCStatInfo* _current_gc_stat; int _num_gc_threads; volatile bool _notification_enabled; + bool _pool_always_affected_by_gc[MemoryManager::max_num_pools]; + public: GCMemoryManager(); ~GCMemoryManager(); + void add_pool(MemoryPool* pool); + void add_pool(MemoryPool* pool, bool always_affected_by_gc); + + bool pool_always_affected_by_gc(int index) { + assert(index >= 0 && index < num_memory_pools(), "Invalid index"); + return _pool_always_affected_by_gc[index]; + } + void initialize_gc_stat_info(); bool is_gc_memory_manager() { return true; } @@ -195,7 +206,8 @@ void gc_begin(bool recordGCBeginTime, bool recordPreGCUsage, bool recordAccumulatedGCTime); void gc_end(bool recordPostGCUsage, bool recordAccumulatedGCTime, - bool recordGCEndTime, bool countCollection, GCCause::Cause cause); + bool recordGCEndTime, bool countCollection, GCCause::Cause cause, + bool allMemoryPoolsAffected); void reset_gc_stat() { _num_collections = 0; _accumulated_timer.reset(); } diff --git a/src/share/vm/services/memoryService.cpp b/src/share/vm/services/memoryService.cpp --- a/src/share/vm/services/memoryService.cpp +++ b/src/share/vm/services/memoryService.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, 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 @@ -193,7 +193,7 @@ _managers_list->append(_major_gc_manager); add_g1YoungGen_memory_pool(g1h, _major_gc_manager, _minor_gc_manager); - add_g1OldGen_memory_pool(g1h, _major_gc_manager); + add_g1OldGen_memory_pool(g1h, _major_gc_manager, _minor_gc_manager); } void MemoryService::add_shenandoah_heap_info(ShenandoahHeap* heap) { @@ -265,8 +265,8 @@ // Add memory pool(s) for one generation void MemoryService::add_generation_memory_pool(Generation* gen, - MemoryManager* major_mgr, - MemoryManager* minor_mgr) { + GCMemoryManager* major_mgr, + GCMemoryManager* minor_mgr) { guarantee(gen != NULL, "No generation for memory pool"); Generation::Name kind = gen->kind(); int index = _pools_list->length(); @@ -356,7 +356,9 @@ #if INCLUDE_ALL_GCS -void MemoryService::add_psYoung_memory_pool(PSYoungGen* gen, MemoryManager* major_mgr, MemoryManager* minor_mgr) { +void MemoryService::add_psYoung_memory_pool(PSYoungGen* gen, + GCMemoryManager* major_mgr, + GCMemoryManager* minor_mgr) { assert(major_mgr != NULL && minor_mgr != NULL, "Should have two managers"); // Add a memory pool for each space and young gen doesn't @@ -380,7 +382,7 @@ _pools_list->append(survivor); } -void MemoryService::add_psOld_memory_pool(PSOldGen* gen, MemoryManager* mgr) { +void MemoryService::add_psOld_memory_pool(PSOldGen* gen, GCMemoryManager* mgr) { PSGenerationPool* old_gen = new PSGenerationPool(gen, "PS Old Gen", MemoryPool::Heap, @@ -390,8 +392,8 @@ } void MemoryService::add_g1YoungGen_memory_pool(G1CollectedHeap* g1h, - MemoryManager* major_mgr, - MemoryManager* minor_mgr) { + GCMemoryManager* major_mgr, + GCMemoryManager* minor_mgr) { assert(major_mgr != NULL && minor_mgr != NULL, "should have two managers"); G1EdenPool* eden = new G1EdenPool(g1h); @@ -406,11 +408,13 @@ } void MemoryService::add_g1OldGen_memory_pool(G1CollectedHeap* g1h, - MemoryManager* mgr) { - assert(mgr != NULL, "should have one manager"); + GCMemoryManager* major_mgr, + GCMemoryManager* minor_mgr) { + assert(major_mgr != NULL && minor_mgr != NULL, "should have two managers"); G1OldGenPool* old_gen = new G1OldGenPool(g1h); - mgr->add_pool(old_gen); + major_mgr->add_pool(old_gen); + minor_mgr->add_pool(old_gen, false /* always_affected_by_gc */); _pools_list->append(old_gen); } @@ -510,7 +514,8 @@ void MemoryService::gc_end(bool fullGC, bool recordPostGCUsage, bool recordAccumulatedGCTime, bool recordGCEndTime, bool countCollection, - GCCause::Cause cause) { + GCCause::Cause cause, + bool allMemoryPoolsAffected) { GCMemoryManager* mgr; if (fullGC) { @@ -522,7 +527,7 @@ // register the GC end statistics and memory usage mgr->gc_end(recordPostGCUsage, recordAccumulatedGCTime, recordGCEndTime, - countCollection, cause); + countCollection, cause, allMemoryPoolsAffected); } void MemoryService::oops_do(OopClosure* f) { @@ -599,10 +604,11 @@ } // this has to be called in a stop the world pause and represent // an entire gc pause, start to finish: - initialize(_fullGC, cause,true, true, true, true, true, true, true); + initialize(_fullGC, cause, true, true, true, true, true, true, true, true); } TraceMemoryManagerStats::TraceMemoryManagerStats(bool fullGC, GCCause::Cause cause, + bool allMemoryPoolsAffected, bool recordGCBeginTime, bool recordPreGCUsage, bool recordPeakUsage, @@ -610,7 +616,8 @@ bool recordAccumulatedGCTime, bool recordGCEndTime, bool countCollection) { - initialize(fullGC, cause, recordGCBeginTime, recordPreGCUsage, recordPeakUsage, + initialize(fullGC, cause, allMemoryPoolsAffected, + recordGCBeginTime, recordPreGCUsage, recordPeakUsage, recordPostGCUsage, recordAccumulatedGCTime, recordGCEndTime, countCollection); } @@ -619,6 +626,7 @@ // the MemoryService void TraceMemoryManagerStats::initialize(bool fullGC, GCCause::Cause cause, + bool allMemoryPoolsAffected, bool recordGCBeginTime, bool recordPreGCUsage, bool recordPeakUsage, @@ -627,6 +635,7 @@ bool recordGCEndTime, bool countCollection) { _fullGC = fullGC; + _allMemoryPoolsAffected = allMemoryPoolsAffected; _recordGCBeginTime = recordGCBeginTime; _recordPreGCUsage = recordPreGCUsage; _recordPeakUsage = recordPeakUsage; @@ -642,5 +651,5 @@ TraceMemoryManagerStats::~TraceMemoryManagerStats() { MemoryService::gc_end(_fullGC, _recordPostGCUsage, _recordAccumulatedGCTime, - _recordGCEndTime, _countCollection, _cause); + _recordGCEndTime, _countCollection, _cause, _allMemoryPoolsAffected); } diff --git a/src/share/vm/services/memoryService.hpp b/src/share/vm/services/memoryService.hpp --- a/src/share/vm/services/memoryService.hpp +++ b/src/share/vm/services/memoryService.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, 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 @@ -78,25 +78,26 @@ static MemoryPool* _compressed_class_pool; static void add_generation_memory_pool(Generation* gen, - MemoryManager* major_mgr, - MemoryManager* minor_mgr); + GCMemoryManager* major_mgr, + GCMemoryManager* minor_mgr); static void add_generation_memory_pool(Generation* gen, - MemoryManager* major_mgr) { + GCMemoryManager* major_mgr) { add_generation_memory_pool(gen, major_mgr, NULL); } static void add_psYoung_memory_pool(PSYoungGen* gen, - MemoryManager* major_mgr, - MemoryManager* minor_mgr); + GCMemoryManager* major_mgr, + GCMemoryManager* minor_mgr); static void add_psOld_memory_pool(PSOldGen* gen, - MemoryManager* mgr); + GCMemoryManager* mgr); static void add_g1YoungGen_memory_pool(G1CollectedHeap* g1h, - MemoryManager* major_mgr, - MemoryManager* minor_mgr); + GCMemoryManager* major_mgr, + GCMemoryManager* minor_mgr); static void add_g1OldGen_memory_pool(G1CollectedHeap* g1h, - MemoryManager* mgr); + GCMemoryManager* major_mgr, + GCMemoryManager* minor_mgr); static MemoryPool* add_space(ContiguousSpace* space, const char* name, @@ -164,7 +165,8 @@ static void gc_end(bool fullGC, bool recordPostGCUsage, bool recordAccumulatedGCTime, bool recordGCEndTime, bool countCollection, - GCCause::Cause cause); + GCCause::Cause cause, + bool allMemoryPoolsAffected); static void oops_do(OopClosure* f); @@ -187,6 +189,7 @@ class TraceMemoryManagerStats : public StackObj { private: bool _fullGC; + bool _allMemoryPoolsAffected; bool _recordGCBeginTime; bool _recordPreGCUsage; bool _recordPeakUsage; @@ -199,6 +202,7 @@ TraceMemoryManagerStats() {} TraceMemoryManagerStats(bool fullGC, GCCause::Cause cause, + bool allMemoryPoolsAffected = true, bool recordGCBeginTime = true, bool recordPreGCUsage = true, bool recordPeakUsage = true, @@ -209,6 +213,7 @@ void initialize(bool fullGC, GCCause::Cause cause, + bool allMemoryPoolsAffected, bool recordGCBeginTime, bool recordPreGCUsage, bool recordPeakUsage, diff --git a/src/share/vm/utilities/bitMap.cpp b/src/share/vm/utilities/bitMap.cpp --- a/src/share/vm/utilities/bitMap.cpp +++ b/src/share/vm/utilities/bitMap.cpp @@ -154,14 +154,24 @@ } } +bool BitMap::is_small_range_of_words(idx_t beg_full_word, idx_t end_full_word) { + // There is little point to call large version on small ranges. + // Need to check carefully, keeping potential idx_t underflow in mind. + // The threshold should be at least one word. + STATIC_ASSERT(small_range_words >= 1); + return (beg_full_word + small_range_words >= end_full_word); +} + void BitMap::set_large_range(idx_t beg, idx_t end) { verify_range(beg, end); idx_t beg_full_word = word_index_round_up(beg); idx_t end_full_word = word_index(end); - assert(end_full_word - beg_full_word >= 32, - "the range must include at least 32 bytes"); + if (is_small_range_of_words(beg_full_word, end_full_word)) { + set_range(beg, end); + return; + } // The range includes at least one full word. set_range_within_word(beg, bit_index(beg_full_word)); @@ -175,8 +185,9 @@ idx_t beg_full_word = word_index_round_up(beg); idx_t end_full_word = word_index(end); - if (end_full_word - beg_full_word < 32) { + if (is_small_range_of_words(beg_full_word, end_full_word)) { clear_range(beg, end); + return; } // The range includes at least one full word. @@ -265,8 +276,10 @@ idx_t beg_full_word = word_index_round_up(beg); idx_t end_full_word = word_index(end); - assert(end_full_word - beg_full_word >= 32, - "the range must include at least 32 bytes"); + if (is_small_range_of_words(beg_full_word, end_full_word)) { + par_at_put_range(beg, end, value); + return; + } // The range includes at least one full word. par_put_range_within_word(beg, bit_index(beg_full_word), value); diff --git a/src/share/vm/utilities/bitMap.hpp b/src/share/vm/utilities/bitMap.hpp --- a/src/share/vm/utilities/bitMap.hpp +++ b/src/share/vm/utilities/bitMap.hpp @@ -56,6 +56,10 @@ // the bitmap appropriately if needed using factor-of-two expansion. void at_put_grow(idx_t index, bool value); + // Threshold for performing small range operation, even when large range + // operation was requested. Measured in words. + static const size_t small_range_words = 32; + protected: // Return the position of bit within the word that contains it (e.g., if // bitmap words are 32 bits, return a number 0 <= n <= 31). @@ -97,6 +101,8 @@ void set_large_range_of_words (idx_t beg, idx_t end); void clear_large_range_of_words (idx_t beg, idx_t end); + static bool is_small_range_of_words(idx_t beg_full_word, idx_t end_full_word); + // The index of the first full word in a range. idx_t word_index_round_up(idx_t bit) const; diff --git a/src/share/vm/utilities/bitMap.inline.hpp b/src/share/vm/utilities/bitMap.inline.hpp --- a/src/share/vm/utilities/bitMap.inline.hpp +++ b/src/share/vm/utilities/bitMap.inline.hpp @@ -321,10 +321,12 @@ } inline void BitMap::set_large_range_of_words(idx_t beg, idx_t end) { + assert(beg <= end, "underflow"); memset(_map + beg, ~(unsigned char)0, (end - beg) * sizeof(uintptr_t)); } inline void BitMap::clear_large_range_of_words(idx_t beg, idx_t end) { + assert(beg <= end, "underflow"); memset(_map + beg, 0, (end - beg) * sizeof(uintptr_t)); } diff --git a/src/share/vm/utilities/globalDefinitions.hpp b/src/share/vm/utilities/globalDefinitions.hpp --- a/src/share/vm/utilities/globalDefinitions.hpp +++ b/src/share/vm/utilities/globalDefinitions.hpp @@ -1144,10 +1144,10 @@ //* largest i such that 2^i <= x // A negative value of 'x' will return '31' -inline int log2_intptr(intptr_t x) { +inline int log2_intptr(uintptr_t x) { int i = -1; uintptr_t p = 1; - while (p != 0 && p <= (uintptr_t)x) { + while (p != 0 && p <= x) { // p = 2^(i+1) && p <= x (i.e., 2^(i+1) <= x) i++; p *= 2; } @@ -1157,11 +1157,10 @@ } //* largest i such that 2^i <= x -// A negative value of 'x' will return '63' -inline int log2_long(jlong x) { +inline int log2_long(julong x) { int i = -1; julong p = 1; - while (p != 0 && p <= (julong)x) { + while (p != 0 && p <= x) { // p = 2^(i+1) && p <= x (i.e., 2^(i+1) <= x) i++; p *= 2; } @@ -1170,6 +1169,27 @@ return i; } +inline int log2_intptr(intptr_t x) { + return log2_intptr((uintptr_t)x); +} + +inline int log2_int(int x) { + return log2_intptr((uintptr_t)x); +} + +inline int log2_jint(jint x) { + return log2_intptr((uintptr_t)x); +} + +inline int log2_uint(uint x) { + return log2_intptr((uintptr_t)x); +} + +// A negative value of 'x' will return '63' +inline int log2_jlong(jlong x) { + return log2_long((julong)x); +} + //* the argument must be exactly a power of 2 inline int exact_log2(intptr_t x) { #ifdef ASSERT @@ -1209,6 +1229,29 @@ inline bool is_odd (intx x) { return x & 1; } inline bool is_even(intx x) { return !is_odd(x); } +// abs methods which cannot overflow and so are well-defined across +// the entire domain of integer types. +static inline unsigned int uabs(unsigned int n) { + union { + unsigned int result; + int value; + }; + result = n; + if (value < 0) result = 0-result; + return result; +} +static inline julong uabs(julong n) { + union { + julong result; + jlong value; + }; + result = n; + if (value < 0) result = 0-result; + return result; +} +static inline julong uabs(jlong n) { return uabs((julong)n); } +static inline unsigned int uabs(int n) { return uabs((unsigned int)n); } + // "to" should be greater than "from." inline intx byte_size(void* from, void* to) { return (address)to - (address)from; @@ -1412,6 +1455,32 @@ #define ARRAY_SIZE(array) (sizeof(array)/sizeof((array)[0])) +//---------------------------------------------------------------------------------------------------- +// Sum and product which can never overflow: they wrap, just like the +// Java operations. Note that we don't intend these to be used for +// general-purpose arithmetic: their purpose is to emulate Java +// operations. + +// The goal of this code to avoid undefined or implementation-defined +// behaviour. The use of an lvalue to reference cast is explicitly +// permitted by Lvalues and rvalues [basic.lval]. [Section 3.10 Para +// 15 in C++03] +#define JAVA_INTEGER_OP(OP, NAME, TYPE, UNSIGNED_TYPE) \ +inline TYPE NAME (TYPE in1, TYPE in2) { \ + UNSIGNED_TYPE ures = static_cast<UNSIGNED_TYPE>(in1); \ + ures OP ## = static_cast<UNSIGNED_TYPE>(in2); \ + return reinterpret_cast<TYPE&>(ures); \ +} + +JAVA_INTEGER_OP(+, java_add, jint, juint) +JAVA_INTEGER_OP(-, java_subtract, jint, juint) +JAVA_INTEGER_OP(*, java_multiply, jint, juint) +JAVA_INTEGER_OP(+, java_add, jlong, julong) +JAVA_INTEGER_OP(-, java_subtract, jlong, julong) +JAVA_INTEGER_OP(*, java_multiply, jlong, julong) + +#undef JAVA_INTEGER_OP + // Dereference vptr // All C++ compilers that we know of have the vtbl pointer in the first // word. If there are exceptions, this function needs to be made compiler diff --git a/src/share/vm/utilities/hashtable.cpp b/src/share/vm/utilities/hashtable.cpp --- a/src/share/vm/utilities/hashtable.cpp +++ b/src/share/vm/utilities/hashtable.cpp @@ -55,7 +55,7 @@ if (_first_free_entry + _entry_size >= _end_block) { int block_size = MIN2(512, MAX2((int)_table_size / 2, (int)_number_of_entries)); int len = _entry_size * block_size; - len = 1 << log2_intptr(len); // round down to power of 2 + len = 1 << log2_int(len); // round down to power of 2 assert(len >= _entry_size, ""); _first_free_entry = NEW_C_HEAP_ARRAY2(char, len, F, CURRENT_PC); _end_block = _first_free_entry + len; diff --git a/src/share/vm/utilities/vmError.cpp b/src/share/vm/utilities/vmError.cpp --- a/src/share/vm/utilities/vmError.cpp +++ b/src/share/vm/utilities/vmError.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, 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 @@ -1060,7 +1060,7 @@ out.print_raw (cmd); out.print_raw_cr("\" ..."); - if (os::fork_and_exec(cmd) < 0) { + if (os::fork_and_exec(cmd, true) < 0) { out.print_cr("os::fork_and_exec failed: %s (%d)", strerror(errno), errno); } } diff --git a/test/Makefile b/test/Makefile --- a/test/Makefile +++ b/test/Makefile @@ -262,6 +262,8 @@ # Default JTREG to run JTREG = $(JT_HOME)/bin/jtreg +# Use agent mode +JTREG_BASIC_OPTIONS += -agentvm # Only run automatic tests JTREG_BASIC_OPTIONS += -a # Report details on all failed or error tests, times too diff --git a/test/compiler/integerArithmetic/MultiplyByConstantLongMax.java b/test/compiler/integerArithmetic/MultiplyByConstantLongMax.java new file mode 100644 --- /dev/null +++ b/test/compiler/integerArithmetic/MultiplyByConstantLongMax.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. 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 8214189 + * @summary test/hotspot/jtreg/compiler/intrinsics/mathexact/MulExactLConstantTest.java fails on Windows x64 when run with -XX:-TieredCompilation + * + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement MultiplyByConstantLongMax + * + */ + +public class MultiplyByConstantLongMax { + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + if (test(1) != Long.MAX_VALUE) { + throw new RuntimeException("incorrect result"); + } + } + } + + private static long test(long v) { + return v * Long.MAX_VALUE; + } +} diff --git a/test/compiler/integerArithmetic/MultiplyByIntegerMinHang.java b/test/compiler/integerArithmetic/MultiplyByIntegerMinHang.java new file mode 100644 --- /dev/null +++ b/test/compiler/integerArithmetic/MultiplyByIntegerMinHang.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. 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 8213419 + * @summary C2 may hang in MulLNode::Ideal()/MulINode::Ideal() with gcc 8.2.1 + * + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement MultiplyByIntegerMinHang + * + */ + +public class MultiplyByIntegerMinHang { + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + if (test1(0) != 0) { + throw new RuntimeException("incorrect result"); + } + if (test1(1) != Integer.MIN_VALUE) { + throw new RuntimeException("incorrect result"); + } + if (test1(2) != 0) { + throw new RuntimeException("incorrect result"); + } + if (test2(0) != 0) { + throw new RuntimeException("incorrect result"); + } + if (test2(1) != Long.MIN_VALUE) { + throw new RuntimeException("incorrect result"); + } + if (test2(2) != 0) { + throw new RuntimeException("incorrect result"); + } + } + } + + private static int test1(int v) { + return v * Integer.MIN_VALUE; + } + + private static long test2(long v) { + return v * Long.MIN_VALUE; + } +} diff --git a/test/compiler/jsr292/RedefineMethodUsedByMultipleMethodHandles.java b/test/compiler/jsr292/RedefineMethodUsedByMultipleMethodHandles.java --- a/test/compiler/jsr292/RedefineMethodUsedByMultipleMethodHandles.java +++ b/test/compiler/jsr292/RedefineMethodUsedByMultipleMethodHandles.java @@ -26,7 +26,7 @@ * @bug 8042235 * @summary redefining method used by multiple MethodHandles crashes VM * @compile -XDignore.symbol.file RedefineMethodUsedByMultipleMethodHandles.java - * @run main RedefineMethodUsedByMultipleMethodHandles + * @run main/othervm RedefineMethodUsedByMultipleMethodHandles */ import java.io.*; diff --git a/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java b/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java --- a/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java +++ b/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ * -XX:+WhiteBoxAPI TestRTMTotalCountIncrRate */ +import sun.misc.Unsafe; import java.util.List; import com.oracle.java.testlibrary.*; @@ -96,14 +97,12 @@ Asserts.assertEQ(lock.getTotalLocks(), Test.TOTAL_ITERATIONS, "Total locks should be exactly the same as amount of " + "iterations."); - } else { - Asserts.assertGT(lock.getTotalLocks(), 0L, "RTM statistics " - + "should contain information for at least on lock."); } } public static class Test implements CompilableTest { private static final long TOTAL_ITERATIONS = 10000L; + private static final Unsafe UNSAFE = Utils.getUnsafe(); private final Object monitor = new Object(); // Following field have to be static in order to avoid escape analysis. @SuppressWarnings("UnsuedDeclaration") @@ -119,8 +118,17 @@ return new String[] { getMethodWithLockName() }; } - public void lock() { + public void lock(boolean forceAbort) { synchronized(monitor) { + if (forceAbort) { + // We're calling native method in order to force + // abort. It's done by explicit xabort call emitted + // in SharedRuntime::generate_native_wrapper. + // If an actual JNI call will be replaced by + // intrinsic - we'll be in trouble, since xabort + // will be no longer called and test may fail. + UNSAFE.addressSize(); + } Test.field++; } } @@ -139,7 +147,11 @@ for (long i = 0L; i < Test.TOTAL_ITERATIONS; i++) { AbortProvoker.verifyMonitorState(test.monitor, shouldBeInflated); - test.lock(); + // Force abort on first iteration to avoid rare case when + // there were no aborts and locks count was not incremented + // with RTMTotalCountIncrRate > 1 (in such case JVM won't + // print JVM locking statistics). + test.lock(i == 0); } } } diff --git a/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java b/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java --- a/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java +++ b/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java @@ -124,9 +124,6 @@ RTMLockingStatistics lock = statistics.get(0); - Asserts.assertGT(lock.getTotalLocks(), 0L, "RTM locking statistics " - + "should contain non zero total locks count"); - Asserts.assertGT(lock.getTotalAborts(), 0L, "RTM locking statistics should contain non zero total aborts " + "count"); diff --git a/test/gc/TestMemoryMXBeansAndPoolsPresence.java b/test/gc/TestMemoryMXBeansAndPoolsPresence.java new file mode 100644 --- /dev/null +++ b/test/gc/TestMemoryMXBeansAndPoolsPresence.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2017, 2019, 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 TestMemoryMXBeansAndPoolsPresence + * @key gc + * @bug 8191564 + * @summary Tests that GarbageCollectorMXBeans and GC MemoryPools are created. + * @library /testlibrary + * @requires vm.gc == null + * @run main/othervm -XX:+UseParallelGC TestMemoryMXBeansAndPoolsPresence Parallel + * @run main/othervm -XX:+UseSerialGC TestMemoryMXBeansAndPoolsPresence Serial + * @run main/othervm -XX:+UseConcMarkSweepGC TestMemoryMXBeansAndPoolsPresence CMS + * @run main/othervm -XX:+UseG1GC TestMemoryMXBeansAndPoolsPresence G1 + */ + +import java.util.List; +import java.util.ArrayList; +import java.lang.management.*; +import java.util.stream.*; + +import com.oracle.java.testlibrary.Asserts; + +class GCBeanDescription { + public String name; + public String[] poolNames; + + public GCBeanDescription(String name, String[] poolNames) { + this.name = name; + this.poolNames = poolNames; + } +} + +public class TestMemoryMXBeansAndPoolsPresence { + public static void test(GCBeanDescription... expectedBeans) { + List<MemoryPoolMXBean> memoryPools = ManagementFactory.getMemoryPoolMXBeans(); + + List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); + Asserts.assertEQ(expectedBeans.length, gcBeans.size()); + + for (GCBeanDescription desc : expectedBeans) { + List<GarbageCollectorMXBean> beans = gcBeans.stream() + .filter(b -> b.getName().equals(desc.name)) + .collect(Collectors.toList()); + Asserts.assertEQ(beans.size(), 1); + + GarbageCollectorMXBean bean = beans.get(0); + Asserts.assertEQ(desc.name, bean.getName()); + + String[] pools = bean.getMemoryPoolNames(); + Asserts.assertEQ(desc.poolNames.length, pools.length); + for (int i = 0; i < desc.poolNames.length; i++) { + Asserts.assertEQ(desc.poolNames[i], pools[i]); + } + } + } + + public static void main(String[] args) { + switch (args[0]) { + case "G1": + test(new GCBeanDescription("G1 Young Generation", new String[] {"G1 Eden Space", "G1 Survivor Space", "G1 Old Gen"}), + new GCBeanDescription("G1 Old Generation", new String[] {"G1 Eden Space", "G1 Survivor Space", "G1 Old Gen"})); + break; + case "CMS": + test(new GCBeanDescription("ParNew", new String[] {"Par Eden Space", "Par Survivor Space"}), + new GCBeanDescription("ConcurrentMarkSweep", new String[] {"Par Eden Space", "Par Survivor Space", "CMS Old Gen"})); + break; + case "Parallel": + test(new GCBeanDescription("PS Scavenge", new String[] {"PS Eden Space", "PS Survivor Space"}), + new GCBeanDescription("PS MarkSweep", new String[] {"PS Eden Space", "PS Survivor Space", "PS Old Gen"})); + break; + case "Serial": + test(new GCBeanDescription("Copy", new String[] {"Eden Space", "Survivor Space"}), + new GCBeanDescription("MarkSweepCompact", new String[] {"Eden Space", "Survivor Space", "Tenured Gen"})); + break; + default: + Asserts.assertTrue(false); + break; + + } + } +} diff --git a/test/gc/arguments/TestG1HeapRegionSize.java b/test/gc/arguments/TestG1HeapRegionSize.java --- a/test/gc/arguments/TestG1HeapRegionSize.java +++ b/test/gc/arguments/TestG1HeapRegionSize.java @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2013, 2018, 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 @@ -25,12 +25,11 @@ * @test TestG1HeapRegionSize * @key gc * @bug 8021879 - * @requires vm.gc=="G1" | vm.gc=="null" * @summary Verify that the flag G1HeapRegionSize is updated properly * @run main/othervm -Xmx64m TestG1HeapRegionSize 1048576 - * @run main/othervm -XX:G1HeapRegionSize=2m -Xmx64m -XX:+UseG1GC TestG1HeapRegionSize 2097152 - * @run main/othervm -XX:G1HeapRegionSize=3m -Xmx64m -XX:+UseG1GC TestG1HeapRegionSize 2097152 - * @run main/othervm -XX:G1HeapRegionSize=64m -Xmx256m -XX:+UseG1GC TestG1HeapRegionSize 33554432 + * @run main/othervm -XX:G1HeapRegionSize=2m -Xmx64m TestG1HeapRegionSize 2097152 + * @run main/othervm -XX:G1HeapRegionSize=3m -Xmx64m TestG1HeapRegionSize 2097152 + * @run main/othervm -XX:G1HeapRegionSize=64m -Xmx256m TestG1HeapRegionSize 33554432 */ import sun.management.ManagementFactoryHelper; @@ -43,7 +42,13 @@ HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); String expectedValue = getExpectedValue(args); - VMOption option = diagnostic.getVMOption("G1HeapRegionSize"); + VMOption option = diagnostic.getVMOption("UseG1GC"); + if (option.getValue().equals("false")) { + System.out.println("Skipping this test. It is only a G1 test."); + return; + } + + option = diagnostic.getVMOption("G1HeapRegionSize"); if (!expectedValue.equals(option.getValue())) { throw new RuntimeException("Wrong value for G1HeapRegionSize. Expected " + expectedValue + " but got " + option.getValue()); } diff --git a/test/gc/arguments/TestMaxHeapSizeTools.java b/test/gc/arguments/TestMaxHeapSizeTools.java --- a/test/gc/arguments/TestMaxHeapSizeTools.java +++ b/test/gc/arguments/TestMaxHeapSizeTools.java @@ -41,8 +41,8 @@ public long initialHeapSize; public long maxHeapSize; - public long minAlignment; - public long maxAlignment; + public long spaceAlignment; + public long heapAlignment; } class TestMaxHeapSizeTools { @@ -192,7 +192,7 @@ // Unfortunately there is no other way to retrieve the minimum heap size and // the alignments. - Matcher m = Pattern.compile("Minimum heap \\d+ Initial heap \\d+ Maximum heap \\d+ Min alignment \\d+ Max alignment \\d+"). + Matcher m = Pattern.compile("Minimum heap \\d+ Initial heap \\d+ Maximum heap \\d+ Space alignment \\d+ Heap alignment \\d+"). matcher(output.getStdout()); if (!m.find()) { throw new RuntimeException("Could not find heap size string."); @@ -204,8 +204,8 @@ val.minHeapSize = valueAfter(match, "Minimum heap "); val.initialHeapSize = valueAfter(match, "Initial heap "); val.maxHeapSize = valueAfter(match, "Maximum heap "); - val.minAlignment = valueAfter(match, "Min alignment "); - val.maxAlignment = valueAfter(match, "Max alignment "); + val.spaceAlignment = valueAfter(match, "Space alignment "); + val.heapAlignment = valueAfter(match, "Heap alignment "); } /** @@ -218,12 +218,12 @@ MinInitialMaxValues v = new MinInitialMaxValues(); getMinInitialMaxHeap(args, v); - if ((expectedMin != -1) && (align_up(expectedMin, v.minAlignment) != v.minHeapSize)) { + if ((expectedMin != -1) && (align_up(expectedMin, v.heapAlignment) != v.minHeapSize)) { throw new RuntimeException("Actual minimum heap size of " + v.minHeapSize + " differs from expected minimum heap size of " + expectedMin); } - if ((expectedInitial != -1) && (align_up(expectedInitial, v.minAlignment) != v.initialHeapSize)) { + if ((expectedInitial != -1) && (align_up(expectedInitial, v.heapAlignment) != v.initialHeapSize)) { throw new RuntimeException("Actual initial heap size of " + v.initialHeapSize + " differs from expected initial heap size of " + expectedInitial); } @@ -247,7 +247,7 @@ MinInitialMaxValues v = new MinInitialMaxValues(); getMinInitialMaxHeap(new String[] { gcflag, "-XX:MaxHeapSize=" + maxHeapsize + "M" }, v); - long expectedHeapSize = align_up(maxHeapsize * K * K, v.maxAlignment); + long expectedHeapSize = align_up(maxHeapsize * K * K, v.heapAlignment); long actualHeapSize = v.maxHeapSize; if (actualHeapSize > expectedHeapSize) { diff --git a/test/gc/g1/mixedgc/TestOldGenCollectionUsage.java b/test/gc/g1/mixedgc/TestOldGenCollectionUsage.java new file mode 100644 --- /dev/null +++ b/test/gc/g1/mixedgc/TestOldGenCollectionUsage.java @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2018, 2019, 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 TestOldGenCollectionUsage.java + * @bug 8195115 + * @summary G1 Old Gen's CollectionUsage.used is zero after mixed GC which is incorrect + * @key gc + * @requires vm.gc=="G1" | vm.gc=="null" + * @library /testlibrary /testlibrary/whitebox + * @build ClassFileInstaller com.oracle.java.testlibrary.* sun.hotspot.WhiteBox TestOldGenCollectionUsage + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -verbose:gc -XX:SurvivorRatio=1 -Xmx14m -Xms14m -XX:MaxTenuringThreshold=1 + * -XX:InitiatingHeapOccupancyPercent=100 -XX:G1MixedGCCountTarget=4 -XX:MaxGCPauseMillis=30000 + * -XX:G1HeapRegionSize=1m -XX:G1HeapWastePercent=0 -XX:G1MixedGCLiveThresholdPercent=100 + * TestOldGenCollectionUsage + */ + +import com.oracle.java.testlibrary.Asserts; +import sun.hotspot.WhiteBox; + +import java.util.ArrayList; +import java.util.List; +import java.util.Collections; + +import java.lang.management.*; + +// 8195115 says that for the "G1 Old Gen" MemoryPool, CollectionUsage.used +// is zero for G1 after a mixed collection, which is incorrect. + +public class TestOldGenCollectionUsage { + + private String poolName = "G1 Old Gen"; + private String collectorName = "G1 Young Generation"; + + public static void main(String [] args) throws Exception { + TestOldGenCollectionUsage t = new TestOldGenCollectionUsage(); + t.run(); + } + + public TestOldGenCollectionUsage() { + System.out.println("Monitor G1 Old Gen pool with G1 Young Generation collector."); + } + + public void run() { + // Find memory pool and collector + List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans(); + MemoryPoolMXBean pool = null; + boolean foundPool = false; + for (int i = 0; i < pools.size(); i++) { + pool = pools.get(i); + String name = pool.getName(); + if (name.contains(poolName)) { + System.out.println("Found pool: " + name); + foundPool = true; + break; + } + } + if (!foundPool) { + throw new RuntimeException(poolName + " not found, test with -XX:+UseG1GC"); + } + + List<GarbageCollectorMXBean> collectors = ManagementFactory.getGarbageCollectorMXBeans(); + GarbageCollectorMXBean collector = null; + boolean foundCollector = false; + for (int i = 0; i < collectors.size(); i++) { + collector = collectors.get(i); + String name = collector.getName(); + if (name.contains(collectorName)) { + System.out.println("Found collector: " + name); + foundCollector = true; + break; + } + } + if (!foundCollector) { + throw new RuntimeException(collectorName + " not found, test with -XX:+UseG1GC"); + } + + MixedGCProvoker gcProvoker = new MixedGCProvoker(); + gcProvoker.allocateOldObjects(); + + // Verify no non-zero result was stored + long usage = pool.getCollectionUsage().getUsed(); + System.out.println(poolName + ": usage after GC = " + usage); + if (usage > 0) { + throw new RuntimeException("Premature mixed collections(s)"); + } + + // Verify that collections were done + long collectionCount = collector.getCollectionCount(); + System.out.println(collectorName + ": collection count = " + + collectionCount); + long collectionTime = collector.getCollectionTime(); + System.out.println(collectorName + ": collection time = " + + collectionTime); + if (collectionCount <= 0) { + throw new RuntimeException("Collection count <= 0"); + } + if (collectionTime <= 0) { + throw new RuntimeException("Collector has not run"); + } + + gcProvoker.provokeMixedGC(); + + usage = pool.getCollectionUsage().getUsed(); + System.out.println(poolName + ": usage after GC = " + usage); + if (usage <= 0) { + throw new RuntimeException(poolName + " found with zero usage"); + } + + long newCollectionCount = collector.getCollectionCount(); + System.out.println(collectorName + ": collection count = " + + newCollectionCount); + long newCollectionTime = collector.getCollectionTime(); + System.out.println(collectorName + ": collection time = " + + newCollectionTime); + if (newCollectionCount <= collectionCount) { + throw new RuntimeException("No new collection"); + } + if (newCollectionTime <= collectionTime) { + throw new RuntimeException("Collector has not run some more"); + } + + System.out.println("Test passed."); + } + + /** + * Utility class to guarantee a mixed GC. The class allocates several arrays and + * promotes them to the oldgen. After that it tries to provoke mixed GC by + * allocating new objects. + * + * The necessary condition for guaranteed mixed GC is running MixedGCProvoker is + * running in VM with the following flags: -XX:MaxTenuringThreshold=1 -Xms12M + * -Xmx12M -XX:G1MixedGCLiveThresholdPercent=100 -XX:G1HeapWastePercent=0 + * -XX:G1HeapRegionSize=1m + */ + public class MixedGCProvoker { + private final WhiteBox WB = WhiteBox.getWhiteBox(); + private final List<byte[]> liveOldObjects = new ArrayList<>(); + private final List<byte[]> newObjects = new ArrayList<>(); + + public static final int ALLOCATION_SIZE = 20000; + public static final int ALLOCATION_COUNT = 15; + + public void allocateOldObjects() { + List<byte[]> deadOldObjects = new ArrayList<>(); + // Allocates buffer and promotes it to the old gen. Mix live and dead old + // objects + for (int i = 0; i < ALLOCATION_COUNT; ++i) { + liveOldObjects.add(new byte[ALLOCATION_SIZE * 5]); + deadOldObjects.add(new byte[ALLOCATION_SIZE * 5]); + } + + // Do two young collections, MaxTenuringThreshold=1 will force promotion. + // G1HeapRegionSize=1m guarantees that old gen regions will be filled. + WB.youngGC(); + WB.youngGC(); + // Check it is promoted & keep alive + Asserts.assertTrue(WB.isObjectInOldGen(liveOldObjects), + "List of the objects is suppose to be in OldGen"); + Asserts.assertTrue(WB.isObjectInOldGen(deadOldObjects), + "List of the objects is suppose to be in OldGen"); + } + + /** + * Waits until Concurent Mark Cycle finishes + * @param wb Whitebox instance + * @param sleepTime sleep time + */ + private void waitTillCMCFinished(int sleepTime) { + while (WB.g1InConcurrentMark()) { + if (sleepTime > -1) { + try { + Thread.sleep(sleepTime); + } catch (InterruptedException e) { + System.out.println("Got InterruptedException while waiting for ConcMarkCycle to finish"); + } + } + } + } + + public void provokeMixedGC() { + waitTillCMCFinished(0); + WB.g1StartConcMarkCycle(); + waitTillCMCFinished(0); + WB.youngGC(); + + System.out.println("Allocating new objects to provoke mixed GC"); + // Provoke a mixed collection. G1MixedGCLiveThresholdPercent=100 + // guarantees that full old gen regions will be included. + for (int i = 0; i < (ALLOCATION_COUNT * 20); i++) { + try { + newObjects.add(new byte[ALLOCATION_SIZE]); + } catch (OutOfMemoryError e) { + newObjects.clear(); + WB.youngGC(); + WB.youngGC(); + System.out.println("OutOfMemoryError is reported, stop allocating new objects"); + break; + } + } + // check that liveOldObjects still alive + Asserts.assertTrue(WB.isObjectInOldGen(liveOldObjects), + "List of the objects is suppose to be in OldGen"); + } + + } + +} diff --git a/test/runtime/6981737/Test6981737.java b/test/runtime/6981737/Test6981737.java --- a/test/runtime/6981737/Test6981737.java +++ b/test/runtime/6981737/Test6981737.java @@ -48,8 +48,6 @@ vendor_re = "Sun Microsystems Inc\\."; vm_spec_version_re = "1\\.0"; } - verifyProperty("java.vendor", vendor_re); - verifyProperty("java.vm.vendor", vendor_re); verifyProperty("java.vm.specification.vendor", vendor_re); verifyProperty("java.specification.vendor", vendor_re); verifyProperty("java.vm.specification.version", vm_spec_version_re); diff --git a/test/runtime/ErrorHandling/TestCrashOnOutOfMemoryError.java b/test/runtime/ErrorHandling/TestCrashOnOutOfMemoryError.java --- a/test/runtime/ErrorHandling/TestCrashOnOutOfMemoryError.java +++ b/test/runtime/ErrorHandling/TestCrashOnOutOfMemoryError.java @@ -25,7 +25,7 @@ * @test TestCrashOnOutOfMemoryError * @summary Test using -XX:+CrashOnOutOfMemoryError * @library /testlibrary - * @build jdk.test.lib.* + * @build com.oracle.java.testlibrary.* * @run driver TestCrashOnOutOfMemoryError * @bug 8138745 */ diff --git a/test/runtime/ErrorHandling/TestExitOnOutOfMemoryError.java b/test/runtime/ErrorHandling/TestExitOnOutOfMemoryError.java --- a/test/runtime/ErrorHandling/TestExitOnOutOfMemoryError.java +++ b/test/runtime/ErrorHandling/TestExitOnOutOfMemoryError.java @@ -25,7 +25,7 @@ * @test TestExitOnOutOfMemoryError * @summary Test using -XX:ExitOnOutOfMemoryError * @library /testlibrary - * @build jdk.test.lib.* + * @build com.oracle.java.testlibrary.* * @run driver TestExitOnOutOfMemoryError * @bug 8138745 */ diff --git a/test/runtime/NMT/JcmdDetailDiff.java b/test/runtime/NMT/JcmdDetailDiff.java --- a/test/runtime/NMT/JcmdDetailDiff.java +++ b/test/runtime/NMT/JcmdDetailDiff.java @@ -26,7 +26,6 @@ * @summary run NMT baseline, allocate memory and verify output from detail.diff * @key nmt jcmd * @library /testlibrary /testlibrary/whitebox - * @ignore * @build JcmdDetailDiff * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail JcmdDetailDiff diff --git a/test/runtime/NMT/MallocSiteTypeChange.java b/test/runtime/NMT/MallocSiteTypeChange.java new file mode 100644 --- /dev/null +++ b/test/runtime/NMT/MallocSiteTypeChange.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. 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 MallocSiteTypeChange + * @summary Test a malloc site type change results NMT to report deallocation of old type and allocation of new type + * @bug 8200109 + * @key nmt jcmd + * @modules java.base/jdk.internal.misc + * @library /testlibrary /testlibrary/whitebox + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocSiteTypeChange + */ + +import com.oracle.java.testlibrary.*; +import sun.hotspot.WhiteBox; + +public class MallocSiteTypeChange { + public static void main(String args[]) throws Exception { + OutputAnalyzer output; + WhiteBox wb = WhiteBox.getWhiteBox(); + + // Grab my own PID + String pid = Long.toString(ProcessTools.getProcessId()); + ProcessBuilder pb = new ProcessBuilder(); + + int pc = 1; + long addr = wb.NMTMallocWithPseudoStack(4 * 1024, pc); + + // Verify that current tracking level is "detail" + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"}); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("Test (reserved=4KB, committed=4KB)"); + + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "baseline"}); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("Baseline succeeded"); + + wb.NMTFree(addr); + addr = wb.NMTMallocWithPseudoStackAndType(2 * 1024, pc, 7 /* mtInternal */ ); + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail.diff"}); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("(malloc=0KB type=Test -4KB)"); + output.shouldContain("(malloc=2KB type=Internal +2KB #1 +1)"); + output.shouldHaveExitValue(0); + } +} diff --git a/test/runtime/StackGap/T.java b/test/runtime/StackGap/T.java new file mode 100644 --- /dev/null +++ b/test/runtime/StackGap/T.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. 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. + */ + +public class T { + + public static void test(int n) { + if (n == 0) return; + System.out.println (n); + test (n - 1); + + } + +} diff --git a/test/runtime/StackGap/exestack-gap.c b/test/runtime/StackGap/exestack-gap.c new file mode 100644 --- /dev/null +++ b/test/runtime/StackGap/exestack-gap.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include <jni.h> +#include <stdio.h> +#include <stdlib.h> + +JNIEnv* create_vm(JavaVM **jvm, char *extra_option) +{ + JNIEnv* env; + JavaVMInitArgs args; + JavaVMOption options[4]; + args.version = JNI_VERSION_1_8; + args.nOptions = 3 + (extra_option != NULL); + options[0].optionString = "-Xss2048k"; + char classpath[4096]; + snprintf(classpath, sizeof classpath, + "-Djava.class.path=%s", getenv("CLASSPATH")); + options[1].optionString = classpath; + options[2].optionString = "-XX:+UnlockExperimentalVMOptions"; + if (extra_option) { + options[3].optionString = extra_option; + } + args.options = &options[0]; + args.ignoreUnrecognized = 0; + int rv; + rv = JNI_CreateJavaVM(jvm, (void**)&env, &args); + if (rv < 0) return NULL; + return env; +} + +void run(char *extra_arg) { + JavaVM *jvm; + jclass T_class; + jmethodID test_method; + JNIEnv *env = create_vm(&jvm, extra_arg); + if (env == NULL) + exit(1); + T_class = (*env)->FindClass(env, "T"); + if ((*env)->ExceptionCheck(env) == JNI_TRUE) { + (*env)->ExceptionDescribe(env); + exit(1); + } + test_method = (*env)->GetStaticMethodID(env, T_class, "test", "(I)V"); + if ((*env)->ExceptionCheck(env) == JNI_TRUE) { + (*env)->ExceptionDescribe(env); + exit(1); + } + (*env)->CallStaticVoidMethod(env, T_class, test_method, 1000); +} + + +int main(int argc, char **argv) +{ + if (argc > 1) { + run(argv[1]); + } else { + run(NULL); + } + + return 0; +} diff --git a/test/runtime/StackGap/testme.sh b/test/runtime/StackGap/testme.sh new file mode 100644 --- /dev/null +++ b/test/runtime/StackGap/testme.sh @@ -0,0 +1,73 @@ +# Copyright (c) 2014, 2018, 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. +#!/bin/sh + +# +# @test testme.sh +# @bug 8197429 +# @summary Linux kernel stack guard should not cause segfaults on x86-32 +# @compile T.java +# @run shell testme.sh +# + +if [ "${TESTSRC}" = "" ] +then + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" +fi +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh + +if [ "${VM_OS}" != "linux" ] +then + echo "Test only valid for Linux" + exit 0 +fi + +gcc_cmd=`which gcc` +if [ "x$gcc_cmd" = "x" ]; then + echo "WARNING: gcc not found. Cannot execute test." 2>&1 + exit 0; +fi + +CFLAGS="-m${VM_BITS}" + +LD_LIBRARY_PATH=.:${COMPILEJAVA}/jre/lib/${VM_CPU}/${VM_TYPE}:/usr/lib:$LD_LIBRARY_PATH +export LD_LIBRARY_PATH + +cp ${TESTSRC}${FS}exestack-gap.c . + +# Copy the result of our @compile action: +cp ${TESTCLASSES}${FS}T.class . + +echo "Compilation flag: ${COMP_FLAG}" +# Note pthread may not be found thus invoke creation will fail to be created. +# Check to ensure you have a /usr/lib/libpthread.so if you don't please look +# for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation. + +$gcc_cmd -DLINUX ${CFLAGS} -o stack-gap \ + -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \ + -L${COMPILEJAVA}/jre/lib/${VM_CPU}/${VM_TYPE} \ + -ljvm -lpthread exestack-gap.c + +./stack-gap || exit $? +./stack-gap -XX:+DisablePrimordialThreadGuardPages || exit $? diff --git a/test/sanity/MismatchedWhiteBox/WhiteBox.java b/test/sanity/MismatchedWhiteBox/WhiteBox.java new file mode 100644 --- /dev/null +++ b/test/sanity/MismatchedWhiteBox/WhiteBox.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013, 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 WhiteBox + * @bug 8011675 + * @summary verify that whitebox can be used even if not all functions are declared in java-part + * @author igor.ignatyev@oracle.com + * @library /testlibrary + * @compile WhiteBox.java + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI sun.hotspot.WhiteBox + * @clean sun.hotspot.WhiteBox + */ + +package sun.hotspot; + +public class WhiteBox { + private static native void registerNatives(); + static { registerNatives(); } + public native int notExistedMethod(); + public native int getHeapOopSize(); + public static void main(String[] args) { + WhiteBox wb = new WhiteBox(); + if (wb.getHeapOopSize() < 0) { + throw new Error("wb.getHeapOopSize() < 0"); + } + boolean catched = false; + try { + wb.notExistedMethod(); + } catch (UnsatisfiedLinkError e) { + catched = true; + } + if (!catched) { + throw new Error("wb.notExistedMethod() was invoked"); + } + } +} diff --git a/test/sanity/WhiteBox.java b/test/sanity/WhiteBox.java deleted file mode 100644 --- a/test/sanity/WhiteBox.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2013, 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 WhiteBox - * @bug 8011675 - * @summary verify that whitebox can be used even if not all functions are declared in java-part - * @author igor.ignatyev@oracle.com - * @library /testlibrary - * @compile WhiteBox.java - * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI sun.hotspot.WhiteBox - * @clean sun.hotspot.WhiteBox - */ - -package sun.hotspot; - -public class WhiteBox { - private static native void registerNatives(); - static { registerNatives(); } - public native int notExistedMethod(); - public native int getHeapOopSize(); - public static void main(String[] args) { - WhiteBox wb = new WhiteBox(); - if (wb.getHeapOopSize() < 0) { - throw new Error("wb.getHeapOopSize() < 0"); - } - boolean catched = false; - try { - wb.notExistedMethod(); - } catch (UnsatisfiedLinkError e) { - catched = true; - } - if (!catched) { - throw new Error("wb.notExistedMethod() was invoked"); - } - } -} diff --git a/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java b/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java --- a/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java +++ b/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java @@ -152,6 +152,9 @@ args.add(javapath); Collections.addAll(args, getPlatformSpecificVMArgs()); + args.add("-cp"); + args.add(System.getProperty("java.class.path")); + if (addTestVmOptions) { String vmopts = System.getProperty("test.vm.opts"); if (vmopts != null && vmopts.length() > 0) { diff --git a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java --- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java +++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, 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 @@ -117,6 +117,7 @@ public native void NMTUncommitMemory(long addr, long size); public native void NMTReleaseMemory(long addr, long size); public native long NMTMallocWithPseudoStack(long size, int index); + public native long NMTMallocWithPseudoStackAndType(long size, int index, int type); public native boolean NMTIsDetailSupported(); public native boolean NMTChangeTrackingLevel(); public native int NMTGetHashSize();