Merge
authoramurillo
Fri, 02 May 2014 09:52:17 -0700
changeset 24246 058d96676d00
parent 24229 0d1f816217dc (current diff)
parent 24245 9e3d7b4e7041 (diff)
child 24247 ca74accc73cf
child 24330 4e65b09f7101
child 24332 8e5759b26d4f
child 24354 d6e52809bcb8
Merge
hotspot/make/hotspot_version
--- 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 - <major>.<minor>-b<nn> (11.0-b07)
+# HOTSPOT_RELEASE_VERSION - <major_ver>.<minor_ver>.<micro_ver>[-<identifier>][-<debug_target>][-b<nn>]
 # HOTSPOT_BUILD_VERSION   - internal, internal-$(USER_RELEASE_SUFFIX) or empty
 # JRE_RELEASE_VERSION     - <major>.<minor>.<micro> (1.7.0)
 #
--- 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;
--- 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;
--- 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/$@)
 
--- 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 - <major>.<minor>-b<nn> (11.0-b07)
+# HOTSPOT_RELEASE_VERSION - <major_ver>.<minor_ver>.<micro_ver>[-<identifier>][-<debug_target>][-b<nn>]
 # HOTSPOT_BUILD_VERSION   - internal, internal-$(USER_RELEASE_SUFFIX) or empty
 # JRE_RELEASE_VERSION     - <major>.<minor>.<micro> (1.7.0)
 #
--- 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
--- 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
--- 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;
--- 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;
--- 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/$@)
 
--- 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
--- 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
--- /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
--- 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 - <major>.<minor>-b<nn> (11.0-b07)
+# HOTSPOT_RELEASE_VERSION - <major_ver>.<minor_ver>.<micro_ver>[-<identifier>][-<debug_target>][-b<nn>]
 # HOTSPOT_BUILD_VERSION   - internal, internal-$(USER_RELEASE_SUFFIX) or empty
 # JRE_RELEASE_VERSION     - <major>.<minor>.<micro> (1.7.0)
 #
--- 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;
--- 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;
--- 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/$@)
 
--- 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 - <major>.<minor>-b<nn> (11.0-b07)
+# HOTSPOT_RELEASE_VERSION - <major_ver>.<minor_ver>.<micro_ver>[-<identifier>][-<debug_target>][-b<nn>]
 # HOTSPOT_BUILD_VERSION   - internal, internal-$(USER_RELEASE_SUFFIX) or empty
 # JRE_RELEASE_VERSION     - <major>.<minor>.<micro> (1.7.0)
 #
--- 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;
--- 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/$@)
 
--- 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<yz> 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)" == ""
--- 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)
--- 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)\""
--- 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)" != ""
--- 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;
--- 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<int>* _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
--- 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
--- 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.
--- 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;
--- 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");
--- 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####
--- 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
--- 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);
--- 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).
--- 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
--- 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)
 
--- 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.
--- 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
--- 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;
--- 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:
-     * <major>.<minor>-bxx[-<identifier>][-<debug_flavor>]
-     */
-    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; /* <major_ver>.<minor_ver>.<micro_ver>[-<identifier>][-<debug_target>][-b<nn>]  */
+    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
--- 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 <setjmp.h>
+# ifdef __APPLE__
+#  include <mach/mach_time.h>
+# endif
 #endif
 
 class AgentLibrary;
--- 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)                                   \
                                                                                                                                      \
--- 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
-// <major_ver>.<minor_ver>-b<nn>[-<identifier>][-<debug_target>]
+// HOTSPOT_RELEASE_VERSION follows the JDK release version naming convention
+// <major_ver>.<minor_ver>.<micro_ver>[-<identifier>][-<debug_target>][-b<nn>]
 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:
-  // <major_ver>.<minor_ver>-b<nn>[-<identifier>]
-  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);
 }
 
--- 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
--- 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;
--- 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