# HG changeset patch # User amurillo # Date 1399049537 25200 # Node ID 058d96676d00cc0f62941375483fef56da12eb29 # Parent 0d1f816217dce5e72187f167cc1816080cbeb453# Parent 9e3d7b4e7041d44b0b788a6503b12d9d6d7c1885 Merge diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/aix/makefiles/buildtree.make --- a/hotspot/make/aix/makefiles/buildtree.make Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/aix/makefiles/buildtree.make Fri May 02 09:52:17 2014 -0700 @@ -37,7 +37,7 @@ # GAMMADIR - top of workspace # OS_FAMILY - operating system # VARIANT - core, compiler1, compiler2, or tiered -# HOTSPOT_RELEASE_VERSION - .-b (11.0-b07) +# HOTSPOT_RELEASE_VERSION - ..[-][-][-b] # HOTSPOT_BUILD_VERSION - internal, internal-$(USER_RELEASE_SUFFIX) or empty # JRE_RELEASE_VERSION - .. (1.7.0) # diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/aix/makefiles/mapfile-vers-debug --- a/hotspot/make/aix/makefiles/mapfile-vers-debug Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/aix/makefiles/mapfile-vers-debug Fri May 02 09:52:17 2014 -0700 @@ -122,7 +122,7 @@ JVM_GetClassModifiers; JVM_GetClassName; JVM_GetClassNameUTF; - JVM_GetClassSignature; + JVM_GetClassSignature; JVM_GetClassSigners; JVM_GetClassTypeAnnotations; JVM_GetComponentType; @@ -163,6 +163,7 @@ JVM_GetStackTraceElement; JVM_GetSystemPackage; JVM_GetSystemPackages; + JVM_GetTemporaryDirectory; JVM_GetThreadStateNames; JVM_GetThreadStateValues; JVM_GetVersionInfo; diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/aix/makefiles/mapfile-vers-product --- a/hotspot/make/aix/makefiles/mapfile-vers-product Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/aix/makefiles/mapfile-vers-product Fri May 02 09:52:17 2014 -0700 @@ -161,6 +161,7 @@ JVM_GetStackTraceElement; JVM_GetSystemPackage; JVM_GetSystemPackages; + JVM_GetTemporaryDirectory; JVM_GetThreadStateNames; JVM_GetThreadStateValues; JVM_GetVersionInfo; diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/aix/makefiles/vm.make --- a/hotspot/make/aix/makefiles/vm.make Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/aix/makefiles/vm.make Fri May 02 09:52:17 2014 -0700 @@ -73,17 +73,14 @@ endif endif -# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined -# in $(GAMMADIR)/make/defs.make -ifeq ($(HOTSPOT_BUILD_VERSION),) - BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HOTSPOT_RELEASE_VERSION)\"" -else - BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HOTSPOT_RELEASE_VERSION)-$(HOTSPOT_BUILD_VERSION)\"" -endif - # The following variables are defined in the generated flags.make file. -BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HS_BUILD_VER)\"" -JRE_VERSION = -DJRE_RELEASE_VERSION="\"$(JRE_RELEASE_VER)\"" +JDK_VER_DEFS = -DJDK_MAJOR_VERSION="\"$(JDK_MAJOR_VERSION)\"" \ + -DJDK_MINOR_VERSION="\"$(JDK_MINOR_VERSION)\"" \ + -DJDK_MICRO_VERSION="\"$(JDK_MICRO_VERSION)\"" \ + -DJDK_BUILD_NUMBER="\"$(JDK_BUILD_NUMBER)\"" +VM_VER_DEFS = -DHOTSPOT_RELEASE_VERSION="\"$(HS_BUILD_VER)\"" \ + -DJRE_RELEASE_VERSION="\"$(JRE_RELEASE_VER)\"" \ + $(JDK_VER_DEFS) HS_LIB_ARCH = -DHOTSPOT_LIB_ARCH=\"$(LIBARCH)\" BUILD_TARGET = -DHOTSPOT_BUILD_TARGET="\"$(TARGET)\"" BUILD_USER = -DHOTSPOT_BUILD_USER="\"$(HOTSPOT_BUILD_USER)\"" @@ -92,7 +89,6 @@ CXXFLAGS = \ ${SYSDEFS} \ ${INCLUDES} \ - ${BUILD_VERSION} \ ${BUILD_TARGET} \ ${BUILD_USER} \ ${HS_LIB_ARCH} \ @@ -101,7 +97,7 @@ # 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 += ${VM_VER_DEFS} CXXFLAGS/BYFILE = $(CXXFLAGS/$@) diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/bsd/makefiles/buildtree.make --- a/hotspot/make/bsd/makefiles/buildtree.make Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/bsd/makefiles/buildtree.make Fri May 02 09:52:17 2014 -0700 @@ -36,7 +36,7 @@ # GAMMADIR - top of workspace # OS_FAMILY - operating system # VARIANT - core, compiler1, compiler2, or tiered -# HOTSPOT_RELEASE_VERSION - .-b (11.0-b07) +# HOTSPOT_RELEASE_VERSION - ..[-][-][-b] # HOTSPOT_BUILD_VERSION - internal, internal-$(USER_RELEASE_SUFFIX) or empty # JRE_RELEASE_VERSION - .. (1.7.0) # diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug --- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Fri May 02 09:52:17 2014 -0700 @@ -161,6 +161,7 @@ _JVM_GetStackTraceElement _JVM_GetSystemPackage _JVM_GetSystemPackages + _JVM_GetTemporaryDirectory _JVM_GetThreadStateNames _JVM_GetThreadStateValues _JVM_GetVersionInfo diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/bsd/makefiles/mapfile-vers-darwin-product --- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Fri May 02 09:52:17 2014 -0700 @@ -161,6 +161,7 @@ _JVM_GetStackTraceElement _JVM_GetSystemPackage _JVM_GetSystemPackages + _JVM_GetTemporaryDirectory _JVM_GetThreadStateNames _JVM_GetThreadStateValues _JVM_GetVersionInfo diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/bsd/makefiles/mapfile-vers-debug --- a/hotspot/make/bsd/makefiles/mapfile-vers-debug Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug Fri May 02 09:52:17 2014 -0700 @@ -122,7 +122,7 @@ JVM_GetClassModifiers; JVM_GetClassName; JVM_GetClassNameUTF; - JVM_GetClassSignature; + JVM_GetClassSignature; JVM_GetClassSigners; JVM_GetClassTypeAnnotations; JVM_GetComponentType; @@ -163,6 +163,7 @@ JVM_GetStackTraceElement; JVM_GetSystemPackage; JVM_GetSystemPackages; + JVM_GetTemporaryDirectory; JVM_GetThreadStateNames; JVM_GetThreadStateValues; JVM_GetVersionInfo; diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/bsd/makefiles/mapfile-vers-product --- a/hotspot/make/bsd/makefiles/mapfile-vers-product Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-product Fri May 02 09:52:17 2014 -0700 @@ -163,6 +163,7 @@ JVM_GetStackTraceElement; JVM_GetSystemPackage; JVM_GetSystemPackages; + JVM_GetTemporaryDirectory; JVM_GetThreadStateNames; JVM_GetThreadStateValues; JVM_GetVersionInfo; diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/bsd/makefiles/vm.make --- a/hotspot/make/bsd/makefiles/vm.make Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/bsd/makefiles/vm.make Fri May 02 09:52:17 2014 -0700 @@ -72,17 +72,14 @@ endif endif -# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined -# in $(GAMMADIR)/make/defs.make -ifeq ($(HOTSPOT_BUILD_VERSION),) - BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HOTSPOT_RELEASE_VERSION)\"" -else - BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HOTSPOT_RELEASE_VERSION)-$(HOTSPOT_BUILD_VERSION)\"" -endif - # The following variables are defined in the generated flags.make file. -BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HS_BUILD_VER)\"" -JRE_VERSION = -DJRE_RELEASE_VERSION="\"$(JRE_RELEASE_VER)\"" +JDK_VER_DEFS = -DJDK_MAJOR_VERSION="\"$(JDK_MAJOR_VERSION)\"" \ + -DJDK_MINOR_VERSION="\"$(JDK_MINOR_VERSION)\"" \ + -DJDK_MICRO_VERSION="\"$(JDK_MICRO_VERSION)\"" \ + -DJDK_BUILD_NUMBER="\"$(JDK_BUILD_NUMBER)\"" +VM_VER_DEFS = -DHOTSPOT_RELEASE_VERSION="\"$(HS_BUILD_VER)\"" \ + -DJRE_RELEASE_VERSION="\"$(JRE_RELEASE_VER)\"" \ + $(JDK_VER_DEFS) HS_LIB_ARCH = -DHOTSPOT_LIB_ARCH=\"$(LIBARCH)\" BUILD_TARGET = -DHOTSPOT_BUILD_TARGET="\"$(TARGET)\"" BUILD_USER = -DHOTSPOT_BUILD_USER="\"$(HOTSPOT_BUILD_USER)\"" @@ -91,7 +88,6 @@ CXXFLAGS = \ ${SYSDEFS} \ ${INCLUDES} \ - ${BUILD_VERSION} \ ${BUILD_TARGET} \ ${BUILD_USER} \ ${HS_LIB_ARCH} \ @@ -100,7 +96,7 @@ # 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 += ${VM_VER_DEFS} CXXFLAGS/BYFILE = $(CXXFLAGS/$@) diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/defs.make --- a/hotspot/make/defs.make Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/defs.make Fri May 02 09:52:17 2014 -0700 @@ -114,7 +114,7 @@ endif # hotspot version definitions -include $(GAMMADIR)/make/hotspot_version +include $(GAMMADIR)/make/jdk_version # Java versions needed ifeq ($(PREVIOUS_JDK_VERSION),) @@ -129,6 +129,9 @@ ifeq ($(JDK_MICRO_VERSION),) JDK_MICRO_VERSION=$(JDK_MICRO_VER) endif +ifeq ($(JDK_BUILD_NUMBER),) + JDK_BUILD_NUMBER=0 +endif ifeq ($(JDK_MKTG_VERSION),) JDK_MKTG_VERSION=$(JDK_MINOR_VERSION).$(JDK_MICRO_VERSION) endif @@ -146,7 +149,7 @@ endif ifndef HOTSPOT_RELEASE_VERSION - HOTSPOT_RELEASE_VERSION=$(HS_MAJOR_VER).$(HS_MINOR_VER)-b$(HS_BUILD_NUMBER) + HOTSPOT_RELEASE_VERSION=$(FULL_VERSION) endif ifdef HOTSPOT_BUILD_VERSION @@ -325,7 +328,6 @@ MAKE_ARGS += OUTPUTDIR=$(ABS_OUTPUTDIR) MAKE_ARGS += GAMMADIR=$(ABS_GAMMADIR) MAKE_ARGS += MAKE_VERBOSE=$(MAKE_VERBOSE) -MAKE_ARGS += HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION) MAKE_ARGS += JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION) # Pass HOTSPOT_BUILD_VERSION as argument to OS specific Makefile diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/hotspot_version --- a/hotspot/make/hotspot_version Wed Jul 05 19:39:35 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -# -# Copyright (c) 2006, 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. -# - -# -# - -# -# Master Hotspot version file. These values may be overridden by a control -# workspace build. This file format must remain compatible with both -# GNU Makefile and Microsoft nmake formats. -# - -# Don't put quotes (fail windows build). -HOTSPOT_VM_COPYRIGHT=Copyright 2013 - -HS_MAJOR_VER=25 -HS_MINOR_VER=0 -HS_BUILD_NUMBER=62 - -JDK_MAJOR_VER=1 -JDK_MINOR_VER=8 -JDK_MICRO_VER=0 - -# Previous (bootdir) JDK version -JDK_PREVIOUS_VERSION=1.7.0 diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/jdk_version --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/make/jdk_version Fri May 02 09:52:17 2014 -0700 @@ -0,0 +1,36 @@ +# +# Copyright (c) 2006, 2014, 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. +# +# Master JDK version file. These values may be overridden by a control +# workspace build. This file format must remain compatible with both +# GNU Makefile and Microsoft nmake formats. +# + +# Don't put quotes (fail windows build). +HOTSPOT_VM_COPYRIGHT=Copyright 2014 + +JDK_MAJOR_VER=1 +JDK_MINOR_VER=9 +JDK_MICRO_VER=0 + +# Previous (bootdir) JDK version +JDK_PREVIOUS_VERSION=1.8.0 diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/linux/makefiles/buildtree.make --- a/hotspot/make/linux/makefiles/buildtree.make Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/linux/makefiles/buildtree.make Fri May 02 09:52:17 2014 -0700 @@ -36,7 +36,7 @@ # GAMMADIR - top of workspace # OS_FAMILY - operating system # VARIANT - core, compiler1, compiler2, or tiered -# HOTSPOT_RELEASE_VERSION - .-b (11.0-b07) +# HOTSPOT_RELEASE_VERSION - ..[-][-][-b] # HOTSPOT_BUILD_VERSION - internal, internal-$(USER_RELEASE_SUFFIX) or empty # JRE_RELEASE_VERSION - .. (1.7.0) # diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/linux/makefiles/mapfile-vers-debug --- a/hotspot/make/linux/makefiles/mapfile-vers-debug Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/linux/makefiles/mapfile-vers-debug Fri May 02 09:52:17 2014 -0700 @@ -122,7 +122,7 @@ JVM_GetClassModifiers; JVM_GetClassName; JVM_GetClassNameUTF; - JVM_GetClassSignature; + JVM_GetClassSignature; JVM_GetClassSigners; JVM_GetClassTypeAnnotations; JVM_GetComponentType; @@ -163,6 +163,7 @@ JVM_GetStackTraceElement; JVM_GetSystemPackage; JVM_GetSystemPackages; + JVM_GetTemporaryDirectory; JVM_GetThreadStateNames; JVM_GetThreadStateValues; JVM_GetVersionInfo; diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/linux/makefiles/mapfile-vers-product --- a/hotspot/make/linux/makefiles/mapfile-vers-product Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/linux/makefiles/mapfile-vers-product Fri May 02 09:52:17 2014 -0700 @@ -163,6 +163,7 @@ JVM_GetStackTraceElement; JVM_GetSystemPackage; JVM_GetSystemPackages; + JVM_GetTemporaryDirectory; JVM_GetThreadStateNames; JVM_GetThreadStateValues; JVM_GetVersionInfo; diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/linux/makefiles/vm.make --- a/hotspot/make/linux/makefiles/vm.make Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/linux/makefiles/vm.make Fri May 02 09:52:17 2014 -0700 @@ -73,17 +73,14 @@ endif endif -# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined -# in $(GAMMADIR)/make/defs.make -ifeq ($(HOTSPOT_BUILD_VERSION),) - BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HOTSPOT_RELEASE_VERSION)\"" -else - BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HOTSPOT_RELEASE_VERSION)-$(HOTSPOT_BUILD_VERSION)\"" -endif - # The following variables are defined in the generated flags.make file. -BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HS_BUILD_VER)\"" -JRE_VERSION = -DJRE_RELEASE_VERSION="\"$(JRE_RELEASE_VER)\"" +JDK_VER_DEFS = -DJDK_MAJOR_VERSION="\"$(JDK_MAJOR_VERSION)\"" \ + -DJDK_MINOR_VERSION="\"$(JDK_MINOR_VERSION)\"" \ + -DJDK_MICRO_VERSION="\"$(JDK_MICRO_VERSION)\"" \ + -DJDK_BUILD_NUMBER="\"$(JDK_BUILD_NUMBER)\"" +VM_VER_DEFS = -DHOTSPOT_RELEASE_VERSION="\"$(HS_BUILD_VER)\"" \ + -DJRE_RELEASE_VERSION="\"$(JRE_RELEASE_VER)\"" \ + $(JDK_VER_DEFS) HS_LIB_ARCH = -DHOTSPOT_LIB_ARCH=\"$(LIBARCH)\" BUILD_TARGET = -DHOTSPOT_BUILD_TARGET="\"$(TARGET)\"" BUILD_USER = -DHOTSPOT_BUILD_USER="\"$(HOTSPOT_BUILD_USER)\"" @@ -92,7 +89,6 @@ CXXFLAGS = \ ${SYSDEFS} \ ${INCLUDES} \ - ${BUILD_VERSION} \ ${BUILD_TARGET} \ ${BUILD_USER} \ ${HS_LIB_ARCH} \ @@ -101,7 +97,7 @@ # 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 += ${VM_VER_DEFS} CXXFLAGS/BYFILE = $(CXXFLAGS/$@) diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/solaris/makefiles/buildtree.make --- a/hotspot/make/solaris/makefiles/buildtree.make Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/solaris/makefiles/buildtree.make Fri May 02 09:52:17 2014 -0700 @@ -36,7 +36,7 @@ # GAMMADIR - top of workspace # OS_FAMILY - operating system # VARIANT - core, compiler1, compiler2, or tiered -# HOTSPOT_RELEASE_VERSION - .-b (11.0-b07) +# HOTSPOT_RELEASE_VERSION - ..[-][-][-b] # HOTSPOT_BUILD_VERSION - internal, internal-$(USER_RELEASE_SUFFIX) or empty # JRE_RELEASE_VERSION - .. (1.7.0) # diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/solaris/makefiles/mapfile-vers --- a/hotspot/make/solaris/makefiles/mapfile-vers Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/solaris/makefiles/mapfile-vers Fri May 02 09:52:17 2014 -0700 @@ -163,6 +163,7 @@ JVM_GetStackTraceElement; JVM_GetSystemPackage; JVM_GetSystemPackages; + JVM_GetTemporaryDirectory; JVM_GetThreadStateNames; JVM_GetThreadStateValues; JVM_GetVersionInfo; diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/solaris/makefiles/vm.make --- a/hotspot/make/solaris/makefiles/vm.make Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/solaris/makefiles/vm.make Fri May 02 09:52:17 2014 -0700 @@ -69,8 +69,13 @@ endif # The following variables are defined in the generated flags.make file. -BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HS_BUILD_VER)\"" -JRE_VERSION = -DJRE_RELEASE_VERSION="\"$(JRE_RELEASE_VER)\"" +JDK_VER_DEFS = -DJDK_MAJOR_VERSION="\"$(JDK_MAJOR_VERSION)\"" \ + -DJDK_MINOR_VERSION="\"$(JDK_MINOR_VERSION)\"" \ + -DJDK_MICRO_VERSION="\"$(JDK_MICRO_VERSION)\"" \ + -DJDK_BUILD_NUMBER="\"$(JDK_BUILD_NUMBER)\"" +VM_VER_DEFS = -DHOTSPOT_RELEASE_VERSION="\"$(HS_BUILD_VER)\"" \ + -DJRE_RELEASE_VERSION="\"$(JRE_RELEASE_VER)\"" \ + $(JDK_VER_DEFS) HS_LIB_ARCH = -DHOTSPOT_LIB_ARCH=\"$(LIBARCH)\" BUILD_TARGET = -DHOTSPOT_BUILD_TARGET="\"$(TARGET)\"" BUILD_USER = -DHOTSPOT_BUILD_USER="\"$(HOTSPOT_BUILD_USER)\"" @@ -79,7 +84,6 @@ CXXFLAGS = \ ${SYSDEFS} \ ${INCLUDES} \ - ${BUILD_VERSION} \ ${BUILD_TARGET} \ ${BUILD_USER} \ ${HS_LIB_ARCH} \ @@ -88,7 +92,7 @@ # 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 += ${VM_VER_DEFS} CXXFLAGS/BYFILE = $(CXXFLAGS/$@) diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/windows/build.make --- a/hotspot/make/windows/build.make Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/windows/build.make Fri May 02 09:52:17 2014 -0700 @@ -117,7 +117,7 @@ # These can be overridden via the nmake.exe command line. # They are overridden by RE during the control builds. # -!include "$(WorkSpace)/make/hotspot_version" +!include "$(WorkSpace)/make/jdk_version" # Define HOTSPOT_VM_DISTRO based on settings in make/openjdk_distro # or make/hotspot_distro. @@ -163,7 +163,7 @@ # 1.6.0-b01 will be 6.0.0.1 # 1.6.0_01a-b02 will be 6.0.11.2 # -# JDK_* variables are defined in make/hotspot_version or on command line +# JDK_* variables are defined in make/jdk_version or on command line # JDK_VER=$(JDK_MINOR_VER),$(JDK_MICRO_VER),$(JDK_UPDATE_VER),$(JDK_BUILD_NUMBER) JDK_DOTVER=$(JDK_MINOR_VER).$(JDK_MICRO_VER).$(JDK_UPDATE_VER).$(JDK_BUILD_NUMBER) @@ -179,13 +179,12 @@ # Hotspot Express VM FileVersion: # 10.0-b will have DLL version 10.0.0.yz (need 4 numbers). # -# HS_* variables are defined in make/hotspot_version # -HS_VER=$(HS_MAJOR_VER),$(HS_MINOR_VER),0,$(HS_BUILD_NUMBER) -HS_DOTVER=$(HS_MAJOR_VER).$(HS_MINOR_VER).0.$(HS_BUILD_NUMBER) +HS_VER=$(JDK_VER) +HS_DOTVER=$(JDK_DOTVER) !if "$(HOTSPOT_RELEASE_VERSION)" == "" -HOTSPOT_RELEASE_VERSION=$(HS_MAJOR_VER).$(HS_MINOR_VER)-b$(HS_BUILD_NUMBER) +HOTSPOT_RELEASE_VERSION=$(JRE_RELEASE_VERSION) !endif !if "$(HOTSPOT_BUILD_VERSION)" == "" diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/windows/makefiles/defs.make --- a/hotspot/make/windows/makefiles/defs.make Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/windows/makefiles/defs.make Fri May 02 09:52:17 2014 -0700 @@ -179,9 +179,9 @@ # next parameters are defined in $(GAMMADIR)/make/defs.make. MAKE_ARGS += JDK_MKTG_VERSION=$(JDK_MKTG_VERSION) -MAKE_ARGS += JDK_MAJOR_VER=$(JDK_MAJOR_VERSION) -MAKE_ARGS += JDK_MINOR_VER=$(JDK_MINOR_VERSION) -MAKE_ARGS += JDK_MICRO_VER=$(JDK_MICRO_VERSION) +MAKE_ARGS += JDK_MAJOR_VERSION=$(JDK_MAJOR_VERSION) +MAKE_ARGS += JDK_MINOR_VERSION=$(JDK_MINOR_VERSION) +MAKE_ARGS += JDK_MICRO_VERSION=$(JDK_MICRO_VERSION) ifdef COOKED_JDK_UPDATE_VERSION MAKE_ARGS += JDK_UPDATE_VER=$(COOKED_JDK_UPDATE_VERSION) diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/windows/makefiles/vm.make --- a/hotspot/make/windows/makefiles/vm.make Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/windows/makefiles/vm.make Fri May 02 09:52:17 2014 -0700 @@ -56,6 +56,10 @@ # The following variables are defined in the generated local.make file. CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_RELEASE_VERSION=\"$(HS_BUILD_VER)\"" +CXX_FLAGS=$(CXX_FLAGS) /D "JDK_MAJOR_VERSION=\"$(JDK_MAJOR_VERSION)\"" +CXX_FLAGS=$(CXX_FLAGS) /D "JDK_MINOR_VERSION=\"$(JDK_MINOR_VERSION)\"" +CXX_FLAGS=$(CXX_FLAGS) /D "JDK_MICRO_VERSION=\"$(JDK_MICRO_VERSION)\"" +CXX_FLAGS=$(CXX_FLAGS) /D "JDK_BUILD_NUMBER=\"$(JDK_BUILD_NUMBER)\"" CXX_FLAGS=$(CXX_FLAGS) /D "JRE_RELEASE_VERSION=\"$(JRE_RELEASE_VER)\"" CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_LIB_ARCH=\"$(HOTSPOT_LIB_ARCH)\"" CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_BUILD_TARGET=\"$(BUILD_FLAVOR)\"" diff -r 0d1f816217dc -r 058d96676d00 hotspot/make/windows/projectfiles/common/Makefile --- a/hotspot/make/windows/projectfiles/common/Makefile Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/make/windows/projectfiles/common/Makefile Fri May 02 09:52:17 2014 -0700 @@ -78,24 +78,23 @@ default:: $(AdditionalTargets) $(JvmtiGeneratedFiles) $(TraceGeneratedFiles) -!include $(HOTSPOTWORKSPACE)/make/hotspot_version +!include $(HOTSPOTWORKSPACE)/make/jdk_version !if "$(USER_RELEASE_SUFFIX)" != "" HOTSPOT_BUILD_VERSION = internal-$(USER_RELEASE_SUFFIX) !else HOTSPOT_BUILD_VERSION = internal !endif -!if "$(HOTSPOT_RELEASE_VERSION)" != "" -HOTSPOT_RELEASE_VERSION="\\\"$(HOTSPOT_RELEASE_VERSION)\\\"" -!else -HOTSPOT_RELEASE_VERSION="\\\"$(HS_MAJOR_VER).$(HS_MINOR_VER)-b$(HS_BUILD_NUMBER)-$(HOTSPOT_BUILD_VERSION)\\\"" -!endif !if "$(JRE_RELEASE_VERSION)" != "" JRE_RELEASE_VERSION="\\\"$(JRE_RELEASE_VERSION)\\\"" !else JRE_RELEASE_VERSION="\\\"$(JDK_MAJOR_VER).$(JDK_MINOR_VER).$(JDK_MICRO_VER)\\\"" !endif - +!if "$(HOTSPOT_RELEASE_VERSION)" != "" +HOTSPOT_RELEASE_VERSION="\\\"$(HOTSPOT_RELEASE_VERSION)\\\"" +!else +HOTSPOT_RELEASE_VERSION="\\\"$(JRE_RELEASE_VERSION)\\\"" +!endif # Define HOTSPOT_VM_DISTRO if HOTSPOT_VM_DISTRO is set, # and if it is not see if we have the src/closed directory !if "$(HOTSPOT_VM_DISTRO)" != "" diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/os/bsd/vm/os_bsd.cpp --- a/hotspot/src/os/bsd/vm/os_bsd.cpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Fri May 02 09:52:17 2014 -0700 @@ -127,8 +127,12 @@ // global variables julong os::Bsd::_physical_memory = 0; - +#ifdef __APPLE__ +mach_timebase_info_data_t os::Bsd::_timebase_info = {0, 0}; +volatile uint64_t os::Bsd::_max_abstime = 0; +#else int (*os::Bsd::_clock_gettime)(clockid_t, struct timespec *) = NULL; +#endif pthread_t os::Bsd::_main_thread; int os::Bsd::_page_size = -1; @@ -986,13 +990,15 @@ return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000); } +#ifndef __APPLE__ #ifndef CLOCK_MONOTONIC #define CLOCK_MONOTONIC (1) #endif +#endif #ifdef __APPLE__ void os::Bsd::clock_init() { - // XXXDARWIN: Investigate replacement monotonic clock + mach_timebase_info(&_timebase_info); } #else void os::Bsd::clock_init() { @@ -1007,10 +1013,39 @@ #endif + +#ifdef __APPLE__ + +jlong os::javaTimeNanos() { + const uint64_t tm = mach_absolute_time(); + const uint64_t now = (tm * Bsd::_timebase_info.numer) / Bsd::_timebase_info.denom; + const uint64_t prev = Bsd::_max_abstime; + if (now <= prev) { + return prev; // same or retrograde time; + } + const uint64_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&Bsd::_max_abstime, prev); + assert(obsv >= prev, "invariant"); // Monotonicity + // If the CAS succeeded then we're done and return "now". + // If the CAS failed and the observed value "obsv" is >= now then + // we should return "obsv". If the CAS failed and now > obsv > prv then + // some other thread raced this thread and installed a new value, in which case + // we could either (a) retry the entire operation, (b) retry trying to install now + // or (c) just return obsv. We use (c). No loop is required although in some cases + // we might discard a higher "now" value in deference to a slightly lower but freshly + // installed obsv value. That's entirely benign -- it admits no new orderings compared + // to (a) or (b) -- and greatly reduces coherence traffic. + // We might also condition (c) on the magnitude of the delta between obsv and now. + // Avoiding excessive CAS operations to hot RW locations is critical. + // See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate + return (prev == obsv) ? now : obsv; +} + +#else // __APPLE__ + jlong os::javaTimeNanos() { if (os::supports_monotonic_clock()) { struct timespec tp; - int status = Bsd::clock_gettime(CLOCK_MONOTONIC, &tp); + int status = Bsd::_clock_gettime(CLOCK_MONOTONIC, &tp); assert(status == 0, "gettime error"); jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec); return result; @@ -1023,6 +1058,8 @@ } } +#endif // __APPLE__ + void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { if (os::supports_monotonic_clock()) { info_ptr->max_value = ALL_64_BITS; diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/os/bsd/vm/os_bsd.hpp --- a/hotspot/src/os/bsd/vm/os_bsd.hpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/os/bsd/vm/os_bsd.hpp Fri May 02 09:52:17 2014 -0700 @@ -58,7 +58,13 @@ // For signal flags diagnostics static int sigflags[MAXSIGNUM]; +#ifdef __APPLE__ + // mach_absolute_time + static mach_timebase_info_data_t _timebase_info; + static volatile uint64_t _max_abstime; +#else static int (*_clock_gettime)(clockid_t, struct timespec *); +#endif static GrowableArray* _cpu_to_node; @@ -134,10 +140,6 @@ // Real-time clock functions static void clock_init(void); - static int clock_gettime(clockid_t clock_id, struct timespec *tp) { - return _clock_gettime ? _clock_gettime(clock_id, tp) : -1; - } - // Stack repair handling // none present diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/os/bsd/vm/os_bsd.inline.hpp --- a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp Fri May 02 09:52:17 2014 -0700 @@ -287,7 +287,11 @@ } inline bool os::supports_monotonic_clock() { +#ifdef __APPLE__ + return true; +#else return Bsd::_clock_gettime != NULL; +#endif } #endif // OS_BSD_VM_OS_BSD_INLINE_HPP diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/os/solaris/vm/os_solaris.cpp --- a/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Fri May 02 09:52:17 2014 -0700 @@ -347,11 +347,7 @@ static hrtime_t first_hrtime = 0; static const hrtime_t hrtime_hz = 1000*1000*1000; -const int LOCK_BUSY = 1; -const int LOCK_FREE = 0; -const int LOCK_INVALID = -1; static volatile hrtime_t max_hrtime = 0; -static volatile int max_hrtime_lock = LOCK_FREE; // Update counter with LSB as lock-in-progress void os::Solaris::initialize_system_info() { @@ -1364,58 +1360,31 @@ } -// gethrtime can move backwards if read from one cpu and then a different cpu -// getTimeNanos is guaranteed to not move backward on Solaris -// local spinloop created as faster for a CAS on an int than -// a CAS on a 64bit jlong. Also Atomic::cmpxchg for jlong is not -// supported on sparc v8 or pre supports_cx8 intel boxes. -// oldgetTimeNanos for systems which do not support CAS on 64bit jlong -// i.e. sparc v8 and pre supports_cx8 (i486) intel boxes -inline hrtime_t oldgetTimeNanos() { - int gotlock = LOCK_INVALID; - hrtime_t newtime = gethrtime(); - - for (;;) { -// grab lock for max_hrtime - int curlock = max_hrtime_lock; - if (curlock & LOCK_BUSY) continue; - if (gotlock = Atomic::cmpxchg(LOCK_BUSY, &max_hrtime_lock, LOCK_FREE) != LOCK_FREE) continue; - if (newtime > max_hrtime) { - max_hrtime = newtime; - } else { - newtime = max_hrtime; - } - // release lock - max_hrtime_lock = LOCK_FREE; - return newtime; - } -} -// gethrtime can move backwards if read from one cpu and then a different cpu -// getTimeNanos is guaranteed to not move backward on Solaris +// gethrtime() should be monotonic according to the documentation, +// but some virtualized platforms are known to break this guarantee. +// getTimeNanos() must be guaranteed not to move backwards, so we +// are forced to add a check here. inline hrtime_t getTimeNanos() { - if (VM_Version::supports_cx8()) { - const hrtime_t now = gethrtime(); - // Use atomic long load since 32-bit x86 uses 2 registers to keep long. - const hrtime_t prev = Atomic::load((volatile jlong*)&max_hrtime); - if (now <= prev) return prev; // same or retrograde time; - const hrtime_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&max_hrtime, prev); - assert(obsv >= prev, "invariant"); // Monotonicity - // If the CAS succeeded then we're done and return "now". - // If the CAS failed and the observed value "obs" is >= now then - // we should return "obs". If the CAS failed and now > obs > prv then - // some other thread raced this thread and installed a new value, in which case - // we could either (a) retry the entire operation, (b) retry trying to install now - // or (c) just return obs. We use (c). No loop is required although in some cases - // we might discard a higher "now" value in deference to a slightly lower but freshly - // installed obs value. That's entirely benign -- it admits no new orderings compared - // to (a) or (b) -- and greatly reduces coherence traffic. - // We might also condition (c) on the magnitude of the delta between obs and now. - // Avoiding excessive CAS operations to hot RW locations is critical. - // See http://blogs.sun.com/dave/entry/cas_and_cache_trivia_invalidate - return (prev == obsv) ? now : obsv ; - } else { - return oldgetTimeNanos(); - } + const hrtime_t now = gethrtime(); + const hrtime_t prev = max_hrtime; + if (now <= prev) { + return prev; // same or retrograde time; + } + const hrtime_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&max_hrtime, prev); + assert(obsv >= prev, "invariant"); // Monotonicity + // If the CAS succeeded then we're done and return "now". + // If the CAS failed and the observed value "obsv" is >= now then + // we should return "obsv". If the CAS failed and now > obsv > prv then + // some other thread raced this thread and installed a new value, in which case + // we could either (a) retry the entire operation, (b) retry trying to install now + // or (c) just return obsv. We use (c). No loop is required although in some cases + // we might discard a higher "now" value in deference to a slightly lower but freshly + // installed obsv value. That's entirely benign -- it admits no new orderings compared + // to (a) or (b) -- and greatly reduces coherence traffic. + // We might also condition (c) on the magnitude of the delta between obsv and now. + // Avoiding excessive CAS operations to hot RW locations is critical. + // See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate + return (prev == obsv) ? now : obsv; } // Time since start-up in seconds to a fine granularity. diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/os/windows/vm/os_windows.cpp --- a/hotspot/src/os/windows/vm/os_windows.cpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Fri May 02 09:52:17 2014 -0700 @@ -130,6 +130,13 @@ case DLL_PROCESS_DETACH: if(ForceTimeHighResolution) timeEndPeriod(1L); + + // Workaround for issue when a custom launcher doesn't call + // DestroyJavaVM and NMT is trying to track memory when free is + // called from a static destructor + if (MemTracker::is_on()) { + MemTracker::shutdown(MemTracker::NMT_normal); + } break; default: break; diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/classfile/javaClasses.cpp --- a/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Fri May 02 09:52:17 2014 -0700 @@ -421,6 +421,15 @@ return UNICODE::as_utf8(position, len); } +char* java_lang_String::as_utf8_string(oop java_string, int start, int len, char* buf, int buflen) { + typeArrayOop value = java_lang_String::value(java_string); + int offset = java_lang_String::offset(java_string); + int length = java_lang_String::length(java_string); + assert(start + len <= length, "just checking"); + jchar* position = value->char_at_addr(offset + start); + return UNICODE::as_utf8(position, len, buf, buflen); +} + bool java_lang_String::equals(oop java_string, jchar* chars, int len) { assert(java_string->klass() == SystemDictionary::String_klass(), "must be java_string"); diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/classfile/javaClasses.hpp --- a/hotspot/src/share/vm/classfile/javaClasses.hpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Fri May 02 09:52:17 2014 -0700 @@ -162,6 +162,7 @@ static char* as_utf8_string(oop java_string); static char* as_utf8_string(oop java_string, char* buf, int buflen); static char* as_utf8_string(oop java_string, int start, int len); + static char* as_utf8_string(oop java_string, int start, int len, char* buf, int buflen); static char* as_platform_dependent_str(Handle java_string, TRAPS); static jchar* as_unicode_string(oop java_string, int& length, TRAPS); // produce an ascii string with all other values quoted using \u#### diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Fri May 02 09:52:17 2014 -0700 @@ -1282,6 +1282,7 @@ Universe::verify(VerifyOption_G1UsePrevMarking, " VerifyDuringGC:(before)"); } + g1h->check_bitmaps("Remark Start"); G1CollectorPolicy* g1p = g1h->g1_policy(); g1p->record_concurrent_mark_remark_start(); @@ -1330,6 +1331,7 @@ Universe::verify(VerifyOption_G1UseNextMarking, " VerifyDuringGC:(after)"); } + g1h->check_bitmaps("Remark End"); assert(!restart_for_overflow(), "sanity"); // Completely reset the marking state since marking completed set_non_marking_state(); @@ -1979,6 +1981,7 @@ Universe::verify(VerifyOption_G1UsePrevMarking, " VerifyDuringGC:(before)"); } + g1h->check_bitmaps("Cleanup Start"); G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy(); g1p->record_concurrent_mark_cleanup_start(); @@ -2133,6 +2136,7 @@ Universe::verify(VerifyOption_G1UsePrevMarking, " VerifyDuringGC:(after)"); } + g1h->check_bitmaps("Cleanup End"); g1h->verify_region_sets_optional(); g1h->trace_heap_after_concurrent_cycle(); @@ -3224,6 +3228,11 @@ void ConcurrentMark::abort() { // Clear all marks to force marking thread to do nothing _nextMarkBitMap->clearAll(); + + // Note we cannot clear the previous marking bitmap here + // since VerifyDuringGC verifies the objects marked during + // a full GC against the previous bitmap. + // Clear the liveness counting data clear_all_count_data(); // Empty mark stack diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri May 02 09:52:17 2014 -0700 @@ -768,6 +768,7 @@ // match new_top. assert(hr == NULL || (hr->end() == new_end && hr->top() == new_top), "sanity"); + check_bitmaps("Humongous Region Allocation", first_hr); assert(first_hr->used() == word_size * HeapWordSize, "invariant"); _summary_bytes_used += first_hr->used(); @@ -1326,6 +1327,7 @@ verify_before_gc(); + check_bitmaps("Full GC Start"); pre_full_gc_dump(gc_timer); COMPILER2_PRESENT(DerivedPointerTable::clear()); @@ -1499,6 +1501,18 @@ verify_after_gc(); + // Clear the previous marking bitmap, if needed for bitmap verification. + // Note we cannot do this when we clear the next marking bitmap in + // ConcurrentMark::abort() above since VerifyDuringGC verifies the + // objects marked during a full GC against the previous bitmap. + // But we need to clear it before calling check_bitmaps below since + // the full GC has compacted objects and updated TAMS but not updated + // the prev bitmap. + if (G1VerifyBitmaps) { + ((CMBitMap*) concurrent_mark()->prevMarkBitMap())->clearAll(); + } + check_bitmaps("Full GC End"); + // Start a new incremental collection set for the next pause assert(g1_policy()->collection_set() == NULL, "must be"); g1_policy()->start_incremental_cset_building(); @@ -3978,6 +3992,7 @@ increment_gc_time_stamp(); verify_before_gc(); + check_bitmaps("GC Start"); COMPILER2_PRESENT(DerivedPointerTable::clear()); @@ -4223,6 +4238,7 @@ increment_gc_time_stamp(); verify_after_gc(); + check_bitmaps("GC End"); assert(!ref_processor_stw()->discovery_enabled(), "Postcondition"); ref_processor_stw()->verify_no_references_recorded(); @@ -5945,6 +5961,11 @@ assert(!hr->is_empty(), "the region should not be empty"); assert(free_list != NULL, "pre-condition"); + if (G1VerifyBitmaps) { + MemRegion mr(hr->bottom(), hr->end()); + concurrent_mark()->clearRangePrevBitmap(mr); + } + // Clear the card counts for this region. // Note: we only need to do this if the region is not young // (since we don't refine cards in young regions). @@ -6079,7 +6100,87 @@ void G1CollectedHeap::verify_dirty_young_regions() { verify_dirty_young_list(_young_list->first_region()); } -#endif + +bool G1CollectedHeap::verify_no_bits_over_tams(const char* bitmap_name, CMBitMapRO* bitmap, + HeapWord* tams, HeapWord* end) { + guarantee(tams <= end, + err_msg("tams: "PTR_FORMAT" end: "PTR_FORMAT, tams, end)); + HeapWord* result = bitmap->getNextMarkedWordAddress(tams, end); + if (result < end) { + gclog_or_tty->cr(); + gclog_or_tty->print_cr("## wrong marked address on %s bitmap: "PTR_FORMAT, + bitmap_name, result); + gclog_or_tty->print_cr("## %s tams: "PTR_FORMAT" end: "PTR_FORMAT, + bitmap_name, tams, end); + return false; + } + return true; +} + +bool G1CollectedHeap::verify_bitmaps(const char* caller, HeapRegion* hr) { + CMBitMapRO* prev_bitmap = concurrent_mark()->prevMarkBitMap(); + CMBitMapRO* next_bitmap = (CMBitMapRO*) concurrent_mark()->nextMarkBitMap(); + + HeapWord* bottom = hr->bottom(); + HeapWord* ptams = hr->prev_top_at_mark_start(); + HeapWord* ntams = hr->next_top_at_mark_start(); + HeapWord* end = hr->end(); + + bool res_p = verify_no_bits_over_tams("prev", prev_bitmap, ptams, end); + + bool res_n = true; + // We reset mark_in_progress() before we reset _cmThread->in_progress() and in this window + // we do the clearing of the next bitmap concurrently. Thus, we can not verify the bitmap + // if we happen to be in that state. + if (mark_in_progress() || !_cmThread->in_progress()) { + res_n = verify_no_bits_over_tams("next", next_bitmap, ntams, end); + } + if (!res_p || !res_n) { + gclog_or_tty->print_cr("#### Bitmap verification failed for "HR_FORMAT, + HR_FORMAT_PARAMS(hr)); + gclog_or_tty->print_cr("#### Caller: %s", caller); + return false; + } + return true; +} + +void G1CollectedHeap::check_bitmaps(const char* caller, HeapRegion* hr) { + if (!G1VerifyBitmaps) return; + + guarantee(verify_bitmaps(caller, hr), "bitmap verification"); +} + +class G1VerifyBitmapClosure : public HeapRegionClosure { +private: + const char* _caller; + G1CollectedHeap* _g1h; + bool _failures; + +public: + G1VerifyBitmapClosure(const char* caller, G1CollectedHeap* g1h) : + _caller(caller), _g1h(g1h), _failures(false) { } + + bool failures() { return _failures; } + + virtual bool doHeapRegion(HeapRegion* hr) { + if (hr->continuesHumongous()) return false; + + bool result = _g1h->verify_bitmaps(_caller, hr); + if (!result) { + _failures = true; + } + return false; + } +}; + +void G1CollectedHeap::check_bitmaps(const char* caller) { + if (!G1VerifyBitmaps) return; + + G1VerifyBitmapClosure cl(caller, this); + heap_region_iterate(&cl); + guarantee(!cl.failures(), "bitmap verification"); +} +#endif // PRODUCT void G1CollectedHeap::cleanUpCardTable() { G1SATBCardTableModRefBS* ct_bs = g1_barrier_set(); @@ -6464,6 +6565,7 @@ if (new_alloc_region != NULL) { set_region_short_lived_locked(new_alloc_region); _hr_printer.alloc(new_alloc_region, G1HRPrinter::Eden, young_list_full); + check_bitmaps("Mutator Region Allocation", new_alloc_region); return new_alloc_region; } } @@ -6530,8 +6632,10 @@ if (survivor) { new_alloc_region->set_survivor(); _hr_printer.alloc(new_alloc_region, G1HRPrinter::Survivor); + check_bitmaps("Survivor Region Allocation", new_alloc_region); } else { _hr_printer.alloc(new_alloc_region, G1HRPrinter::Old); + check_bitmaps("Old Region Allocation", new_alloc_region); } bool during_im = g1_policy()->during_initial_mark_pause(); new_alloc_region->note_start_of_copying(during_im); diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri May 02 09:52:17 2014 -0700 @@ -1186,6 +1186,30 @@ void verify_dirty_young_list(HeapRegion* head) PRODUCT_RETURN; void verify_dirty_young_regions() PRODUCT_RETURN; +#ifndef PRODUCT + // Make sure that the given bitmap has no marked objects in the + // range [from,limit). If it does, print an error message and return + // false. Otherwise, just return true. bitmap_name should be "prev" + // or "next". + bool verify_no_bits_over_tams(const char* bitmap_name, CMBitMapRO* bitmap, + HeapWord* from, HeapWord* limit); + + // Verify that the prev / next bitmap range [tams,end) for the given + // region has no marks. Return true if all is well, false if errors + // are detected. + bool verify_bitmaps(const char* caller, HeapRegion* hr); +#endif // PRODUCT + + // If G1VerifyBitmaps is set, verify that the marking bitmaps for + // the given region do not have any spurious marks. If errors are + // detected, print appropriate error messages and crash. + void check_bitmaps(const char* caller, HeapRegion* hr) PRODUCT_RETURN; + + // If G1VerifyBitmaps is set, verify that the marking bitmaps do not + // have any spurious marks. If errors are detected, print + // appropriate error messages and crash. + void check_bitmaps(const char* caller) PRODUCT_RETURN; + // verify_region_sets() performs verification over the region // lists. It will be compiled in the product code to be used when // necessary (i.e., during heap verification). diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp Fri May 02 09:52:17 2014 -0700 @@ -191,6 +191,7 @@ hr->note_self_forwarding_removal_start(during_initial_mark, during_conc_mark); + _g1h->check_bitmaps("Self-Forwarding Ptr Removal", hr); // In the common case (i.e. when there is no evacuation // failure) we make sure that the following is done when diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Fri May 02 09:52:17 2014 -0700 @@ -325,11 +325,14 @@ "evacuation pauses") \ \ diagnostic(bool, G1VerifyRSetsDuringFullGC, false, \ - "If true, perform verification of each heap region's " \ - "remembered set when verifying the heap during a full GC.") \ + "If true, perform verification of each heap region's " \ + "remembered set when verifying the heap during a full GC.") \ \ diagnostic(bool, G1VerifyHeapRegionCodeRoots, false, \ - "Verify the code root lists attached to each heap region.") + "Verify the code root lists attached to each heap region.") \ + \ + develop(bool, G1VerifyBitmaps, false, \ + "Verifies the consistency of the marking bitmaps") G1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG) diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/oops/klass.cpp --- a/hotspot/src/share/vm/oops/klass.cpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/oops/klass.cpp Fri May 02 09:52:17 2014 -0700 @@ -488,6 +488,7 @@ } void Klass::restore_unshareable_info(TRAPS) { + TRACE_INIT_ID(this); // If an exception happened during CDS restore, some of these fields may already be // set. We leave the class on the CLD list, even if incomplete so that we don't // modify the CLD list outside a safepoint. diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/prims/jni.cpp --- a/hotspot/src/share/vm/prims/jni.cpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/prims/jni.cpp Fri May 02 09:52:17 2014 -0700 @@ -3150,11 +3150,9 @@ } else { //%note jni_7 if (len > 0) { - ResourceMark rm(THREAD); - char *utf_region = java_lang_String::as_utf8_string(s, start, len); - int utf_len = (int)strlen(utf_region); - memcpy(buf, utf_region, utf_len); - buf[utf_len] = 0; + // Assume the buffer is large enough as the JNI spec. does not require user error checking + java_lang_String::as_utf8_string(s, start, len, buf, INT_MAX); + // as_utf8_string null-terminates the result string } else { // JDK null-terminates the buffer even in len is zero if (buf != NULL) { @@ -3880,6 +3878,7 @@ void TestOldSize_test(); void TestKlass_test(); void TestBitMap_test(); +void TestAsUtf8(); #if INCLUDE_ALL_GCS void TestOldFreeSpaceCalculation_test(); void TestG1BiasedArray_test(); @@ -3907,6 +3906,7 @@ run_unit_test(TestOldSize_test()); run_unit_test(TestKlass_test()); run_unit_test(TestBitMap_test()); + run_unit_test(TestAsUtf8()); #if INCLUDE_VM_STRUCTS run_unit_test(VMStructs::test()); #endif diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/prims/jvm.cpp --- a/hotspot/src/share/vm/prims/jvm.cpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/prims/jvm.cpp Fri May 02 09:52:17 2014 -0700 @@ -386,6 +386,23 @@ JVM_END +/* + * Return the temporary directory that the VM uses for the attach + * and perf data files. + * + * It is important that this directory is well-known and the + * same for all VM instances. It cannot be affected by configuration + * variables such as java.io.tmpdir. + */ +JVM_ENTRY(jstring, JVM_GetTemporaryDirectory(JNIEnv *env)) + JVMWrapper("JVM_GetTemporaryDirectory"); + HandleMark hm(THREAD); + const char* temp_dir = os::get_temp_directory(); + Handle h = java_lang_String::create_from_platform_dependent_str(temp_dir, CHECK_NULL); + return (jstring) JNIHandles::make_local(env, h()); +JVM_END + + // java.lang.Runtime ///////////////////////////////////////////////////////////////////////// extern volatile jint vm_created; diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/prims/jvm.h --- a/hotspot/src/share/vm/prims/jvm.h Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/prims/jvm.h Fri May 02 09:52:17 2014 -0700 @@ -1485,6 +1485,9 @@ JNIEXPORT jobject JNICALL JVM_InitAgentProperties(JNIEnv *env, jobject agent_props); +JNIEXPORT jstring JNICALL +JVM_GetTemporaryDirectory(JNIEnv *env); + /* Generics reflection support. * * Returns information about the given class's EnclosingMethod @@ -1553,12 +1556,10 @@ * ========================================================================== */ typedef struct { - /* HotSpot Express VM version string: - * .-bxx[-][-] - */ - unsigned int jvm_version; /* Consists of major.minor.0.build */ - unsigned int update_version : 8; /* 0 in HotSpot Express VM */ - unsigned int special_update_version : 8; /* 0 in HotSpot Express VM */ + /* VM version string: follows the JDK release version naming convention */ + unsigned int jvm_version; /* ..[-][-][-b] */ + unsigned int update_version : 8; + unsigned int special_update_version : 8; unsigned int reserved1 : 16; unsigned int reserved2; @@ -1577,11 +1578,7 @@ #define JVM_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24) #define JVM_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16) -// Micro version is 0 in HotSpot Express VM (set in jvm.cpp). #define JVM_VERSION_MICRO(version) ((version & 0x0000FF00) >> 8) -/* Build number is available in all HotSpot Express VM builds. - * It is defined in make/hotspot_version file. - */ #define JVM_VERSION_BUILD(version) ((version & 0x000000FF)) JNIEXPORT void JNICALL diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/runtime/os.hpp --- a/hotspot/src/share/vm/runtime/os.hpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/runtime/os.hpp Fri May 02 09:52:17 2014 -0700 @@ -48,6 +48,9 @@ #ifdef TARGET_OS_FAMILY_bsd # include "jvm_bsd.h" # include +# ifdef __APPLE__ +# include +# endif #endif class AgentLibrary; diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/runtime/vmStructs.cpp --- a/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Fri May 02 09:52:17 2014 -0700 @@ -1218,6 +1218,7 @@ static_field(Abstract_VM_Version, _s_internal_vm_info_string, const char*) \ static_field(Abstract_VM_Version, _vm_major_version, int) \ static_field(Abstract_VM_Version, _vm_minor_version, int) \ + static_field(Abstract_VM_Version, _vm_micro_version, int) \ static_field(Abstract_VM_Version, _vm_build_number, int) \ static_field(Abstract_VM_Version, _reserve_for_allocation_prefetch, int) \ \ diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/runtime/vm_version.cpp --- a/hotspot/src/share/vm/runtime/vm_version.cpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/runtime/vm_version.cpp Fri May 02 09:52:17 2014 -0700 @@ -55,6 +55,20 @@ #ifndef HOTSPOT_RELEASE_VERSION #error HOTSPOT_RELEASE_VERSION must be defined #endif + +#ifndef JDK_MAJOR_VERSION + #error JDK_MAJOR_VERSION must be defined +#endif +#ifndef JDK_MINOR_VERSION + #error JDK_MINOR_VERSION must be defined +#endif +#ifndef JDK_MICRO_VERSION + #error JDK_MICRO_VERSION must be defined +#endif +#ifndef JDK_BUILD_NUMBER + #error JDK_BUILD_NUMBER must be defined +#endif + #ifndef JRE_RELEASE_VERSION #error JRE_RELEASE_VERSION must be defined #endif @@ -68,39 +82,44 @@ #define VM_RELEASE HOTSPOT_RELEASE_VERSION "-" HOTSPOT_BUILD_TARGET #endif -// HOTSPOT_RELEASE_VERSION must follow the release version naming convention -// .-b[-][-] +// HOTSPOT_RELEASE_VERSION follows the JDK release version naming convention +// ..[-][-][-b] int Abstract_VM_Version::_vm_major_version = 0; int Abstract_VM_Version::_vm_minor_version = 0; +int Abstract_VM_Version::_vm_micro_version = 0; int Abstract_VM_Version::_vm_build_number = 0; bool Abstract_VM_Version::_initialized = false; int Abstract_VM_Version::_parallel_worker_threads = 0; bool Abstract_VM_Version::_parallel_worker_threads_initialized = false; +#ifdef ASSERT +static void assert_digits(const char * s, const char * message) { + for (int i = 0; s[i] != '\0'; i++) { + assert(isdigit(s[i]), message); + } +} +#endif + +static void set_version_field(int * version_field, const char * version_str, + const char * const assert_msg) { + if (version_str != NULL && *version_str != '\0') { + DEBUG_ONLY(assert_digits(version_str, assert_msg)); + *version_field = atoi(version_str); + } +} + void Abstract_VM_Version::initialize() { if (_initialized) { return; } - char* vm_version = os::strdup(HOTSPOT_RELEASE_VERSION); - // Expecting the next vm_version format: - // .-b[-] - char* vm_major_ver = vm_version; - assert(isdigit(vm_major_ver[0]),"wrong vm major version number"); - char* vm_minor_ver = strchr(vm_major_ver, '.'); - assert(vm_minor_ver != NULL && isdigit(vm_minor_ver[1]),"wrong vm minor version number"); - vm_minor_ver[0] = '\0'; // terminate vm_major_ver - vm_minor_ver += 1; - char* vm_build_num = strchr(vm_minor_ver, '-'); - assert(vm_build_num != NULL && vm_build_num[1] == 'b' && isdigit(vm_build_num[2]),"wrong vm build number"); - vm_build_num[0] = '\0'; // terminate vm_minor_ver - vm_build_num += 2; + set_version_field(&_vm_major_version, JDK_MAJOR_VERSION, "bad major version"); + set_version_field(&_vm_minor_version, JDK_MINOR_VERSION, "bad minor version"); + set_version_field(&_vm_micro_version, JDK_MICRO_VERSION, "bad micro version"); + int offset = (JDK_BUILD_NUMBER != NULL && JDK_BUILD_NUMBER[0] == 'b') ? 1 : 0; + set_version_field(&_vm_build_number, JDK_BUILD_NUMBER + offset, + "bad build number"); - _vm_major_version = atoi(vm_major_ver); - _vm_minor_version = atoi(vm_minor_ver); - _vm_build_number = atoi(vm_build_num); - - os::free(vm_version); _initialized = true; } @@ -276,6 +295,7 @@ unsigned int Abstract_VM_Version::jvm_version() { return ((Abstract_VM_Version::vm_major_version() & 0xFF) << 24) | ((Abstract_VM_Version::vm_minor_version() & 0xFF) << 16) | + ((Abstract_VM_Version::vm_micro_version() & 0xFF) << 8) | (Abstract_VM_Version::vm_build_number() & 0xFF); } diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/runtime/vm_version.hpp --- a/hotspot/src/share/vm/runtime/vm_version.hpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/runtime/vm_version.hpp Fri May 02 09:52:17 2014 -0700 @@ -44,6 +44,7 @@ static unsigned int _logical_processors_per_package; static int _vm_major_version; static int _vm_minor_version; + static int _vm_micro_version; static int _vm_build_number; static bool _initialized; static int _parallel_worker_threads; @@ -68,6 +69,7 @@ static int vm_major_version() { assert(_initialized, "not initialized"); return _vm_major_version; } static int vm_minor_version() { assert(_initialized, "not initialized"); return _vm_minor_version; } + static int vm_micro_version() { assert(_initialized, "not initialized"); return _vm_micro_version; } static int vm_build_number() { assert(_initialized, "not initialized"); return _vm_build_number; } // Gets the jvm_version_info.jvm_version defined in jvm.h diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/services/memTracker.cpp --- a/hotspot/src/share/vm/services/memTracker.cpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/services/memTracker.cpp Fri May 02 09:52:17 2014 -0700 @@ -785,7 +785,7 @@ MEMFLAGS flags, address pc) { assert(old_addr != NULL && new_addr != NULL, "Sanity check"); assert(_op == Realloc || _op == NoOp, "Wrong call"); - if (MemTracker::is_on() && NMT_CAN_TRACK(flags) && _op != NoOp) { + if (MemTracker::is_on() && NMT_CAN_TRACK(flags) && _op != NoOp && !MemTracker::shutdown_in_progress()) { assert(_seq > 0, "Need pre-reserve sequence number"); if (_need_thread_critical_lock) { ThreadCritical tc; @@ -811,7 +811,7 @@ // OOM already? if (addr == NULL) return; - if (MemTracker::is_on() && NMT_CAN_TRACK(flags) && _op != NoOp) { + if (MemTracker::is_on() && NMT_CAN_TRACK(flags) && _op != NoOp && !MemTracker::shutdown_in_progress()) { bool pre_reserved_seq = (_seq != 0); address pc = CALLER_CALLER_PC; MEMFLAGS orig_flags = flags; diff -r 0d1f816217dc -r 058d96676d00 hotspot/src/share/vm/utilities/utf8.cpp --- a/hotspot/src/share/vm/utilities/utf8.cpp Wed Jul 05 19:39:35 2017 +0200 +++ b/hotspot/src/share/vm/utilities/utf8.cpp Fri May 02 09:52:17 2014 -0700 @@ -329,23 +329,19 @@ char* UNICODE::as_utf8(jchar* base, int length) { int utf8_len = utf8_length(base, length); - u_char* result = NEW_RESOURCE_ARRAY(u_char, utf8_len + 1); - u_char* p = result; - for (int index = 0; index < length; index++) { - p = utf8_write(p, base[index]); - } - *p = '\0'; - assert(p == &result[utf8_len], "length prediction must be correct"); - return (char*) result; + u_char* buf = NEW_RESOURCE_ARRAY(u_char, utf8_len + 1); + char* result = as_utf8(base, length, (char*) buf, utf8_len + 1); + assert((int) strlen(result) == utf8_len, "length prediction must be correct"); + return result; } char* UNICODE::as_utf8(jchar* base, int length, char* buf, int buflen) { u_char* p = (u_char*)buf; - u_char* end = (u_char*)buf + buflen; for (int index = 0; index < length; index++) { jchar c = base[index]; - if (p + utf8_size(c) >= end) break; // string is truncated - p = utf8_write(p, base[index]); + buflen -= utf8_size(c); + if (buflen <= 0) break; // string is truncated + p = utf8_write(p, c); } *p = '\0'; return buf; @@ -389,3 +385,29 @@ } *p = '\0'; } + +#ifndef PRODUCT +void TestAsUtf8() { + char res[60]; + jchar str[20]; + + for (int i = 0; i < 20; i++) { + str[i] = 0x0800; // char that is 2B in UTF-16 but 3B in UTF-8 + } + str[19] = (jchar)'\0'; + + // The resulting string in UTF-8 is 3*19 bytes long, but should be truncated + UNICODE::as_utf8(str, 19, res, 10); + assert(strlen(res) == 9, "string should be truncated here"); + + UNICODE::as_utf8(str, 19, res, 18); + assert(strlen(res) == 15, "string should be truncated here"); + + UNICODE::as_utf8(str, 19, res, 20); + assert(strlen(res) == 18, "string should be truncated here"); + + // Test with an "unbounded" buffer + UNICODE::as_utf8(str, 19, res, INT_MAX); + assert(strlen(res) == 3*19, "string should end here"); +} +#endif