changeset 28709:4746a63313f6

Merge
author duke
date Wed, 05 Jul 2017 20:17:28 +0200
parents ac59fe6cd98f 4adaea63f465
children 5b8db585a33c
files jdk/make/data/checkdeps/refs.allowed jdk/make/src/classes/build/tools/deps/CheckDeps.java jdk/src/java.base/aix/native/libnet/java/net/aix_close.c jdk/src/java.base/unix/classes/java/lang/UNIXProcess.java jdk/src/java.base/unix/native/libjava/UNIXProcess_md.c jdk/src/java.base/unix/native/libjava/java_props_macosx.c jdk/src/java.base/unix/native/libjava/java_props_macosx.h jdk/src/java.base/unix/native/libnet/bsd_close.c jdk/src/java.base/unix/native/libnet/linux_close.c jdk/src/java.base/unix/native/libnet/solaris_close.c jdk/src/jdk.security.auth/unix/native/libjaas/Solaris.c jdk/test/java/lang/CharSequence/DefaultTest.java jdk/test/java/util/ResourceBundle/Bug6287579.java
diffstat 275 files changed, 14094 insertions(+), 6007 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags-top-repo	Thu Jan 29 15:36:21 2015 -0800
+++ b/.hgtags-top-repo	Wed Jul 05 20:17:28 2017 +0200
@@ -290,3 +290,4 @@
 3dd628fde2086218d548841022ee8436b6b88185 jdk9-b45
 12f1e276447bcc81516e85367d53e4f08897049d jdk9-b46
 b6cca3e6175a69f39e5799b7349ddb0176630291 jdk9-b47
+0064e246d83f6f9fc245c19b6d05041ecaf4b6d4 jdk9-b48
--- a/common/autoconf/basics.m4	Thu Jan 29 15:36:21 2015 -0800
+++ b/common/autoconf/basics.m4	Wed Jul 05 20:17:28 2017 +0200
@@ -987,3 +987,26 @@
     IS_RECONFIGURE=no
   fi
 ])
+
+# Check for support for specific options in bash
+AC_DEFUN_ONCE([BASIC_CHECK_BASH_OPTIONS],
+[
+  # Test if bash supports pipefail.
+  AC_MSG_CHECKING([if bash supports pipefail])
+  if ${BASH} -c 'set -o pipefail'; then
+    BASH_ARGS="$BASH_ARGS -o pipefail"
+    AC_MSG_RESULT([yes])
+  else
+    AC_MSG_RESULT([no])
+  fi
+
+  AC_MSG_CHECKING([if bash supports errexit (-e)])
+  if ${BASH} -e -c 'true'; then
+    BASH_ARGS="$BASH_ARGS -e"
+    AC_MSG_RESULT([yes])
+  else
+    AC_MSG_RESULT([no])
+  fi
+
+  AC_SUBST(BASH_ARGS)
+])
--- a/common/autoconf/bootcycle-spec.gmk.in	Thu Jan 29 15:36:21 2015 -0800
+++ b/common/autoconf/bootcycle-spec.gmk.in	Wed Jul 05 20:17:28 2017 +0200
@@ -46,8 +46,12 @@
 BOOT_JDK := $(JDK_IMAGE_DIR)
 
 # The bootcycle build has a different output directory
-BUILD_OUTPUT:=@BUILD_OUTPUT@/bootcycle-build
-SJAVAC_SERVER_DIR:=$(subst @BUILD_OUTPUT@,$(BUILD_OUTPUT),$(SJAVAC_SERVER_DIR))
+OLD_BUILD_OUTPUT:=@BUILD_OUTPUT@
+BUILD_OUTPUT:=$(OLD_BUILD_OUTPUT)/bootcycle-build
+# The HOTSPOT_DIST dir is not defined relative to BUILD_OUTPUT in spec.gmk. Must not
+# use space in this patsubst to avoid leading space in HOTSPOT_DIST.
+HOTSPOT_DIST:=$(patsubst $(OLD_BUILD_OUTPUT)%,$(BUILD_OUTPUT)%,$(HOTSPOT_DIST))
+SJAVAC_SERVER_DIR:=$(patsubst $(OLD_BUILD_OUTPUT)%, $(BUILD_OUTPUT)%, $(SJAVAC_SERVER_DIR))
 
 JAVA_CMD:=$(BOOT_JDK)/bin/java
 JAVAC_CMD:=$(BOOT_JDK)/bin/javac
--- a/common/autoconf/configure.ac	Thu Jan 29 15:36:21 2015 -0800
+++ b/common/autoconf/configure.ac	Wed Jul 05 20:17:28 2017 +0200
@@ -113,6 +113,7 @@
 
 # Setup tools that requires more complex handling, or that is not needed by the configure script.
 BASIC_SETUP_COMPLEX_TOOLS
+BASIC_CHECK_BASH_OPTIONS
 
 # Check if pkg-config is available.
 PKG_PROG_PKG_CONFIG
--- a/common/autoconf/generated-configure.sh	Thu Jan 29 15:36:21 2015 -0800
+++ b/common/autoconf/generated-configure.sh	Wed Jul 05 20:17:28 2017 +0200
@@ -853,6 +853,7 @@
 OS_VERSION_MINOR
 OS_VERSION_MAJOR
 PKG_CONFIG
+BASH_ARGS
 CODESIGN
 XATTR
 DSYMUTIL
@@ -3522,6 +3523,9 @@
 
 
 
+# Check for support for specific options in bash
+
+
 #
 # Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -4329,7 +4333,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1420811523
+DATE_WHEN_GENERATED=1421247827
 
 ###############################################################################
 #
@@ -19609,6 +19613,32 @@
   fi
 
 
+  # Test if bash supports pipefail.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if bash supports pipefail" >&5
+$as_echo_n "checking if bash supports pipefail... " >&6; }
+  if ${BASH} -c 'set -o pipefail'; then
+    BASH_ARGS="$BASH_ARGS -o pipefail"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if bash supports errexit (-e)" >&5
+$as_echo_n "checking if bash supports errexit (-e)... " >&6; }
+  if ${BASH} -e -c 'true'; then
+    BASH_ARGS="$BASH_ARGS -e"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  fi
+
+
+
+
 # Check if pkg-config is available.
 
 
@@ -27408,8 +27438,8 @@
     # The trailing space for everyone except PATH is no typo, but is needed due
     # to trailing \ in the Windows paths. These will be stripped later.
     $ECHO "$WINPATH_BASH -c 'echo VS_PATH="'\"$PATH\" > set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
-    $ECHO "$WINPATH_BASH -c 'echo VS_INCLUDE="'\"$INCLUDE\;$include \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
-    $ECHO "$WINPATH_BASH -c 'echo VS_LIB="'\"$LIB\;$lib \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
+    $ECHO "$WINPATH_BASH -c 'echo VS_INCLUDE="'\"$INCLUDE \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
+    $ECHO "$WINPATH_BASH -c 'echo VS_LIB="'\"$LIB \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
     $ECHO "$WINPATH_BASH -c 'echo VCINSTALLDIR="'\"$VCINSTALLDIR \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
     $ECHO "$WINPATH_BASH -c 'echo WindowsSdkDir="'\"$WindowsSdkDir \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
     $ECHO "$WINPATH_BASH -c 'echo WINDOWSSDKDIR="'\"$WINDOWSSDKDIR \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
--- a/common/autoconf/spec.gmk.in	Thu Jan 29 15:36:21 2015 -0800
+++ b/common/autoconf/spec.gmk.in	Wed Jul 05 20:17:28 2017 +0200
@@ -78,6 +78,11 @@
 OUTPUT_SYNC_SUPPORTED:=@OUTPUT_SYNC_SUPPORTED@
 OUTPUT_SYNC:=@OUTPUT_SYNC@
 
+# Override the shell with bash
+BASH:=@BASH@
+BASH_ARGS:=@BASH_ARGS@
+SHELL:=$(BASH) $(BASH_ARGS)
+
 # The "human readable" name of this configuration
 CONF_NAME:=@CONF_NAME@
 
@@ -243,7 +248,7 @@
 HOTSPOT_OUTPUTDIR=$(BUILD_OUTPUT)/hotspot
 JDK_OUTPUTDIR=$(BUILD_OUTPUT)/jdk
 IMAGES_OUTPUTDIR=$(BUILD_OUTPUT)/images
-TESTMAKE_OUTPUTDIR=$(BUILD_OUTPUT)/testmake
+TESTMAKE_OUTPUTDIR=$(BUILD_OUTPUT)/test-make
 MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/make-support
 
 HOTSPOT_DIST=@HOTSPOT_DIST@
@@ -495,7 +500,6 @@
 # Tools adhering to a minimal and common standard of posix compliance.
 AWK:=@AWK@
 BASENAME:=@BASENAME@
-BASH:=@BASH@
 CAT:=@CAT@
 CCACHE:=@CCACHE@
 # CD is going away, but remains to cater for legacy makefiles.
--- a/corba/.hgtags	Thu Jan 29 15:36:21 2015 -0800
+++ b/corba/.hgtags	Wed Jul 05 20:17:28 2017 +0200
@@ -290,3 +290,4 @@
 9e3f2bed80c0e5a84a256ce41f1d10c5ade48466 jdk9-b45
 326f2068b4a4c05e2fa27d6acf93eba7b54b090d jdk9-b46
 ee8447ca632e1d39180b4767c749db101bff7314 jdk9-b47
+a13c49c5f2899b702652a460ed7aa73123e671e6 jdk9-b48
--- a/hotspot/.hgtags	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/.hgtags	Wed Jul 05 20:17:28 2017 +0200
@@ -450,3 +450,4 @@
 5dc8184af1e2bb30b0103113d1f1a58a21a80c37 jdk9-b45
 a184ee1d717297bd35b7c3e35393e137921a3ed2 jdk9-b46
 3b241fb72b8925b75941d612db762a6d5da66d02 jdk9-b47
+cc775a4a24c7f5d9e624b4205e9fbd48a17331f6 jdk9-b48
--- a/hotspot/make/aix/Makefile	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/make/aix/Makefile	Wed Jul 05 20:17:28 2017 +0200
@@ -246,8 +246,7 @@
 XSLT_CHECK	= $(REMOTE) $(RUN.JAVAP) javax.xml.transform.TransformerFactory
 # If not found then fail fast.
 check_j2se_version:
-	$(QUIETLY) $(XSLT_CHECK) > /dev/null 2>&1; \
-	if [ $$? -ne 0 ]; then \
+	$(QUIETLY) if ! $(XSLT_CHECK) > /dev/null 2>&1; then \
 	  $(REMOTE) $(RUN.JAVA) -version; \
 	  echo "*** An XSLT processor (J2SE 1.4.x or newer) is required" \
 	  "to bootstrap this build" 1>&2; \
--- a/hotspot/make/aix/makefiles/xlc.make	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/make/aix/makefiles/xlc.make	Wed Jul 05 20:17:28 2017 +0200
@@ -74,6 +74,12 @@
 # no xlc counterpart for -fcheck-new
 # CFLAGS += -fcheck-new
 
+# We need to define this on the command line if we want to use the the
+# predefined format specifiers from "inttypes.h". Otherwise system headrs
+# can indirectly include inttypes.h before we define __STDC_FORMAT_MACROS
+# in globalDefinitions.hpp
+CFLAGS += -D__STDC_FORMAT_MACROS
+
 ARCHFLAG = -q64
 
 CFLAGS     += $(ARCHFLAG)
--- a/hotspot/make/bsd/Makefile	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/make/bsd/Makefile	Wed Jul 05 20:17:28 2017 +0200
@@ -240,8 +240,7 @@
 XSLT_CHECK	= $(REMOTE) $(RUN.JAVAP) javax.xml.transform.TransformerFactory
 # If not found then fail fast.
 check_j2se_version:
-	$(QUIETLY) $(XSLT_CHECK) > /dev/null 2>&1; \
-	if [ $$? -ne 0 ]; then \
+	$(QUIETLY) if ! $(XSLT_CHECK) > /dev/null 2>&1; then \
 	  $(REMOTE) $(RUN.JAVA) -version; \
 	  echo "*** An XSLT processor (J2SE 1.4.x or newer) is required" \
 	  "to bootstrap this build" 1>&2; \
--- a/hotspot/make/bsd/makefiles/dtrace.make	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/make/bsd/makefiles/dtrace.make	Wed Jul 05 20:17:28 2017 +0200
@@ -179,23 +179,23 @@
 # $@.tmp is created first to avoid an empty $(JVMOFFS).h if an error occurs.
 $(JVMOFFS).h: $(GENOFFS)
 	$(QUIETLY) DYLD_LIBRARY_PATH=.:$(DYLD_LIBRARY_PATH) ./$(GENOFFS) -header > $@.tmp; touch $@; \
-	if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
-	then rm -f $@; mv $@.tmp $@; \
-	else rm -f $@.tmp; \
+	if diff $@.tmp $@ > /dev/null 2>&1 ; \
+	then rm -f $@.tmp; \
+	else rm -f $@; mv $@.tmp $@; \
 	fi
 
 $(JVMOFFS)Index.h: $(GENOFFS)
 	$(QUIETLY) DYLD_LIBRARY_PATH=.:$(DYLD_LIBRARY_PATH) ./$(GENOFFS) -index > $@.tmp; touch $@; \
-	if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
-	then rm -f $@; mv $@.tmp $@; \
-	else rm -f $@.tmp; \
+	if diff $@.tmp $@ > /dev/null 2>&1 ; \
+	then rm -f $@.tmp; \
+	else rm -f $@; mv $@.tmp $@; \
 	fi
 
 $(JVMOFFS).cpp: $(GENOFFS) $(JVMOFFS).h $(JVMOFFS)Index.h
 	$(QUIETLY) DYLD_LIBRARY_PATH=.:$(DYLD_LIBRARY_PATH) ./$(GENOFFS) -table > $@.tmp; touch $@; \
-	if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
-	then rm -f $@; mv $@.tmp $@; \
-	else rm -f $@.tmp; \
+	if diff $@.tmp $@ > /dev/null 2>&1; \
+	then rm -f $@.tmp; \
+	else rm -f $@; mv $@.tmp $@; \
 	fi
 
 $(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp 
--- a/hotspot/make/bsd/makefiles/universal.gmk	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/make/bsd/makefiles/universal.gmk	Wed Jul 05 20:17:28 2017 +0200
@@ -59,7 +59,7 @@
 
 # Package built libraries in a universal binary
 $(UNIVERSAL_LIPO_LIST):
-	BUILT_LIPO_FILES="`find $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) 2>/dev/null`"; \
+	BUILT_LIPO_FILES="`find $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) 2>/dev/null`" || test $$? = "1"; \
 	if [ -n "$${BUILT_LIPO_FILES}" ]; then \
 	  $(MKDIR) -p $(shell dirname $@); \
 	  lipo -create -output $@ $${BUILT_LIPO_FILES}; \
@@ -70,7 +70,7 @@
 # - copies directories; including empty dirs
 # - copies files, symlinks, other non-directory files
 $(UNIVERSAL_COPY_LIST):
-	BUILT_COPY_FILES="`find $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) -prune 2>/dev/null`"; \
+	BUILT_COPY_FILES="`find $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) -prune 2>/dev/null`" || test $$? = "1"; \
 	if [ -n "$${BUILT_COPY_FILES}" ]; then \
 	  for i in $${BUILT_COPY_FILES}; do \
 	    $(MKDIR) -p $(shell dirname $@); \
--- a/hotspot/make/linux/Makefile	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/make/linux/Makefile	Wed Jul 05 20:17:28 2017 +0200
@@ -246,8 +246,7 @@
 XSLT_CHECK	= $(REMOTE) $(RUN.JAVAP) javax.xml.transform.TransformerFactory
 # If not found then fail fast.
 check_j2se_version:
-	$(QUIETLY) $(XSLT_CHECK) > /dev/null 2>&1; \
-	if [ $$? -ne 0 ]; then \
+	$(QUIETLY) if ! $(XSLT_CHECK) > /dev/null 2>&1; then \
 	  $(REMOTE) $(RUN.JAVA) -version; \
 	  echo "*** An XSLT processor (J2SE 1.4.x or newer) is required" \
 	  "to bootstrap this build" 1>&2; \
--- a/hotspot/make/linux/makefiles/vm.make	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/make/linux/makefiles/vm.make	Wed Jul 05 20:17:28 2017 +0200
@@ -334,10 +334,8 @@
 	    rm -f $@.1; ln -s $@ $@.1;                                  \
             if [ \"$(CROSS_COMPILE_ARCH)\" = \"\" ] ; then                    \
 	      if [ -x /usr/sbin/selinuxenabled ] ; then                 \
-	        /usr/sbin/selinuxenabled;                               \
-                if [ $$? = 0 ] ; then					\
-		  /usr/bin/chcon -t textrel_shlib_t $@;                 \
-		  if [ $$? != 0 ]; then                                 \
+                if /usr/sbin/selinuxenabled; then			\
+		  if ! /usr/bin/chcon -t textrel_shlib_t $@; then       \
 		    echo "ERROR: Cannot chcon $@";			\
 		  fi							\
 	        fi							\
--- a/hotspot/make/sa.files	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/make/sa.files	Wed Jul 05 20:17:28 2017 +0200
@@ -39,6 +39,7 @@
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/sparc/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/c1/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/ci/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/classfile/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/code/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/compiler/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/*.java \
@@ -49,8 +50,10 @@
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/basic/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dummy/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/ia64/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/amd64/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/ia64/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/ppc64/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/x86/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/sparc/*.java \
@@ -71,6 +74,7 @@
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/win32/coff/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/amd64/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/ia64/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/x86/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windows/x86/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windows/amd64/*.java \
@@ -101,6 +105,8 @@
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/solaris_x86/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/sparc/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/x86/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/win32_amd64/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/win32_x86/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/ppc64/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/jcore/*.java \
--- a/hotspot/make/solaris/Makefile	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/make/solaris/Makefile	Wed Jul 05 20:17:28 2017 +0200
@@ -190,8 +190,7 @@
 XSLT_CHECK	= $(RUN.JAVAP) javax.xml.transform.TransformerFactory
 # If not found then fail fast.
 check_j2se_version:
-	$(QUIETLY) $(XSLT_CHECK) > /dev/null 2>&1; \
-	if [ $$? -ne 0 ]; then \
+	$(QUIETLY) if ! $(XSLT_CHECK) > /dev/null 2>&1; then \
 	  $(RUN.JAVA) -version; \
 	  echo "*** An XSLT processor (J2SE 1.4.x or newer) is required" \
 	  "to bootstrap this build" 1>&2; \
--- a/hotspot/make/solaris/makefiles/dtrace.make	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/make/solaris/makefiles/dtrace.make	Wed Jul 05 20:17:28 2017 +0200
@@ -171,11 +171,11 @@
 		./lib$(GENOFFS).so
 
 CONDITIONALLY_UPDATE_JVMOFFS_TARGET = \
-	cmp -s $@ $@.tmp; \
-	case $$? in \
-	0) rm -f $@.tmp;; \
-	*) rm -f $@ && mv $@.tmp $@ && echo Updated $@;; \
-	esac
+	if cmp -s $@ $@.tmp; then \
+	  rm -f $@.tmp; \
+	else \
+	  rm -f $@ && mv $@.tmp $@ && echo Updated $@; \
+	fi
 
 # $@.tmp is created first to avoid an empty $(JVMOFFS).h if an error occurs.
 $(JVMOFFS).h: $(GENOFFS)
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -567,16 +567,21 @@
   inline void load_with_trap_null_check(Register d, int si16, Register s1);
 
   // Load heap oop and decompress. Loaded oop may not be null.
-  inline void load_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1 = noreg);
+  // Specify tmp to save one cycle.
+  inline void load_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1 = noreg,
+                                     Register tmp = noreg);
+  // Store heap oop and decompress.  Decompressed oop may not be null.
+  // Specify tmp register if d should not be changed.
   inline void store_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1,
-                                      /*specify if d must stay uncompressed*/ Register tmp = noreg);
+                                      Register tmp = noreg);
 
   // Null allowed.
   inline void load_heap_oop(Register d, RegisterOrConstant offs, Register s1 = noreg);
 
   // Encode/decode heap oop. Oop may not be null, else en/decoding goes wrong.
+  // src == d allowed.
   inline Register encode_heap_oop_not_null(Register d, Register src = noreg);
-  inline void decode_heap_oop_not_null(Register d);
+  inline Register decode_heap_oop_not_null(Register d, Register src = noreg);
 
   // Null allowed.
   inline void decode_heap_oop(Register d);
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.inline.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.inline.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -311,11 +311,14 @@
   ld(d, si16, s1);
 }
 
-inline void MacroAssembler::load_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1) {
+inline void MacroAssembler::load_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1, Register tmp) {
   if (UseCompressedOops) {
-    lwz(d, offs, s1);
+    // In disjoint mode decoding can save a cycle if src != dst.
+    Register narrowOop = (tmp != noreg && Universe::narrow_oop_base_disjoint()) ? tmp : d;
+    lwz(narrowOop, offs, s1);
     // Attention: no null check here!
-    decode_heap_oop_not_null(d);
+    Register res = decode_heap_oop_not_null(d, narrowOop);
+    assert(res == d, "caller will not consume loaded value");
   } else {
     ld(d, offs, s1);
   }
@@ -340,26 +343,36 @@
 }
 
 inline Register MacroAssembler::encode_heap_oop_not_null(Register d, Register src) {
-  Register current = (src!=noreg) ? src : d; // Compressed oop is in d if no src provided.
-  if (Universe::narrow_oop_base() != NULL) {
+  Register current = (src != noreg) ? src : d; // Oop to be compressed is in d if no src provided.
+  if (Universe::narrow_oop_base_overlaps()) {
     sub(d, current, R30);
     current = d;
   }
   if (Universe::narrow_oop_shift() != 0) {
-    srdi(d, current, LogMinObjAlignmentInBytes);
+    rldicl(d, current, 64-Universe::narrow_oop_shift(), 32);  // Clears the upper bits.
     current = d;
   }
   return current; // Encoded oop is in this register.
 }
 
-inline void MacroAssembler::decode_heap_oop_not_null(Register d) {
+inline Register MacroAssembler::decode_heap_oop_not_null(Register d, Register src) {
+  if (Universe::narrow_oop_base_disjoint() && src != noreg && src != d &&
+      Universe::narrow_oop_shift() != 0) {
+    mr(d, R30);
+    rldimi(d, src, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift());
+    return d;
+  }
+
+  Register current = (src != noreg) ? src : d; // Compressed oop is in d if no src provided.
   if (Universe::narrow_oop_shift() != 0) {
-    assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
-    sldi(d, d, LogMinObjAlignmentInBytes);
+    sldi(d, current, Universe::narrow_oop_shift());
+    current = d;
   }
   if (Universe::narrow_oop_base() != NULL) {
-    add(d, d, R30);
+    add(d, current, R30);
+    current = d;
   }
+  return current; // Decoded oop is in this register.
 }
 
 inline void MacroAssembler::decode_heap_oop(Register d) {
@@ -368,13 +381,7 @@
     cmpwi(CCR0, d, 0);
     beq(CCR0, isNull);
   }
-  if (Universe::narrow_oop_shift() != 0) {
-    assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
-    sldi(d, d, LogMinObjAlignmentInBytes);
-  }
-  if (Universe::narrow_oop_base() != NULL) {
-    add(d, d, R30);
-  }
+  decode_heap_oop_not_null(d);
   bind(isNull);
 }
 
--- a/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -172,15 +172,15 @@
 
   // Load the invoker, as MH -> MH.form -> LF.vmentry
   __ verify_oop(recv);
-  __ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes()), recv);
+  __ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes()), recv, temp2);
   __ verify_oop(method_temp);
-  __ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes()), method_temp);
+  __ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes()), method_temp, temp2);
   __ verify_oop(method_temp);
-  // the following assumes that a Method* is normally compressed in the vmtarget field:
+  // The following assumes that a Method* is normally compressed in the vmtarget field:
   __ ld(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()), method_temp);
 
   if (VerifyMethodHandles && !for_compiler_entry) {
-    // make sure recv is already on stack
+    // Make sure recv is already on stack.
     __ ld(temp2, in_bytes(Method::const_offset()), method_temp);
     __ load_sized_value(temp2, in_bytes(ConstMethod::size_of_parameters_offset()), temp2,
                         sizeof(u2), /*is_signed*/ false);
@@ -259,8 +259,9 @@
   }
 
   if (TraceMethodHandles) {
-    if (tmp_mh != noreg)
+    if (tmp_mh != noreg) {
       __ mr(R23_method_handle, tmp_mh);  // make stub happy
+    }
     trace_method_handle_interpreter_entry(_masm, iid);
   }
 
@@ -332,7 +333,7 @@
       if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) {
         Label L_ok;
         Register temp2_defc = temp2;
-        __ load_heap_oop_not_null(temp2_defc, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg);
+        __ load_heap_oop_not_null(temp2_defc, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg, temp3);
         load_klass_from_Class(_masm, temp2_defc, temp3, temp4);
         __ verify_klass_ptr(temp2_defc);
         __ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, temp4, L_ok);
@@ -407,7 +408,7 @@
       }
 
       Register temp2_intf = temp2;
-      __ load_heap_oop_not_null(temp2_intf, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg);
+      __ load_heap_oop_not_null(temp2_intf, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg, temp3);
       load_klass_from_Class(_masm, temp2_intf, temp3, temp4);
       __ verify_klass_ptr(temp2_intf);
 
@@ -464,7 +465,7 @@
                  strstr(adaptername, "linkTo") == NULL);    // static linkers don't have MH
   const char* mh_reg_name = has_mh ? "R23_method_handle" : "G23";
   tty->print_cr("MH %s %s="INTPTR_FORMAT " sp=" INTPTR_FORMAT,
-                adaptername, mh_reg_name, (intptr_t) mh, (intptr_t) entry_sp);
+                adaptername, mh_reg_name, (intptr_t) mh, entry_sp);
 
   if (Verbose) {
     tty->print_cr("Registers:");
@@ -535,23 +536,22 @@
 
   BLOCK_COMMENT("trace_method_handle {");
 
-  int nbytes_save = 10 * 8;             // 10 volatile gprs
-  __ save_LR_CR(R0);
-  __ mr(R0, R1_SP);                     // saved_sp
-  assert(Assembler::is_simm(-nbytes_save, 16), "Overwriting R0");
-  // Push_frame_reg_args only uses R0 if nbytes_save is wider than 16 bit.
-  __ push_frame_reg_args(nbytes_save, R0);
-  __ save_volatile_gprs(R1_SP, frame::abi_reg_args_size); // Except R0.
+  const Register tmp = R11; // Will be preserved.
+  const int nbytes_save = 11*8; // volatile gprs except R0
+  __ save_volatile_gprs(R1_SP, -nbytes_save); // except R0
+  __ save_LR_CR(tmp); // save in old frame
 
-  __ load_const(R3_ARG1, (address)adaptername);
+  __ mr(R5_ARG3, R1_SP);     // saved_sp
+  __ push_frame_reg_args(nbytes_save, tmp);
+
+  __ load_const_optimized(R3_ARG1, (address)adaptername, tmp);
   __ mr(R4_ARG2, R23_method_handle);
-  __ mr(R5_ARG3, R0);        // saved_sp
   __ mr(R6_ARG4, R1_SP);
   __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub));
 
-  __ restore_volatile_gprs(R1_SP, 112); // Except R0.
   __ pop_frame();
-  __ restore_LR_CR(R0);
+  __ restore_LR_CR(tmp);
+  __ restore_volatile_gprs(R1_SP, -nbytes_save); // except R0
 
   BLOCK_COMMENT("} trace_method_handle");
 }
--- a/hotspot/src/cpu/ppc/vm/ppc.ad	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/ppc/vm/ppc.ad	Wed Jul 05 20:17:28 2017 +0200
@@ -1,6 +1,6 @@
 //
-// Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
-// Copyright 2012, 2014 SAP AG. All rights reserved.
+// Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+// Copyright 2012, 2015 SAP AG. 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
@@ -2698,7 +2698,7 @@
         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
         __ relocate(a.rspec());
       } else if (constant_reloc == relocInfo::metadata_type) {
-        AddressLiteral a = __ allocate_metadata_address((Metadata *)val);
+        AddressLiteral a = __ constant_metadata_address((Metadata *)val);
         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
         __ relocate(a.rspec());
       } else {
@@ -2727,7 +2727,7 @@
         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
         __ relocate(a.rspec());
       } else if (constant_reloc == relocInfo::metadata_type) {
-        AddressLiteral a = __ allocate_metadata_address((Metadata *)val);
+        AddressLiteral a = __ constant_metadata_address((Metadata *)val);
         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
         __ relocate(a.rspec());
       } else {  // non-oop pointers, e.g. card mark base, heap top
@@ -6029,6 +6029,20 @@
   ins_pipe(pipe_class_default);
 %}
 
+// Optimize DecodeN for disjoint base.
+// Load base of compressed oops into a register
+instruct loadBase(iRegLdst dst) %{
+  effect(DEF dst);
+
+  format %{ "MR      $dst, r30_heapbase" %}
+  size(4);
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_or);
+    __ mr($dst$$Register, R30);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 // Loading ConN must be postalloc expanded so that edges between
 // the nodes are safe. They may not interfere with a safepoint.
 // GL TODO: This needs three instructions: better put this into the constant pool.
@@ -6724,13 +6738,12 @@
   ins_pipe(pipe_class_default);
 %}
 
-// base != 0
-// 32G aligned narrow oop base.
-instruct encodeP_32GAligned(iRegNdst dst, iRegPsrc src) %{
+// Disjoint narrow oop base.
+instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{
   match(Set dst (EncodeP src));
-  predicate(false /* TODO: PPC port Universe::narrow_oop_base_disjoint()*/);
-
-  format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with 32G aligned base" %}
+  predicate(Universe::narrow_oop_base_disjoint());
+
+  format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with disjoint base" %}
   size(4);
   ins_encode %{
     // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
@@ -6745,7 +6758,7 @@
   effect(TEMP crx);
   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull &&
             Universe::narrow_oop_shift() != 0 &&
-            true /* TODO: PPC port Universe::narrow_oop_base_overlaps()*/);
+            Universe::narrow_oop_base_overlaps());
 
   format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %}
   postalloc_expand( postalloc_expand_encode_oop(dst, src, crx));
@@ -6756,7 +6769,7 @@
   match(Set dst (EncodeP src));
   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull &&
             Universe::narrow_oop_shift() != 0 &&
-            true /* TODO: PPC port Universe::narrow_oop_base_overlaps()*/);
+            Universe::narrow_oop_base_overlaps());
 
   format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %}
   postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) );
@@ -6876,6 +6889,7 @@
              n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
             Universe::narrow_oop_shift() != 0 &&
             Universe::narrow_oop_base() != 0);
+  ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex.
   effect(TEMP crx);
 
   format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %}
@@ -6897,6 +6911,106 @@
   ins_pipe(pipe_class_default);
 %}
 
+// Optimize DecodeN for disjoint base.
+// Shift narrow oop and or it into register that already contains the heap base.
+// Base == dst must hold, and is assured by construction in postaloc_expand.
+instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{
+  match(Set dst (DecodeN src));
+  effect(TEMP base);
+  predicate(false);
+
+  format %{ "RLDIMI  $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %}
+  size(4);
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_rldimi);
+    __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift());
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+// Optimize DecodeN for disjoint base.
+// This node requires only one cycle on the critical path.
+// We must postalloc_expand as we can not express use_def effects where
+// the used register is L and the def'ed register P.
+instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
+  match(Set dst (DecodeN src));
+  effect(TEMP_DEF dst);
+  predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
+             n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
+            Universe::narrow_oop_base_disjoint());
+  ins_cost(DEFAULT_COST);
+
+  format %{ "MOV     $dst, R30 \t\n"
+            "RLDIMI  $dst, $src, shift, 32-shift \t// decode with disjoint base" %}
+  postalloc_expand %{
+    loadBaseNode *n1 = new loadBaseNode();
+    n1->add_req(NULL);
+    n1->_opnds[0] = op_dst;
+
+    decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
+    n2->add_req(n_region, n_src, n1);
+    n2->_opnds[0] = op_dst;
+    n2->_opnds[1] = op_src;
+    n2->_opnds[2] = op_dst;
+    n2->_bottom_type = _bottom_type;
+
+    ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
+    ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
+
+    nodes->push(n1);
+    nodes->push(n2);
+  %}
+%}
+
+instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
+  match(Set dst (DecodeN src));
+  effect(TEMP_DEF dst, TEMP crx);
+  predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
+             n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
+            Universe::narrow_oop_base_disjoint() && VM_Version::has_isel());
+  ins_cost(3 * DEFAULT_COST);
+
+  format %{ "DecodeN  $dst, $src \t// decode with disjoint base using isel" %}
+  postalloc_expand %{
+    loadBaseNode *n1 = new loadBaseNode();
+    n1->add_req(NULL);
+    n1->_opnds[0] = op_dst;
+
+    cmpN_reg_imm0Node *n_compare  = new cmpN_reg_imm0Node();
+    n_compare->add_req(n_region, n_src);
+    n_compare->_opnds[0] = op_crx;
+    n_compare->_opnds[1] = op_src;
+    n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
+    
+    decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
+    n2->add_req(n_region, n_src, n1);
+    n2->_opnds[0] = op_dst;
+    n2->_opnds[1] = op_src;
+    n2->_opnds[2] = op_dst;
+    n2->_bottom_type = _bottom_type;
+
+    cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
+    n_cond_set->add_req(n_region, n_compare, n2);
+    n_cond_set->_opnds[0] = op_dst;
+    n_cond_set->_opnds[1] = op_crx;
+    n_cond_set->_opnds[2] = op_dst;
+    n_cond_set->_bottom_type = _bottom_type;
+
+    assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
+    ra_->set_oop(n_cond_set, true);
+    
+    ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
+    ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
+    ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
+    ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
+
+    nodes->push(n1);
+    nodes->push(n_compare);
+    nodes->push(n2);
+    nodes->push(n_cond_set);
+  %}
+%}
+
 // src != 0, shift != 0, base != 0
 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{
   match(Set dst (DecodeN src));
@@ -6904,6 +7018,7 @@
              n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
             Universe::narrow_oop_shift() != 0 &&
             Universe::narrow_oop_base() != 0);
+  ins_cost(2 * DEFAULT_COST);
 
   format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %}
   postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src));
@@ -6973,13 +7088,12 @@
   ins_pipe(pipe_class_default);
 %}
 
-// base != 0
-// 32G aligned narrow oop base.
-instruct encodePKlass_32GAligned(iRegNdst dst, iRegPsrc src) %{
+// Disjoint narrow oop base.
+instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{
   match(Set dst (EncodePKlass src));
   predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/);
 
-  format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with 32G aligned base" %}
+  format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with disjoint base" %}
   size(4);
   ins_encode %{
     // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
@@ -7486,7 +7600,7 @@
   ins_encode %{
     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register,
-                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+                MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(),
                 noreg, NULL, true);
   %}
   ins_pipe(pipe_class_default);
@@ -10476,7 +10590,7 @@
   match(Set crx (CmpN src1 src2));
 
   size(4);
-  ins_cost(DEFAULT_COST);
+  ins_cost(2);
   format %{ "CMPLW   $crx, $src1, $src2 \t// compressed ptr" %}
   ins_encode %{
     // TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
@@ -10488,7 +10602,7 @@
 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
   match(Set crx (CmpN src1 src2));
   // Make this more expensive than zeroCheckN_iReg_imm0.
-  ins_cost(DEFAULT_COST);
+  ins_cost(2);
 
   format %{ "CMPLWI  $crx, $src1, $src2 \t// compressed ptr" %}
   size(4);
@@ -10508,6 +10622,7 @@
             _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
             _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
             Matcher::branches_to_uncommon_trap(_leaf));
+  ins_cost(1); // Should not be cheaper than zeroCheckN.
 
   ins_is_TrapBasedCheckNode(true);
 
@@ -10889,7 +11004,7 @@
 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
                              iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
   match(Set result (PartialSubtypeCheck subklass superklass));
-  effect(TEMP result, TEMP tmp_klass, TEMP tmp_arrayptr);
+  effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
   ins_cost(DEFAULT_COST*10);
 
   format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
@@ -11000,7 +11115,7 @@
   predicate(SpecialStringIndexOf);  // type check implicit by parameter type, See Matcher::match_rule_supported
   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
 
-  effect(TEMP result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1);
+  effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1);
 
   ins_cost(150);
   format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
@@ -11037,7 +11152,7 @@
                              iRegIdst tmp1, iRegIdst tmp2,
                              flagsRegCR0 cr0, flagsRegCR1 cr1) %{
   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
-  effect(USE_KILL needle, /* TDEF needle, */ TEMP result,
+  effect(USE_KILL needle, /* TDEF needle, */ TEMP_DEF result,
          TEMP tmp1, TEMP tmp2);
   // Required for EA: check if it is still a type_array.
   predicate(SpecialStringIndexOf && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
@@ -11084,7 +11199,7 @@
                             iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
                             flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
-  effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP result,
+  effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6);
   // Required for EA: check if it is still a type_array.
   predicate(SpecialStringIndexOf && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
@@ -11118,7 +11233,7 @@
                         flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
   effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
-         TEMP result,
+         TEMP_DEF result,
          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6);
   predicate(SpecialStringIndexOf);  // See Matcher::match_rule_supported.
   ins_cost(300);
@@ -11142,7 +11257,7 @@
                            iRegPdst tmp1, iRegPdst tmp2,
                            flagsRegCR0 cr0, flagsRegCR6 cr6, regCTR ctr) %{
   match(Set result (StrEquals (Binary str1 str2) cntImm));
-  effect(TEMP result, TEMP tmp1, TEMP tmp2,
+  effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2,
          KILL cr0, KILL cr6, KILL ctr);
   predicate(SpecialStringEquals);  // See Matcher::match_rule_supported.
   ins_cost(250);
@@ -11165,7 +11280,7 @@
                        iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3, iRegPdst tmp4, iRegPdst tmp5,
                        flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
   match(Set result (StrEquals (Binary str1 str2) cnt));
-  effect(TEMP result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
+  effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
          KILL cr0, KILL cr1, KILL cr6, KILL ctr);
   predicate(SpecialStringEquals);  // See Matcher::match_rule_supported.
   ins_cost(300);
@@ -11188,7 +11303,7 @@
 instruct string_compare(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
                         iRegPdst tmp, flagsRegCR0 cr0, regCTR ctr) %{
   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
-  effect(USE_KILL cnt1, USE_KILL cnt2, USE_KILL str1, USE_KILL str2, TEMP result, TEMP tmp, KILL cr0, KILL ctr);
+  effect(USE_KILL cnt1, USE_KILL cnt2, USE_KILL str1, USE_KILL str2, TEMP_DEF result, TEMP tmp, KILL cr0, KILL ctr);
   ins_cost(300);
 
   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
--- a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -483,15 +483,6 @@
 
 }
 
-jbyte* G1PostBarrierStub::_byte_map_base = NULL;
-
-jbyte* G1PostBarrierStub::byte_map_base_slow() {
-  BarrierSet* bs = Universe::heap()->barrier_set();
-  assert(bs->is_a(BarrierSet::G1SATBCTLogging),
-         "Must be if we're using this.");
-  return ((G1SATBCardTableModRefBS*)bs)->byte_map_base;
-}
-
 void G1PostBarrierStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
 
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1374,6 +1374,7 @@
 }
 
 void InterpreterMacroAssembler::test_invocation_counter_for_mdp(Register invocation_count,
+                                                                Register method_counters,
                                                                 Register Rtmp,
                                                                 Label &profile_continue) {
   assert(ProfileInterpreter, "must be profiling interpreter");
@@ -1386,9 +1387,8 @@
   br_notnull_short(ImethodDataPtr, Assembler::pn, done);
 
   // Test to see if we should create a method data oop
-  AddressLiteral profile_limit((address) &InvocationCounter::InterpreterProfileLimit);
-  sethi(profile_limit, Rtmp);
-  ld(Rtmp, profile_limit.low10(), Rtmp);
+  Address profile_limit(method_counters, MethodCounters::interpreter_profile_limit_offset());
+  ld(profile_limit, Rtmp);
   cmp(invocation_count, Rtmp);
   // Use long branches because call_VM() code and following code generated by
   // test_backedge_count_for_osr() is large in debug VM.
@@ -2375,6 +2375,7 @@
 
 #ifndef CC_INTERP
 void InterpreterMacroAssembler::test_backedge_count_for_osr( Register backedge_count,
+                                                             Register method_counters,
                                                              Register branch_bcp,
                                                              Register Rtmp ) {
   Label did_not_overflow;
@@ -2382,8 +2383,8 @@
   assert_different_registers(backedge_count, Rtmp, branch_bcp);
   assert(UseOnStackReplacement,"Must UseOnStackReplacement to test_backedge_count_for_osr");
 
-  AddressLiteral limit(&InvocationCounter::InterpreterBackwardBranchLimit);
-  load_contents(limit, Rtmp);
+  Address limit(method_counters, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset()));
+  ld(limit, Rtmp);
   cmp_and_br_short(backedge_count, Rtmp, Assembler::lessUnsigned, Assembler::pt, did_not_overflow);
 
   // When ProfileInterpreter is on, the backedge_count comes from the
@@ -2500,17 +2501,13 @@
 
 // Jump if ((*counter_addr += increment) & mask) satisfies the condition.
 void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
-                                                        int increment, int mask,
+                                                        int increment, Address mask_addr,
                                                         Register scratch1, Register scratch2,
                                                         Condition cond, Label *where) {
   ld(counter_addr, scratch1);
   add(scratch1, increment, scratch1);
-  if (is_simm13(mask)) {
-    andcc(scratch1, mask, G0);
-  } else {
-    set(mask, scratch2);
-    andcc(scratch1, scratch2,  G0);
-  }
+  ld(mask_addr, scratch2);
+  andcc(scratch1, scratch2,  G0);
   br(cond, false, Assembler::pn, *where);
   delayed()->st(scratch1, counter_addr);
 }
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -267,7 +267,7 @@
   void increment_invocation_counter( Register Rcounters, Register Rtmp, Register Rtmp2 );
   void increment_backedge_counter( Register Rcounters, Register Rtmp, Register Rtmp2 );
 #ifndef CC_INTERP
-  void test_backedge_count_for_osr( Register backedge_count, Register branch_bcp, Register Rtmp );
+  void test_backedge_count_for_osr(Register backedge_count, Register method_counters, Register branch_bcp, Register Rtmp );
 
 #endif /* CC_INTERP */
   // Object locking
@@ -280,7 +280,7 @@
   void set_method_data_pointer_for_bcp();
   void test_method_data_pointer(Label& zero_continue);
   void verify_method_data_pointer();
-  void test_invocation_counter_for_mdp(Register invocation_count, Register Rtmp, Label &profile_continue);
+  void test_invocation_counter_for_mdp(Register invocation_count, Register method_counters, Register Rtmp, Label &profile_continue);
 
   void set_mdp_data_at(int constant, Register value);
   void increment_mdp_data_at(Address counter, Register bumped_count,
@@ -291,7 +291,7 @@
                              Register bumped_count, Register scratch2,
                              bool decrement = false);
   void increment_mask_and_jump(Address counter_addr,
-                               int increment, int mask,
+                               int increment, Address mask_addr,
                                Register scratch1, Register scratch2,
                                Condition cond, Label *where);
   void set_mdp_flag_at(int flag_constant, Register scratch);
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -282,12 +282,11 @@
 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) {
   // Note: In tiered we increment either counters in MethodCounters* or in
   // MDO depending if we're profiling or not.
-  const Register Rcounters = G3_scratch;
+  const Register G3_method_counters = G3_scratch;
   Label done;
 
   if (TieredCompilation) {
     const int increment = InvocationCounter::count_increment;
-    const int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
     Label no_mdo;
     if (ProfileInterpreter) {
       // If no method data exists, go to profile_continue.
@@ -297,6 +296,7 @@
       Address mdo_invocation_counter(G4_scratch,
                                      in_bytes(MethodData::invocation_counter_offset()) +
                                      in_bytes(InvocationCounter::counter_offset()));
+      Address mask(G4_scratch, in_bytes(MethodData::invoke_mask_offset()));
       __ increment_mask_and_jump(mdo_invocation_counter, increment, mask,
                                  G3_scratch, Lscratch,
                                  Assembler::zero, overflow);
@@ -305,20 +305,21 @@
 
     // Increment counter in MethodCounters*
     __ bind(no_mdo);
-    Address invocation_counter(Rcounters,
+    Address invocation_counter(G3_method_counters,
             in_bytes(MethodCounters::invocation_counter_offset()) +
             in_bytes(InvocationCounter::counter_offset()));
-    __ get_method_counters(Lmethod, Rcounters, done);
+    __ get_method_counters(Lmethod, G3_method_counters, done);
+    Address mask(G3_method_counters, in_bytes(MethodCounters::invoke_mask_offset()));
     __ increment_mask_and_jump(invocation_counter, increment, mask,
                                G4_scratch, Lscratch,
                                Assembler::zero, overflow);
     __ bind(done);
-  } else {
+  } else { // not TieredCompilation
     // Update standard invocation counters
-    __ get_method_counters(Lmethod, Rcounters, done);
-    __ increment_invocation_counter(Rcounters, O0, G4_scratch);
+    __ get_method_counters(Lmethod, G3_method_counters, done);
+    __ increment_invocation_counter(G3_method_counters, O0, G4_scratch);
     if (ProfileInterpreter) {
-      Address interpreter_invocation_counter(Rcounters,
+      Address interpreter_invocation_counter(G3_method_counters,
             in_bytes(MethodCounters::interpreter_invocation_counter_offset()));
       __ ld(interpreter_invocation_counter, G4_scratch);
       __ inc(G4_scratch);
@@ -327,16 +328,16 @@
 
     if (ProfileInterpreter && profile_method != NULL) {
       // Test to see if we should create a method data oop
-      AddressLiteral profile_limit((address)&InvocationCounter::InterpreterProfileLimit);
-      __ load_contents(profile_limit, G3_scratch);
-      __ cmp_and_br_short(O0, G3_scratch, Assembler::lessUnsigned, Assembler::pn, *profile_method_continue);
+      Address profile_limit(G3_method_counters, in_bytes(MethodCounters::interpreter_profile_limit_offset()));
+      __ ld(profile_limit, G1_scratch);
+      __ cmp_and_br_short(O0, G1_scratch, Assembler::lessUnsigned, Assembler::pn, *profile_method_continue);
 
       // if no method data exists, go to profile_method
       __ test_method_data_pointer(*profile_method);
     }
 
-    AddressLiteral invocation_limit((address)&InvocationCounter::InterpreterInvocationLimit);
-    __ load_contents(invocation_limit, G3_scratch);
+    Address invocation_limit(G3_method_counters, in_bytes(MethodCounters::interpreter_invocation_limit_offset()));
+    __ ld(invocation_limit, G3_scratch);
     __ cmp(O0, G3_scratch);
     __ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow); // Far distance
     __ delayed()->nop();
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1599,13 +1599,12 @@
     // Bump bytecode pointer by displacement (take the branch)
     __ delayed()->add( O1_disp, Lbcp, Lbcp );     // add to bc addr
 
-    const Register Rcounters = G3_scratch;
-    __ get_method_counters(Lmethod, Rcounters, Lforward);
+    const Register G3_method_counters = G3_scratch;
+    __ get_method_counters(Lmethod, G3_method_counters, Lforward);
 
     if (TieredCompilation) {
       Label Lno_mdo, Loverflow;
       int increment = InvocationCounter::count_increment;
-      int mask = ((1 << Tier0BackedgeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
       if (ProfileInterpreter) {
         // If no method data exists, go to profile_continue.
         __ ld_ptr(Lmethod, Method::method_data_offset(), G4_scratch);
@@ -1614,6 +1613,7 @@
         // Increment backedge counter in the MDO
         Address mdo_backedge_counter(G4_scratch, in_bytes(MethodData::backedge_counter_offset()) +
                                                  in_bytes(InvocationCounter::counter_offset()));
+        Address mask(G4_scratch, in_bytes(MethodData::backedge_mask_offset()));
         __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, G3_scratch, O0,
                                    Assembler::notZero, &Lforward);
         __ ba_short(Loverflow);
@@ -1621,9 +1621,10 @@
 
       // If there's no MDO, increment counter in MethodCounters*
       __ bind(Lno_mdo);
-      Address backedge_counter(Rcounters,
+      Address backedge_counter(G3_method_counters,
               in_bytes(MethodCounters::backedge_counter_offset()) +
               in_bytes(InvocationCounter::counter_offset()));
+      Address mask(G3_method_counters, in_bytes(MethodCounters::backedge_mask_offset()));
       __ increment_mask_and_jump(backedge_counter, increment, mask, G4_scratch, O0,
                                  Assembler::notZero, &Lforward);
       __ bind(Loverflow);
@@ -1663,18 +1664,19 @@
       __ jmp(O2, G0);
       __ delayed()->nop();
 
-    } else {
+    } else { // not TieredCompilation
       // Update Backedge branch separately from invocations
       const Register G4_invoke_ctr = G4;
-      __ increment_backedge_counter(Rcounters, G4_invoke_ctr, G1_scratch);
+      __ increment_backedge_counter(G3_method_counters, G4_invoke_ctr, G1_scratch);
       if (ProfileInterpreter) {
-        __ test_invocation_counter_for_mdp(G4_invoke_ctr, G3_scratch, Lforward);
+        __ test_invocation_counter_for_mdp(G4_invoke_ctr, G3_method_counters, G1_scratch, Lforward);
         if (UseOnStackReplacement) {
-          __ test_backedge_count_for_osr(O2_bumped_count, l_cur_bcp, G3_scratch);
+
+          __ test_backedge_count_for_osr(O2_bumped_count, G3_method_counters, l_cur_bcp, G1_scratch);
         }
       } else {
         if (UseOnStackReplacement) {
-          __ test_backedge_count_for_osr(G4_invoke_ctr, l_cur_bcp, G3_scratch);
+          __ test_backedge_count_for_osr(G4_invoke_ctr, G3_method_counters, l_cur_bcp, G1_scratch);
         }
       }
     }
--- a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -541,15 +541,6 @@
 
 }
 
-jbyte* G1PostBarrierStub::_byte_map_base = NULL;
-
-jbyte* G1PostBarrierStub::byte_map_base_slow() {
-  BarrierSet* bs = Universe::heap()->barrier_set();
-  assert(bs->is_a(BarrierSet::G1SATBCTLogging),
-         "Must be if we're using this.");
-  return ((G1SATBCardTableModRefBS*)bs)->byte_map_base;
-}
-
 void G1PostBarrierStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
   assert(addr()->is_register(), "Precondition.");
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1360,7 +1360,7 @@
 
 // Jump if ((*counter_addr += increment) & mask) satisfies the condition.
 void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
-                                                        int increment, int mask,
+                                                        int increment, Address mask,
                                                         Register scratch, bool preloaded,
                                                         Condition cond, Label* where) {
   if (!preloaded) {
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -182,7 +182,7 @@
   void increment_mdp_data_at(Register mdp_in, Register reg, int constant,
                              bool decrement = false);
   void increment_mask_and_jump(Address counter_addr,
-                               int increment, int mask,
+                               int increment, Address mask,
                                Register scratch, bool preloaded,
                                Condition cond, Label* where);
   void set_mdp_flag_at(Register mdp_in, int flag_constant);
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1426,7 +1426,7 @@
 
 // Jump if ((*counter_addr += increment) & mask) satisfies the condition.
 void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
-                                                        int increment, int mask,
+                                                        int increment, Address mask,
                                                         Register scratch, bool preloaded,
                                                         Condition cond, Label* where) {
   if (!preloaded) {
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -191,7 +191,7 @@
   void increment_mdp_data_at(Register mdp_in, Register reg, int constant,
                              bool decrement = false);
   void increment_mask_and_jump(Address counter_addr,
-                               int increment, int mask,
+                               int increment, Address mask,
                                Register scratch, bool preloaded,
                                Condition cond, Label* where);
   void set_mdp_flag_at(Register mdp_in, int flag_constant);
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -346,7 +346,6 @@
   // depending if we're profiling or not.
   if (TieredCompilation) {
     int increment = InvocationCounter::count_increment;
-    int mask = ((1 << Tier0InvokeNotifyFreqLog)  - 1) << InvocationCounter::count_shift;
     Label no_mdo;
     if (ProfileInterpreter) {
       // Are we profiling?
@@ -356,6 +355,7 @@
       // Increment counter in the MDO
       const Address mdo_invocation_counter(rax, in_bytes(MethodData::invocation_counter_offset()) +
                                                 in_bytes(InvocationCounter::counter_offset()));
+      const Address mask(rax, in_bytes(MethodData::invoke_mask_offset()));
       __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow);
       __ jmp(done);
     }
@@ -366,11 +366,12 @@
                   InvocationCounter::counter_offset());
 
     __ get_method_counters(rbx, rax, done);
+    const Address mask(rax, in_bytes(MethodCounters::invoke_mask_offset()));
     __ increment_mask_and_jump(invocation_counter, increment, mask,
                                rcx, false, Assembler::zero, overflow);
     __ bind(done);
-  } else {
-    const Address backedge_counter  (rax,
+  } else { // not TieredCompilation
+    const Address backedge_counter(rax,
                   MethodCounters::backedge_counter_offset() +
                   InvocationCounter::counter_offset());
     const Address invocation_counter(rax,
@@ -400,16 +401,16 @@
 
     if (ProfileInterpreter && profile_method != NULL) {
       // Test to see if we should create a method data oop
-      __ cmp32(rcx,
-               ExternalAddress((address)&InvocationCounter::InterpreterProfileLimit));
+      __ movptr(rax, Address(rbx, Method::method_counters_offset()));
+      __ cmp32(rcx, Address(rax, in_bytes(MethodCounters::interpreter_profile_limit_offset())));
       __ jcc(Assembler::less, *profile_method_continue);
 
       // if no method data exists, go to profile_method
       __ test_method_data_pointer(rax, *profile_method);
     }
 
-    __ cmp32(rcx,
-             ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit));
+    __ movptr(rax, Address(rbx, Method::method_counters_offset()));
+    __ cmp32(rcx, Address(rax, in_bytes(MethodCounters::interpreter_invocation_limit_offset())));
     __ jcc(Assembler::aboveEqual, *overflow);
     __ bind(done);
   }
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -299,7 +299,6 @@
   // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not.
   if (TieredCompilation) {
     int increment = InvocationCounter::count_increment;
-    int mask = ((1 << Tier0InvokeNotifyFreqLog)  - 1) << InvocationCounter::count_shift;
     Label no_mdo;
     if (ProfileInterpreter) {
       // Are we profiling?
@@ -309,6 +308,7 @@
       // Increment counter in the MDO
       const Address mdo_invocation_counter(rax, in_bytes(MethodData::invocation_counter_offset()) +
                                                 in_bytes(InvocationCounter::counter_offset()));
+      const Address mask(rax, in_bytes(MethodData::invoke_mask_offset()));
       __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow);
       __ jmp(done);
     }
@@ -318,10 +318,11 @@
                   MethodCounters::invocation_counter_offset() +
                   InvocationCounter::counter_offset());
     __ get_method_counters(rbx, rax, done);
+    const Address mask(rax, in_bytes(MethodCounters::invoke_mask_offset()));
     __ increment_mask_and_jump(invocation_counter, increment, mask, rcx,
                                false, Assembler::zero, overflow);
     __ bind(done);
-  } else {
+  } else { // not TieredCompilation
     const Address backedge_counter(rax,
                   MethodCounters::backedge_counter_offset() +
                   InvocationCounter::counter_offset());
@@ -350,14 +351,16 @@
 
     if (ProfileInterpreter && profile_method != NULL) {
       // Test to see if we should create a method data oop
-      __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterProfileLimit));
+      __ movptr(rax, Address(rbx, Method::method_counters_offset()));
+      __ cmp32(rcx, Address(rax, in_bytes(MethodCounters::interpreter_profile_limit_offset())));
       __ jcc(Assembler::less, *profile_method_continue);
 
       // if no method data exists, go to profile_method
       __ test_method_data_pointer(rax, *profile_method);
     }
 
-    __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit));
+    __ movptr(rax, Address(rbx, Method::method_counters_offset()));
+    __ cmp32(rcx, Address(rax, in_bytes(MethodCounters::interpreter_invocation_limit_offset())));
     __ jcc(Assembler::aboveEqual, *overflow);
     __ bind(done);
   }
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1621,7 +1621,6 @@
     if (TieredCompilation) {
       Label no_mdo;
       int increment = InvocationCounter::count_increment;
-      int mask = ((1 << Tier0BackedgeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
       if (ProfileInterpreter) {
         // Are we profiling?
         __ movptr(rbx, Address(rcx, in_bytes(Method::method_data_offset())));
@@ -1630,6 +1629,7 @@
         // Increment the MDO backedge counter
         const Address mdo_backedge_counter(rbx, in_bytes(MethodData::backedge_counter_offset()) +
                                                 in_bytes(InvocationCounter::counter_offset()));
+        const Address mask(rbx, in_bytes(MethodData::backedge_mask_offset()));
         __ increment_mask_and_jump(mdo_backedge_counter, increment, mask,
                                    rax, false, Assembler::zero, &backedge_counter_overflow);
         __ jmp(dispatch);
@@ -1637,9 +1637,10 @@
       __ bind(no_mdo);
       // Increment backedge counter in MethodCounters*
       __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
+      const Address mask(rcx, in_bytes(MethodCounters::backedge_mask_offset()));
       __ increment_mask_and_jump(Address(rcx, be_offset), increment, mask,
                                  rax, false, Assembler::zero, &backedge_counter_overflow);
-    } else {
+    } else { // not TieredCompilation
       // increment counter
       __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
       __ movl(rax, Address(rcx, be_offset));        // load backedge counter
@@ -1653,8 +1654,7 @@
 
       if (ProfileInterpreter) {
         // Test to see if we should create a method data oop
-        __ cmp32(rax,
-                 ExternalAddress((address) &InvocationCounter::InterpreterProfileLimit));
+        __ cmp32(rax, Address(rcx, in_bytes(MethodCounters::interpreter_profile_limit_offset())));
         __ jcc(Assembler::less, dispatch);
 
         // if no method data exists, go to profile method
@@ -1662,8 +1662,7 @@
 
         if (UseOnStackReplacement) {
           // check for overflow against rbx, which is the MDO taken count
-          __ cmp32(rbx,
-                   ExternalAddress((address) &InvocationCounter::InterpreterBackwardBranchLimit));
+          __ cmp32(rbx, Address(rcx, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset())));
           __ jcc(Assembler::below, dispatch);
 
           // When ProfileInterpreter is on, the backedge_count comes from the
@@ -1678,8 +1677,7 @@
       } else {
         if (UseOnStackReplacement) {
           // check for overflow against rax, which is the sum of the counters
-          __ cmp32(rax,
-                   ExternalAddress((address) &InvocationCounter::InterpreterBackwardBranchLimit));
+          __ cmp32(rax, Address(rcx, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset())));
           __ jcc(Assembler::aboveEqual, backedge_counter_overflow);
 
         }
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1642,7 +1642,6 @@
     if (TieredCompilation) {
       Label no_mdo;
       int increment = InvocationCounter::count_increment;
-      int mask = ((1 << Tier0BackedgeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
       if (ProfileInterpreter) {
         // Are we profiling?
         __ movptr(rbx, Address(rcx, in_bytes(Method::method_data_offset())));
@@ -1651,6 +1650,7 @@
         // Increment the MDO backedge counter
         const Address mdo_backedge_counter(rbx, in_bytes(MethodData::backedge_counter_offset()) +
                                            in_bytes(InvocationCounter::counter_offset()));
+        const Address mask(rbx, in_bytes(MethodData::backedge_mask_offset()));
         __ increment_mask_and_jump(mdo_backedge_counter, increment, mask,
                                    rax, false, Assembler::zero, &backedge_counter_overflow);
         __ jmp(dispatch);
@@ -1658,9 +1658,10 @@
       __ bind(no_mdo);
       // Increment backedge counter in MethodCounters*
       __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
+         const Address mask(rcx, in_bytes(MethodCounters::backedge_mask_offset()));
       __ increment_mask_and_jump(Address(rcx, be_offset), increment, mask,
                                  rax, false, Assembler::zero, &backedge_counter_overflow);
-    } else {
+    } else { // not TieredCompilation
       // increment counter
       __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
       __ movl(rax, Address(rcx, be_offset));        // load backedge counter
@@ -1674,8 +1675,7 @@
 
       if (ProfileInterpreter) {
         // Test to see if we should create a method data oop
-        __ cmp32(rax,
-                 ExternalAddress((address) &InvocationCounter::InterpreterProfileLimit));
+        __ cmp32(rax, Address(rcx, in_bytes(MethodCounters::interpreter_profile_limit_offset())));
         __ jcc(Assembler::less, dispatch);
 
         // if no method data exists, go to profile method
@@ -1683,8 +1683,7 @@
 
         if (UseOnStackReplacement) {
           // check for overflow against ebx which is the MDO taken count
-          __ cmp32(rbx,
-                   ExternalAddress((address) &InvocationCounter::InterpreterBackwardBranchLimit));
+          __ cmp32(rbx, Address(rcx, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset())));
           __ jcc(Assembler::below, dispatch);
 
           // When ProfileInterpreter is on, the backedge_count comes
@@ -1702,8 +1701,7 @@
         if (UseOnStackReplacement) {
           // check for overflow against eax, which is the sum of the
           // counters
-          __ cmp32(rax,
-                   ExternalAddress((address) &InvocationCounter::InterpreterBackwardBranchLimit));
+          __ cmp32(rax, Address(rcx, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset())));
           __ jcc(Assembler::aboveEqual, backedge_counter_overflow);
 
         }
--- a/hotspot/src/os/aix/vm/perfMemory_aix.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/os/aix/vm/perfMemory_aix.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -31,6 +31,7 @@
 #include "os_aix.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/perfMemory.hpp"
+#include "services/memTracker.hpp"
 #include "utilities/exceptions.hpp"
 
 // put OS-includes here
@@ -196,12 +197,37 @@
   return pid;
 }
 
+// Check if the given statbuf is considered a secure directory for
+// the backing store files. Returns true if the directory is considered
+// a secure location. Returns false if the statbuf is a symbolic link or
+// if an error occurred.
+static bool is_statbuf_secure(struct stat *statp) {
+  if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) {
+    // The path represents a link or some non-directory file type,
+    // which is not what we expected. Declare it insecure.
+    //
+    return false;
+  }
+  // We have an existing directory, check if the permissions are safe.
+  if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) {
+    // The directory is open for writing and could be subjected
+    // to a symlink or a hard link attack. Declare it insecure.
+    return false;
+  }
+  // See if the uid of the directory matches the effective uid of the process.
+  //
+  if (statp->st_uid != geteuid()) {
+    // The directory was not created by this user, declare it insecure.
+    return false;
+  }
+  return true;
+}
 
-// check if the given path is considered a secure directory for
+
+// Check if the given path is considered a secure directory for
 // the backing store files. Returns true if the directory exists
 // and is considered a secure location. Returns false if the path
 // is a symbolic link or if an error occurred.
-//
 static bool is_directory_secure(const char* path) {
   struct stat statbuf;
   int result = 0;
@@ -211,38 +237,276 @@
     return false;
   }
 
-  // the path exists, now check it's mode
-  if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) {
-    // the path represents a link or some non-directory file type,
-    // which is not what we expected. declare it insecure.
-    //
+  // The path exists, see if it is secure.
+  return is_statbuf_secure(&statbuf);
+}
+
+// (Taken over from Solaris to support the O_NOFOLLOW case on AIX.)
+// Check if the given directory file descriptor is considered a secure
+// directory for the backing store files. Returns true if the directory
+// exists and is considered a secure location. Returns false if the path
+// is a symbolic link or if an error occurred.
+static bool is_dirfd_secure(int dir_fd) {
+  struct stat statbuf;
+  int result = 0;
+
+  RESTARTABLE(::fstat(dir_fd, &statbuf), result);
+  if (result == OS_ERR) {
     return false;
   }
-  else {
-    // we have an existing directory, check if the permissions are safe.
-    //
-    if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
-      // the directory is open for writing and could be subjected
-      // to a symlnk attack. declare it insecure.
-      //
-      return false;
+
+  // The path exists, now check its mode.
+  return is_statbuf_secure(&statbuf);
+}
+
+
+// Check to make sure fd1 and fd2 are referencing the same file system object.
+static bool is_same_fsobject(int fd1, int fd2) {
+  struct stat statbuf1;
+  struct stat statbuf2;
+  int result = 0;
+
+  RESTARTABLE(::fstat(fd1, &statbuf1), result);
+  if (result == OS_ERR) {
+    return false;
+  }
+  RESTARTABLE(::fstat(fd2, &statbuf2), result);
+  if (result == OS_ERR) {
+    return false;
+  }
+
+  if ((statbuf1.st_ino == statbuf2.st_ino) &&
+      (statbuf1.st_dev == statbuf2.st_dev)) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+// Helper functions for open without O_NOFOLLOW which is not present on AIX 5.3/6.1.
+// We use the jdk6 implementation here.
+#ifndef O_NOFOLLOW
+// The O_NOFOLLOW oflag doesn't exist before solaris 5.10, this is to simulate that behaviour
+// was done in jdk 5/6 hotspot by Oracle this way
+static int open_o_nofollow_impl(const char* path, int oflag, mode_t mode, bool use_mode) {
+  struct stat orig_st;
+  struct stat new_st;
+  bool create;
+  int error;
+  int fd;
+
+  create = false;
+
+  if (lstat(path, &orig_st) != 0) {
+    if (errno == ENOENT && (oflag & O_CREAT) != 0) {
+      // File doesn't exist, but_we want to create it, add O_EXCL flag
+      // to make sure no-one creates it (or a symlink) before us
+      // This works as we expect with symlinks, from posix man page:
+      // 'If O_EXCL  and  O_CREAT  are set, and path names a symbolic
+      // link, open() shall fail and set errno to [EEXIST]'.
+      oflag |= O_EXCL;
+      create = true;
+    } else {
+      // File doesn't exist, and we are not creating it.
+      return OS_ERR;
     }
+  } else {
+    // Lstat success, check if existing file is a link.
+    if ((orig_st.st_mode & S_IFMT) == S_IFLNK)  {
+      // File is a symlink.
+      errno = ELOOP;
+      return OS_ERR;
+    }
+  }
+
+  if (use_mode == true) {
+    fd = open(path, oflag, mode);
+  } else {
+    fd = open(path, oflag);
+  }
+
+  if (fd == OS_ERR) {
+    return fd;
+  }
+
+  // Can't do inode checks on before/after if we created the file.
+  if (create == false) {
+    if (fstat(fd, &new_st) != 0) {
+      // Keep errno from fstat, in case close also fails.
+      error = errno;
+      ::close(fd);
+      errno = error;
+      return OS_ERR;
+    }
+
+    if (orig_st.st_dev != new_st.st_dev || orig_st.st_ino != new_st.st_ino) {
+      // File was tampered with during race window.
+      ::close(fd);
+      errno = EEXIST;
+      if (PrintMiscellaneous && Verbose) {
+        warning("possible file tampering attempt detected when opening %s", path);
+      }
+      return OS_ERR;
+    }
+  }
+
+  return fd;
+}
+
+static int open_o_nofollow(const char* path, int oflag, mode_t mode) {
+  return open_o_nofollow_impl(path, oflag, mode, true);
+}
+
+static int open_o_nofollow(const char* path, int oflag) {
+  return open_o_nofollow_impl(path, oflag, 0, false);
+}
+#endif
+
+// Open the directory of the given path and validate it.
+// Return a DIR * of the open directory.
+static DIR *open_directory_secure(const char* dirname) {
+  // Open the directory using open() so that it can be verified
+  // to be secure by calling is_dirfd_secure(), opendir() and then check
+  // to see if they are the same file system object.  This method does not
+  // introduce a window of opportunity for the directory to be attacked that
+  // calling opendir() and is_directory_secure() does.
+  int result;
+  DIR *dirp = NULL;
+
+  // No O_NOFOLLOW defined at buildtime, and it is not documented for open;
+  // so provide a workaround in this case.
+#ifdef O_NOFOLLOW
+  RESTARTABLE(::open(dirname, O_RDONLY|O_NOFOLLOW), result);
+#else
+  // workaround (jdk6 coding)
+  RESTARTABLE(::open_o_nofollow(dirname, O_RDONLY), result);
+#endif
+
+  if (result == OS_ERR) {
+    // Directory doesn't exist or is a symlink, so there is nothing to cleanup.
+    if (PrintMiscellaneous && Verbose) {
+      if (errno == ELOOP) {
+        warning("directory %s is a symlink and is not secure\n", dirname);
+      } else {
+        warning("could not open directory %s: %s\n", dirname, strerror(errno));
+      }
+    }
+    return dirp;
+  }
+  int fd = result;
+
+  // Determine if the open directory is secure.
+  if (!is_dirfd_secure(fd)) {
+    // The directory is not a secure directory.
+    os::close(fd);
+    return dirp;
+  }
+
+  // Open the directory.
+  dirp = ::opendir(dirname);
+  if (dirp == NULL) {
+    // The directory doesn't exist, close fd and return.
+    os::close(fd);
+    return dirp;
+  }
+
+  // Check to make sure fd and dirp are referencing the same file system object.
+  if (!is_same_fsobject(fd, dirp->dd_fd)) {
+    // The directory is not secure.
+    os::close(fd);
+    os::closedir(dirp);
+    dirp = NULL;
+    return dirp;
+  }
+
+  // Close initial open now that we know directory is secure
+  os::close(fd);
+
+  return dirp;
+}
+
+// NOTE: The code below uses fchdir(), open() and unlink() because
+// fdopendir(), openat() and unlinkat() are not supported on all
+// versions.  Once the support for fdopendir(), openat() and unlinkat()
+// is available on all supported versions the code can be changed
+// to use these functions.
+
+// Open the directory of the given path, validate it and set the
+// current working directory to it.
+// Return a DIR * of the open directory and the saved cwd fd.
+//
+static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
+
+  // Open the directory.
+  DIR* dirp = open_directory_secure(dirname);
+  if (dirp == NULL) {
+    // Directory doesn't exist or is insecure, so there is nothing to cleanup.
+    return dirp;
+  }
+  int fd = dirp->dd_fd;
+
+  // Open a fd to the cwd and save it off.
+  int result;
+  RESTARTABLE(::open(".", O_RDONLY), result);
+  if (result == OS_ERR) {
+    *saved_cwd_fd = -1;
+  } else {
+    *saved_cwd_fd = result;
+  }
+
+  // Set the current directory to dirname by using the fd of the directory.
+  result = fchdir(fd);
+
+  return dirp;
+}
+
+// Close the directory and restore the current working directory.
+static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) {
+
+  int result;
+  // If we have a saved cwd change back to it and close the fd.
+  if (saved_cwd_fd != -1) {
+    result = fchdir(saved_cwd_fd);
+    ::close(saved_cwd_fd);
+  }
+
+  // Close the directory.
+  os::closedir(dirp);
+}
+
+// Check if the given file descriptor is considered a secure.
+static bool is_file_secure(int fd, const char *filename) {
+
+  int result;
+  struct stat statbuf;
+
+  // Determine if the file is secure.
+  RESTARTABLE(::fstat(fd, &statbuf), result);
+  if (result == OS_ERR) {
+    if (PrintMiscellaneous && Verbose) {
+      warning("fstat failed on %s: %s\n", filename, strerror(errno));
+    }
+    return false;
+  }
+  if (statbuf.st_nlink > 1) {
+    // A file with multiple links is not expected.
+    if (PrintMiscellaneous && Verbose) {
+      warning("file %s has multiple links\n", filename);
+    }
+    return false;
   }
   return true;
 }
 
-
-// return the user name for the given user id
+// Return the user name for the given user id.
 //
-// the caller is expected to free the allocated memory.
-//
+// The caller is expected to free the allocated memory.
 static char* get_user_name(uid_t uid) {
 
   struct passwd pwent;
 
-  // determine the max pwbuf size from sysconf, and hardcode
+  // Determine the max pwbuf size from sysconf, and hardcode
   // a default if this not available through sysconf.
-  //
   long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
   if (bufsize == -1)
     bufsize = 1024;
@@ -344,7 +608,8 @@
     strcat(usrdir_name, "/");
     strcat(usrdir_name, dentry->d_name);
 
-    DIR* subdirp = os::opendir(usrdir_name);
+    // Open the user directory.
+    DIR* subdirp = open_directory_secure(usrdir_name);
 
     if (subdirp == NULL) {
       FREE_C_HEAP_ARRAY(char, usrdir_name);
@@ -464,28 +729,7 @@
   }
 }
 
-
-// remove file
-//
-// this method removes the file with the given file name in the
-// named directory.
-//
-static void remove_file(const char* dirname, const char* filename) {
-
-  size_t nbytes = strlen(dirname) + strlen(filename) + 2;
-  char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
-
-  strcpy(path, dirname);
-  strcat(path, "/");
-  strcat(path, filename);
-
-  remove_file(path);
-
-  FREE_C_HEAP_ARRAY(char, path);
-}
-
-
-// cleanup stale shared memory resources
+// Cleanup stale shared memory resources
 //
 // This method attempts to remove all stale shared memory files in
 // the named user temporary directory. It scans the named directory
@@ -493,33 +737,26 @@
 // process id is extracted from the file name and a test is run to
 // determine if the process is alive. If the process is not alive,
 // any stale file resources are removed.
-//
 static void cleanup_sharedmem_resources(const char* dirname) {
 
-  // open the user temp directory
-  DIR* dirp = os::opendir(dirname);
-
+  int saved_cwd_fd;
+  // Open the directory.
+  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
   if (dirp == NULL) {
-    // directory doesn't exist, so there is nothing to cleanup
+     // Directory doesn't exist or is insecure, so there is nothing to cleanup.
     return;
   }
 
-  if (!is_directory_secure(dirname)) {
-    // the directory is not a secure directory
-    os::closedir(dirp);
-    return;
-  }
-
-  // for each entry in the directory that matches the expected file
+  // For each entry in the directory that matches the expected file
   // name pattern, determine if the file resources are stale and if
   // so, remove the file resources. Note, instrumented HotSpot processes
   // for this user may start and/or terminate during this search and
   // remove or create new files in this directory. The behavior of this
   // loop under these conditions is dependent upon the implementation of
   // opendir/readdir.
-  //
   struct dirent* entry;
   char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
+
   errno = 0;
   while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
 
@@ -529,56 +766,55 @@
 
       if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
 
-        // attempt to remove all unexpected files, except "." and ".."
-        remove_file(dirname, entry->d_name);
+        // Attempt to remove all unexpected files, except "." and "..".
+        unlink(entry->d_name);
       }
 
       errno = 0;
       continue;
     }
 
-    // we now have a file name that converts to a valid integer
+    // We now have a file name that converts to a valid integer
     // that could represent a process id . if this process id
     // matches the current process id or the process is not running,
     // then remove the stale file resources.
     //
-    // process liveness is detected by sending signal number 0 to
+    // Process liveness is detected by sending signal number 0 to
     // the process id (see kill(2)). if kill determines that the
     // process does not exist, then the file resources are removed.
     // if kill determines that that we don't have permission to
     // signal the process, then the file resources are assumed to
     // be stale and are removed because the resources for such a
     // process should be in a different user specific directory.
-    //
     if ((pid == os::current_process_id()) ||
         (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
 
-        remove_file(dirname, entry->d_name);
+        unlink(entry->d_name);
     }
     errno = 0;
   }
-  os::closedir(dirp);
-  FREE_C_HEAP_ARRAY(char, dbuf);
+
+  // Close the directory and reset the current working directory.
+  close_directory_secure_cwd(dirp, saved_cwd_fd);
+
+  FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
 }
 
-// make the user specific temporary directory. Returns true if
+// Make the user specific temporary directory. Returns true if
 // the directory exists and is secure upon return. Returns false
 // if the directory exists but is either a symlink, is otherwise
 // insecure, or if an error occurred.
-//
 static bool make_user_tmp_dir(const char* dirname) {
 
-  // create the directory with 0755 permissions. note that the directory
+  // Create the directory with 0755 permissions. note that the directory
   // will be owned by euid::egid, which may not be the same as uid::gid.
-  //
   if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) {
     if (errno == EEXIST) {
       // The directory already exists and was probably created by another
       // JVM instance. However, this could also be the result of a
       // deliberate symlink. Verify that the existing directory is safe.
-      //
       if (!is_directory_secure(dirname)) {
-        // directory is not secure
+        // Directory is not secure.
         if (PrintMiscellaneous && Verbose) {
           warning("%s directory is insecure\n", dirname);
         }
@@ -614,19 +850,63 @@
     return -1;
   }
 
+  int saved_cwd_fd;
+  // Open the directory and set the current working directory to it.
+  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
+  if (dirp == NULL) {
+    // Directory doesn't exist or is insecure, so cannot create shared
+    // memory file.
+    return -1;
+  }
+
+  // Open the filename in the current directory.
+  // Cannot use O_TRUNC here; truncation of an existing file has to happen
+  // after the is_file_secure() check below.
   int result;
 
-  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result);
+  // No O_NOFOLLOW defined at buildtime, and it is not documented for open;
+  // so provide a workaround in this case.
+#ifdef O_NOFOLLOW
+  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result);
+#else
+  // workaround function (jdk6 code)
+  RESTARTABLE(::open_o_nofollow(filename, O_RDWR|O_CREAT, S_IREAD|S_IWRITE), result);
+#endif
+
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("could not create file %s: %s\n", filename, strerror(errno));
+      if (errno == ELOOP) {
+        warning("file %s is a symlink and is not secure\n", filename);
+      } else {
+        warning("could not create file %s: %s\n", filename, strerror(errno));
+      }
     }
+    // Close the directory and reset the current working directory.
+    close_directory_secure_cwd(dirp, saved_cwd_fd);
+
     return -1;
   }
+  // Close the directory and reset the current working directory.
+  close_directory_secure_cwd(dirp, saved_cwd_fd);
 
   // save the file descriptor
   int fd = result;
 
+  // Check to see if the file is secure.
+  if (!is_file_secure(fd, filename)) {
+    ::close(fd);
+    return -1;
+  }
+
+  // Truncate the file to get rid of any existing data.
+  RESTARTABLE(::ftruncate(fd, (off_t)0), result);
+  if (result == OS_ERR) {
+    if (PrintMiscellaneous && Verbose) {
+      warning("could not truncate shared memory file: %s\n", strerror(errno));
+    }
+    ::close(fd);
+    return -1;
+  }
   // set the file size
   RESTARTABLE(::ftruncate(fd, (off_t)size), result);
   if (result == OS_ERR) {
@@ -648,7 +928,14 @@
 
   // open the file
   int result;
+  // No O_NOFOLLOW defined at buildtime, and it is not documented for open;
+  // so provide a workaround in this case
+#ifdef O_NOFOLLOW
   RESTARTABLE(::open(filename, oflags), result);
+#else
+  RESTARTABLE(::open_o_nofollow(filename, oflags), result);
+#endif
+
   if (result == OS_ERR) {
     if (errno == ENOENT) {
       THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
@@ -662,8 +949,15 @@
       THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
     }
   }
+  int fd = result;
 
-  return result;
+  // Check to see if the file is secure.
+  if (!is_file_secure(fd, filename)) {
+    ::close(fd);
+    return -1;
+  }
+
+  return fd;
 }
 
 // create a named shared memory region. returns the address of the
@@ -695,13 +989,21 @@
   char* dirname = get_user_tmp_dir(user_name);
   char* filename = get_sharedmem_filename(dirname, vmid);
 
+  // Get the short filename.
+  char* short_filename = strrchr(filename, '/');
+  if (short_filename == NULL) {
+    short_filename = filename;
+  } else {
+    short_filename++;
+  }
+
   // cleanup any stale shared memory files
   cleanup_sharedmem_resources(dirname);
 
   assert(((size > 0) && (size % os::vm_page_size() == 0)),
          "unexpected PerfMemory region size");
 
-  fd = create_sharedmem_resources(dirname, filename, size);
+  fd = create_sharedmem_resources(dirname, short_filename, size);
 
   FREE_C_HEAP_ARRAY(char, user_name);
   FREE_C_HEAP_ARRAY(char, dirname);
@@ -733,6 +1035,9 @@
   // clear the shared memory region
   (void)::memset((void*) mapAddress, 0, size);
 
+  // It does not go through os api, the operation has to record from here.
+  MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC, mtInternal);
+
   return mapAddress;
 }
 
@@ -807,7 +1112,7 @@
   char* mapAddress;
   int result;
   int fd;
-  size_t size;
+  size_t size = 0;
   const char* luser = NULL;
 
   int mmap_prot;
@@ -819,12 +1124,18 @@
   // constructs for the file and the shared memory mapping.
   if (mode == PerfMemory::PERF_MODE_RO) {
     mmap_prot = PROT_READ;
+
+  // No O_NOFOLLOW defined at buildtime, and it is not documented for open.
+#ifdef O_NOFOLLOW
+    file_flags = O_RDONLY | O_NOFOLLOW;
+#else
     file_flags = O_RDONLY;
+#endif
   }
   else if (mode == PerfMemory::PERF_MODE_RW) {
 #ifdef LATER
     mmap_prot = PROT_READ | PROT_WRITE;
-    file_flags = O_RDWR;
+    file_flags = O_RDWR | O_NOFOLLOW;
 #else
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               "Unsupported access mode");
@@ -853,9 +1164,9 @@
   // store file, we don't follow them when attaching either.
   //
   if (!is_directory_secure(dirname)) {
-    FREE_C_HEAP_ARRAY(char, dirname);
+    FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
     if (luser != user) {
-      FREE_C_HEAP_ARRAY(char, luser);
+      FREE_C_HEAP_ARRAY(char, luser, mtInternal);
     }
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               "Process not found");
@@ -901,6 +1212,9 @@
               "Could not map PerfMemory");
   }
 
+  // It does not go through os api, the operation has to record from here.
+  MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC, mtInternal);
+
   *addr = mapAddress;
   *sizep = size;
 
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -428,9 +428,9 @@
   }
 
   // Diagnostic code to investigate JDK-6573254
-  int res = 50115;  // non-java thread
+  int res = 30115;  // non-java thread
   if (thread->is_Java_thread()) {
-    res = 40115;    // java thread
+    res = 20115;    // java thread
   }
 
   // Install a win32 structured exception handler around every thread created
@@ -3791,6 +3791,7 @@
 
     static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT;
     static CRITICAL_SECTION crit_sect;
+    static volatile jint process_exiting = 0;
     int i, j;
     DWORD res;
     HANDLE hproc, hthr;
@@ -3798,10 +3799,10 @@
     // The first thread that reached this point, initializes the critical section.
     if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) {
       warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__);
-    } else {
+    } else if (OrderAccess::load_acquire(&process_exiting) == 0) {
       EnterCriticalSection(&crit_sect);
 
-      if (what == EPT_THREAD) {
+      if (what == EPT_THREAD && OrderAccess::load_acquire(&process_exiting) == 0) {
         // Remove from the array those handles of the threads that have completed exiting.
         for (i = 0, j = 0; i < handle_count; ++i) {
           res = WaitForSingleObject(handles[i], 0 /* don't wait */);
@@ -3856,7 +3857,7 @@
         // The current exiting thread has stored its handle in the array, and now
         // should leave the critical section before calling _endthreadex().
 
-      } else { // what != EPT_THREAD
+      } else if (what != EPT_THREAD) {
         if (handle_count > 0) {
           // Before ending the process, make sure all the threads that had called
           // _endthreadex() completed.
@@ -3882,24 +3883,28 @@
           handle_count = 0;
         }
 
-        // End the process, not leaving critical section.
-        // This makes sure no other thread executes exit-related code at the same
-        // time, thus a race is avoided.
-        if (what == EPT_PROCESS) {
-          ::exit(exit_code);
-        } else {
-          _exit(exit_code);
-        }
+        OrderAccess::release_store(&process_exiting, 1);
       }
 
       LeaveCriticalSection(&crit_sect);
     }
+
+    if (what == EPT_THREAD) {
+      while (OrderAccess::load_acquire(&process_exiting) != 0) {
+        // Some other thread is about to call exit(), so we
+        // don't let the current thread proceed to _endthreadex()
+        SuspendThread(GetCurrentThread());
+        // Avoid busy-wait loop, if SuspendThread() failed.
+        Sleep(EXIT_TIMEOUT);
+      }
+    }
   }
 
   // We are here if either
   // - there's no 'race at exit' bug on this OS release;
   // - initialization of the critical section failed (unlikely);
-  // - the current thread has stored its handle and left the critical section.
+  // - the current thread has stored its handle and left the critical section;
+  // - the process-exiting thread has raised the flag and left the critical section.
   if (what == EPT_THREAD) {
     _endthreadex((unsigned)exit_code);
   } else if (what == EPT_PROCESS) {
--- a/hotspot/src/share/vm/c1/c1_CodeStubs.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/c1/c1_CodeStubs.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -601,15 +601,6 @@
   LIR_Opr _addr;
   LIR_Opr _new_val;
 
-  static jbyte* _byte_map_base;
-  static jbyte* byte_map_base_slow();
-  static jbyte* byte_map_base() {
-    if (_byte_map_base == NULL) {
-      _byte_map_base = byte_map_base_slow();
-    }
-    return _byte_map_base;
-  }
-
  public:
   // addr (the address of the object head) and new_val must be registers.
   G1PostBarrierStub(LIR_Opr addr, LIR_Opr new_val): _addr(addr), _new_val(new_val) { }
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -32,6 +32,7 @@
 #include "ci/ciArrayKlass.hpp"
 #include "ci/ciInstance.hpp"
 #include "ci/ciObjArray.hpp"
+#include "runtime/arguments.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/vm_version.hpp"
@@ -3351,7 +3352,12 @@
   if (!x->inlinee()->is_accessor()) {
     CodeEmitInfo* info = state_for(x, x->state(), true);
     // Notify the runtime very infrequently only to take care of counter overflows
-    increment_event_counter_impl(info, x->inlinee(), (1 << Tier23InlineeNotifyFreqLog) - 1, InvocationEntryBci, false, true);
+    int freq_log = Tier23InlineeNotifyFreqLog;
+    double scale;
+    if (_method->has_option_value("CompileThresholdScaling", scale)) {
+      freq_log = Arguments::scaled_freq_log(freq_log, scale);
+    }
+    increment_event_counter_impl(info, x->inlinee(), right_n_bits(freq_log), InvocationEntryBci, false, true);
   }
 }
 
@@ -3366,7 +3372,11 @@
     ShouldNotReachHere();
   }
   // Increment the appropriate invocation/backedge counter and notify the runtime.
-  increment_event_counter_impl(info, info->scope()->method(), (1 << freq_log) - 1, bci, backedge, true);
+  double scale;
+  if (_method->has_option_value("CompileThresholdScaling", scale)) {
+    freq_log = Arguments::scaled_freq_log(freq_log, scale);
+  }
+  increment_event_counter_impl(info, info->scope()->method(), right_n_bits(freq_log), bci, backedge, true);
 }
 
 void LIRGenerator::decrement_age(CodeEmitInfo* info) {
--- a/hotspot/src/share/vm/classfile/compactHashtable.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/classfile/compactHashtable.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -221,6 +221,30 @@
   return (const char*)end;
 }
 
+template <class T, class N> void CompactHashtable<T, N>::symbols_do(SymbolClosure *cl) {
+  assert(!DumpSharedSpaces, "run-time only");
+  for (juint i = 0; i < _bucket_count; i ++) {
+    juint bucket_info = _buckets[i];
+    juint bucket_offset = BUCKET_OFFSET(bucket_info);
+    int   bucket_type = BUCKET_TYPE(bucket_info);
+    juint* bucket = _buckets + bucket_offset;
+    juint* bucket_end = _buckets;
+
+    Symbol* sym;
+    if (bucket_type == COMPACT_BUCKET_TYPE) {
+      sym = (Symbol*)((void*)(_base_address + bucket[0]));
+      cl->do_symbol(&sym);
+    } else {
+      bucket_end += BUCKET_OFFSET(_buckets[i + 1]);
+      while (bucket < bucket_end) {
+        sym = (Symbol*)((void*)(_base_address + bucket[1]));
+        cl->do_symbol(&sym);
+        bucket += 2;
+      }
+    }
+  }
+}
+
 // Explicitly instantiate these types
 template class CompactHashtable<Symbol*, char>;
 
--- a/hotspot/src/share/vm/classfile/compactHashtable.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/classfile/compactHashtable.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -249,6 +249,9 @@
     }
     return NULL;
   }
+
+  // iterate over symbols
+  void symbols_do(SymbolClosure *cl);
 };
 
 ////////////////////////////////////////////////////////////////////////
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -82,6 +82,10 @@
 
 // Call function for all symbols in the symbol table.
 void SymbolTable::symbols_do(SymbolClosure *cl) {
+  // all symbols from shared table
+  _shared_table.symbols_do(cl);
+
+  // all symbols from the dynamic table
   const int n = the_table()->table_size();
   for (int i = 0; i < n; i++) {
     for (HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i);
--- a/hotspot/src/share/vm/classfile/verifier.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/classfile/verifier.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1546,10 +1546,15 @@
           no_control_flow = true; break;
         case Bytecodes::_getstatic :
         case Bytecodes::_putstatic :
+          // pass TRUE, operand can be an array type for getstatic/putstatic.
+          verify_field_instructions(
+            &bcs, &current_frame, cp, true, CHECK_VERIFY(this));
+          no_control_flow = false; break;
         case Bytecodes::_getfield :
         case Bytecodes::_putfield :
+          // pass FALSE, operand can't be an array type for getfield/putfield.
           verify_field_instructions(
-            &bcs, &current_frame, cp, CHECK_VERIFY(this));
+            &bcs, &current_frame, cp, false, CHECK_VERIFY(this));
           no_control_flow = false; break;
         case Bytecodes::_invokevirtual :
         case Bytecodes::_invokespecial :
@@ -2107,6 +2112,7 @@
 void ClassVerifier::verify_field_instructions(RawBytecodeStream* bcs,
                                               StackMapFrame* current_frame,
                                               constantPoolHandle cp,
+                                              bool allow_arrays,
                                               TRAPS) {
   u2 index = bcs->get_index_u2();
   verify_cp_type(bcs->bci(), index, cp,
@@ -2126,8 +2132,8 @@
   // Get referenced class type
   VerificationType ref_class_type = cp_ref_index_to_type(
     index, cp, CHECK_VERIFY(this));
-  if (!ref_class_type.is_object()) {
-    /* Unreachable?  Class file parser verifies Fieldref contents */
+  if (!ref_class_type.is_object() &&
+    (!allow_arrays || !ref_class_type.is_array())) {
     verify_error(ErrorContext::bad_type(bcs->bci(),
         TypeOrigin::cp(index, ref_class_type)),
         "Expecting reference to class in class %s at constant pool index %d",
--- a/hotspot/src/share/vm/classfile/verifier.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/classfile/verifier.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -297,7 +297,7 @@
 
   void verify_field_instructions(
     RawBytecodeStream* bcs, StackMapFrame* current_frame,
-    constantPoolHandle cp, TRAPS);
+    constantPoolHandle cp, bool allow_arrays, TRAPS);
 
   void verify_invoke_init(
     RawBytecodeStream* bcs, u2 ref_index, VerificationType ref_class_type,
--- a/hotspot/src/share/vm/code/codeCache.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -233,8 +233,8 @@
 ReservedCodeSpace CodeCache::reserve_heap_memory(size_t size) {
   // Determine alignment
   const size_t page_size = os::can_execute_large_page_memory() ?
-          MIN2(os::page_size_for_region(InitialCodeCacheSize, 8),
-               os::page_size_for_region(size, 8)) :
+          MIN2(os::page_size_for_region_aligned(InitialCodeCacheSize, 8),
+               os::page_size_for_region_aligned(size, 8)) :
           os::vm_page_size();
   const size_t granularity = os::vm_allocation_granularity();
   const size_t r_align = MAX2(page_size, granularity);
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1470,7 +1470,9 @@
 
   // The method may be explicitly excluded by the user.
   bool quietly;
-  if (CompilerOracle::should_exclude(method, quietly)) {
+  double scale;
+  if (CompilerOracle::should_exclude(method, quietly)
+      || (CompilerOracle::has_option_value(method, "CompileThresholdScaling", scale) && scale == 0)) {
     if (!quietly) {
       // This does not happen quietly...
       ResourceMark rm;
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -162,8 +162,8 @@
          "we should have already filtered out humongous regions");
   assert(_end == orig_end(),
          "we should have already filtered out humongous regions");
-
-  _in_collection_set = false;
+  assert(!_in_collection_set,
+         err_msg("Should not clear heap region %u in the collection set", hrm_index()));
 
   set_allocation_context(AllocationContext::system());
   set_young_index_in_cset(-1);
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1194,8 +1194,10 @@
         return real_forwardee(old);
     }
 
-    new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
-                                       old, m, sz);
+    if (!_promotion_failed) {
+      new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
+                                        old, m, sz);
+    }
 
     if (new_obj == NULL) {
       // promotion failed, forward to self
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -61,9 +61,9 @@
 
 void GenerationSizer::initialize_size_info() {
   trace_gen_sizes("ps heap raw");
-  const size_t max_page_sz = os::page_size_for_region(_max_heap_byte_size, 8);
+  const size_t max_page_sz = os::page_size_for_region_aligned(_max_heap_byte_size, 8);
   const size_t min_pages = 4; // 1 for eden + 1 for each survivor + 1 for old
-  const size_t min_page_sz = os::page_size_for_region(_min_heap_byte_size, min_pages);
+  const size_t min_page_sz = os::page_size_for_region_aligned(_min_heap_byte_size, min_pages);
   const size_t page_sz = MIN2(max_page_sz, min_page_sz);
 
   // Can a page size be something else than a power of two?
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -41,7 +41,7 @@
 
   const size_t words = bits / BitsPerWord;
   const size_t raw_bytes = words * sizeof(idx_t);
-  const size_t page_sz = os::page_size_for_region(raw_bytes, 10);
+  const size_t page_sz = os::page_size_for_region_aligned(raw_bytes, 10);
   const size_t granularity = os::vm_allocation_granularity();
   _reserved_byte_size = align_size_up(raw_bytes, MAX2(page_sz, granularity));
 
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -403,7 +403,7 @@
 ParallelCompactData::create_vspace(size_t count, size_t element_size)
 {
   const size_t raw_bytes = count * element_size;
-  const size_t page_sz = os::page_size_for_region(raw_bytes, 10);
+  const size_t page_sz = os::page_size_for_region_aligned(raw_bytes, 10);
   const size_t granularity = os::vm_allocation_granularity();
   _reserved_byte_size = align_size_up(raw_bytes, MAX2(page_sz, granularity));
 
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -53,7 +53,7 @@
 /*
  * USELABELS - If using GCC, then use labels for the opcode dispatching
  * rather -then a switch statement. This improves performance because it
- * gives us the oportunity to have the instructions that calculate the
+ * gives us the opportunity to have the instructions that calculate the
  * next opcode to jump to be intermixed with the rest of the instructions
  * that implement the opcode (see UPDATE_PC_AND_TOS_AND_CONTINUE macro).
  */
--- a/hotspot/src/share/vm/interpreter/invocationCounter.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/invocationCounter.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -36,7 +36,7 @@
 // Implementation notes: For space reasons, state & counter are both encoded in one word,
 // The state is encoded using some of the least significant bits, the counter is using the
 // more significant bits. The counter is incremented before a method is activated and an
-// action is triggered when when count() > limit().
+// action is triggered when count() > limit().
 
 class InvocationCounter VALUE_OBJ_CLASS_SPEC {
   friend class VMStructs;
@@ -48,7 +48,6 @@
     number_of_state_bits = 2,
     number_of_carry_bits = 1,
     number_of_noncount_bits = number_of_state_bits + number_of_carry_bits,
-    number_of_count_bits = BitsPerInt - number_of_noncount_bits,
     state_limit          = nth_bit(number_of_state_bits),
     count_grain          = nth_bit(number_of_state_bits + number_of_carry_bits),
     carry_mask           = right_n_bits(number_of_carry_bits) << number_of_state_bits,
@@ -68,6 +67,7 @@
     count_increment      = count_grain,          // use this value to increment the 32bit _counter word
     count_mask_value     = count_mask,           // use this value to mask the backedge counter
     count_shift          = number_of_noncount_bits,
+    number_of_count_bits = BitsPerInt - number_of_noncount_bits,
     count_limit          = nth_bit(number_of_count_bits - 1)
   };
 
--- a/hotspot/src/share/vm/memory/heap.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/memory/heap.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -104,8 +104,8 @@
   size_t page_size = os::vm_page_size();
   if (os::can_execute_large_page_memory()) {
     const size_t min_pages = 8;
-    page_size = MIN2(os::page_size_for_region(committed_size, min_pages),
-                     os::page_size_for_region(rs.size(), min_pages));
+    page_size = MIN2(os::page_size_for_region_aligned(committed_size, min_pages),
+                     os::page_size_for_region_aligned(rs.size(), min_pages));
   }
 
   const size_t granularity = os::vm_allocation_granularity();
--- a/hotspot/src/share/vm/oops/method.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/oops/method.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -412,15 +412,14 @@
   }
 
   methodHandle mh(m);
-  ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
-  MethodCounters* counters = MethodCounters::allocate(loader_data, THREAD);
+  MethodCounters* counters = MethodCounters::allocate(mh, THREAD);
   if (HAS_PENDING_EXCEPTION) {
     CompileBroker::log_metaspace_failure();
     ClassLoaderDataGraph::set_metaspace_oom(true);
     return NULL;   // return the exception (which is cleared)
   }
   if (!mh->init_method_counters(counters)) {
-    MetadataFactory::free_metadata(loader_data, counters);
+    MetadataFactory::free_metadata(mh->method_holder()->class_loader_data(), counters);
   }
   return mh->method_counters();
 }
--- a/hotspot/src/share/vm/oops/methodCounters.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/oops/methodCounters.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -23,10 +23,11 @@
  */
 #include "precompiled.hpp"
 #include "oops/methodCounters.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/handles.inline.hpp"
 
-MethodCounters* MethodCounters::allocate(ClassLoaderData* loader_data, TRAPS) {
-  return new(loader_data, size(), false, MetaspaceObj::MethodCountersType, THREAD) MethodCounters();
+MethodCounters* MethodCounters::allocate(methodHandle mh, TRAPS) {
+  ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
+  return new(loader_data, size(), false, MetaspaceObj::MethodCountersType, THREAD) MethodCounters(mh);
 }
 
 void MethodCounters::clear_counters() {
--- a/hotspot/src/share/vm/oops/methodCounters.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/oops/methodCounters.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -26,7 +26,9 @@
 #define SHARE_VM_OOPS_METHODCOUNTERS_HPP
 
 #include "oops/metadata.hpp"
+#include "compiler/compilerOracle.hpp"
 #include "interpreter/invocationCounter.hpp"
+#include "runtime/arguments.hpp"
 
 class MethodCounters: public MetaspaceObj {
  friend class VMStructs;
@@ -45,7 +47,11 @@
   // 3. (INT_MIN..0]                  - method is hot and will deopt and get
   //                                    recompiled without the counters
   int               _nmethod_age;
-
+  int               _interpreter_invocation_limit;        // per-method InterpreterInvocationLimit
+  int               _interpreter_backward_branch_limit;   // per-method InterpreterBackwardBranchLimit
+  int               _interpreter_profile_limit;           // per-method InterpreterProfileLimit
+  int               _invoke_mask;                         // per-method Tier0InvokeNotifyFreqLog
+  int               _backedge_mask;                       // per-method Tier0BackedgeNotifyFreqLog
 #ifdef TIERED
   float             _rate;                        // Events (invocation and backedge counter increments) per millisecond
   jlong             _prev_time;                   // Previous time the rate was acquired
@@ -53,15 +59,15 @@
   u1                _highest_osr_comp_level;      // Same for OSR level
 #endif
 
-  MethodCounters() : _interpreter_invocation_count(0),
-                     _interpreter_throwout_count(0),
-                     _number_of_breakpoints(0),
-                     _nmethod_age(INT_MAX)
+  MethodCounters(methodHandle mh) : _interpreter_invocation_count(0),
+                                    _interpreter_throwout_count(0),
+                                    _number_of_breakpoints(0),
+                                    _nmethod_age(INT_MAX)
 #ifdef TIERED
-                   , _rate(0),
-                     _prev_time(0),
-                     _highest_comp_level(0),
-                     _highest_osr_comp_level(0)
+                                 , _rate(0),
+                                   _prev_time(0),
+                                   _highest_comp_level(0),
+                                   _highest_osr_comp_level(0)
 #endif
   {
     invocation_counter()->init();
@@ -70,10 +76,28 @@
     if (StressCodeAging) {
       set_nmethod_age(HotMethodDetectionLimit);
     }
+
+    // Set per-method thresholds.
+    double scale = 1.0;
+    CompilerOracle::has_option_value(mh, "CompileThresholdScaling", scale);
+
+    int compile_threshold = Arguments::scaled_compile_threshold(CompileThreshold, scale);
+    _interpreter_invocation_limit = compile_threshold << InvocationCounter::count_shift;
+    if (ProfileInterpreter) {
+      // If interpreter profiling is enabled, the backward branch limit
+      // is compared against the method data counter rather than an invocation
+      // counter, therefore no shifting of bits is required.
+      _interpreter_backward_branch_limit = (compile_threshold * (OnStackReplacePercentage - InterpreterProfilePercentage)) / 100;
+    } else {
+      _interpreter_backward_branch_limit = ((compile_threshold * OnStackReplacePercentage) / 100) << InvocationCounter::count_shift;
+    }
+    _interpreter_profile_limit = ((compile_threshold * InterpreterProfilePercentage) / 100) << InvocationCounter::count_shift;
+    _invoke_mask = right_n_bits(Arguments::scaled_freq_log(Tier0InvokeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
+    _backedge_mask = right_n_bits(Arguments::scaled_freq_log(Tier0BackedgeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
   }
 
  public:
-  static MethodCounters* allocate(ClassLoaderData* loader_data, TRAPS);
+  static MethodCounters* allocate(methodHandle mh, TRAPS);
 
   void deallocate_contents(ClassLoaderData* loader_data) {}
   DEBUG_ONLY(bool on_stack() { return false; })  // for template
@@ -161,5 +185,24 @@
     return offset_of(MethodCounters, _interpreter_invocation_count);
   }
 
+  static ByteSize interpreter_invocation_limit_offset() {
+    return byte_offset_of(MethodCounters, _interpreter_invocation_limit);
+  }
+
+  static ByteSize interpreter_backward_branch_limit_offset() {
+    return byte_offset_of(MethodCounters, _interpreter_backward_branch_limit);
+  }
+
+  static ByteSize interpreter_profile_limit_offset() {
+    return byte_offset_of(MethodCounters, _interpreter_profile_limit);
+  }
+
+  static ByteSize invoke_mask_offset() {
+    return byte_offset_of(MethodCounters, _invoke_mask);
+  }
+
+  static ByteSize backedge_mask_offset() {
+    return byte_offset_of(MethodCounters, _backedge_mask);
+  }
 };
 #endif //SHARE_VM_OOPS_METHODCOUNTERS_HPP
--- a/hotspot/src/share/vm/oops/methodData.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/oops/methodData.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -31,6 +31,7 @@
 #include "memory/heapInspection.hpp"
 #include "oops/methodData.hpp"
 #include "prims/jvmtiRedefineClasses.hpp"
+#include "runtime/arguments.hpp"
 #include "runtime/compilationPolicy.hpp"
 #include "runtime/deoptimization.hpp"
 #include "runtime/handles.inline.hpp"
@@ -1131,6 +1132,13 @@
   _backedge_counter.init();
   _invocation_counter_start = 0;
   _backedge_counter_start = 0;
+
+  // Set per-method invoke- and backedge mask.
+  double scale = 1.0;
+  CompilerOracle::has_option_value(_method, "CompileThresholdScaling", scale);
+  _invoke_mask = right_n_bits(Arguments::scaled_freq_log(Tier0InvokeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
+  _backedge_mask = right_n_bits(Arguments::scaled_freq_log(Tier0BackedgeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
+
   _tenure_traps = 0;
   _num_loops = 0;
   _num_blocks = 0;
--- a/hotspot/src/share/vm/oops/methodData.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/oops/methodData.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -2088,6 +2088,8 @@
   int               _invocation_counter_start;
   int               _backedge_counter_start;
   uint              _tenure_traps;
+  int               _invoke_mask;      // per-method Tier0InvokeNotifyFreqLog
+  int               _backedge_mask;    // per-method Tier0BackedgeNotifyFreqLog
 
 #if INCLUDE_RTM_OPT
   // State of RTM code generation during compilation of the method
@@ -2447,10 +2449,19 @@
   static ByteSize invocation_counter_offset() {
     return byte_offset_of(MethodData, _invocation_counter);
   }
+
   static ByteSize backedge_counter_offset() {
     return byte_offset_of(MethodData, _backedge_counter);
   }
 
+  static ByteSize invoke_mask_offset() {
+    return byte_offset_of(MethodData, _invoke_mask);
+  }
+
+  static ByteSize backedge_mask_offset() {
+    return byte_offset_of(MethodData, _backedge_mask);
+  }
+
   static ByteSize parameters_type_data_di_offset() {
     return byte_offset_of(MethodData, _parameters_type_data_di);
   }
--- a/hotspot/src/share/vm/opto/chaitin.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/chaitin.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -582,6 +582,9 @@
   // Peephole remove copies
   post_allocate_copy_removal();
 
+  // Merge multidefs if multiple defs representing the same value are used in a single block.
+  merge_multidefs();
+
 #ifdef ASSERT
   // Veify the graph after RA.
   verify(&live_arena);
--- a/hotspot/src/share/vm/opto/chaitin.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/chaitin.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -681,6 +681,32 @@
   // Extend the node to LRG mapping
   void add_reference( const Node *node, const Node *old_node);
 
+  // Record the first use of a def in the block for a register.
+  class RegDefUse {
+    Node* _def;
+    Node* _first_use;
+  public:
+    RegDefUse() : _def(NULL), _first_use(NULL) { }
+    Node* def() const       { return _def;       }
+    Node* first_use() const { return _first_use; }
+
+    void update(Node* def, Node* use) {
+      if (_def != def) {
+        _def = def;
+        _first_use = use;
+      }
+    }
+    void clear() {
+      _def = NULL;
+      _first_use = NULL;
+    }
+  };
+  typedef GrowableArray<RegDefUse> RegToDefUseMap;
+  int possibly_merge_multidef(Node *n, uint k, Block *block, RegToDefUseMap& reg2defuse);
+
+  // Merge nodes that are a part of a multidef lrg and produce the same value within a block.
+  void merge_multidefs();
+
 private:
 
   static int _final_loads, _final_stores, _final_copies, _final_memoves;
--- a/hotspot/src/share/vm/opto/doCall.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/doCall.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -94,7 +94,7 @@
   if (log != NULL) {
     int rid = (receiver_count >= 0)? log->identify(profile.receiver(0)): -1;
     int r2id = (rid != -1 && profile.has_receiver(1))? log->identify(profile.receiver(1)):-1;
-    log->begin_elem("call method='%d' count='%d' prof_factor='%g'",
+    log->begin_elem("call method='%d' count='%d' prof_factor='%f'",
                     log->identify(callee), site_count, prof_factor);
     if (call_does_dispatch)  log->print(" virtual='1'");
     if (allow_inline)     log->print(" inline='1'");
--- a/hotspot/src/share/vm/opto/escape.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/escape.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -2010,14 +2010,9 @@
         bt = field->layout_type();
       } else {
         // Check for unsafe oop field access
-        for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
-          int opcode = n->fast_out(i)->Opcode();
-          if (opcode == Op_StoreP || opcode == Op_LoadP ||
-              opcode == Op_StoreN || opcode == Op_LoadN) {
-            bt = T_OBJECT;
-            (*unsafe) = true;
-            break;
-          }
+        if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN)) {
+          bt = T_OBJECT;
+          (*unsafe) = true;
         }
       }
     } else if (adr_type->isa_aryptr()) {
@@ -2031,13 +2026,8 @@
       }
     } else if (adr_type->isa_rawptr() || adr_type->isa_klassptr()) {
       // Allocation initialization, ThreadLocal field access, unsafe access
-      for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
-        int opcode = n->fast_out(i)->Opcode();
-        if (opcode == Op_StoreP || opcode == Op_LoadP ||
-            opcode == Op_StoreN || opcode == Op_LoadN) {
-          bt = T_OBJECT;
-          break;
-        }
+      if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN)) {
+        bt = T_OBJECT;
       }
     }
   }
@@ -3092,13 +3082,7 @@
         continue;
     } else if (n->Opcode() == Op_EncodeISOArray) {
       // get the memory projection
-      for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
-        Node *use = n->fast_out(i);
-        if (use->Opcode() == Op_SCMemProj) {
-          n = use;
-          break;
-        }
-      }
+      n = n->find_out_with(Op_SCMemProj);
       assert(n->Opcode() == Op_SCMemProj, "memory projection required");
     } else {
       assert(n->is_Mem(), "memory node required.");
@@ -3122,13 +3106,7 @@
         continue;  // don't push users
       } else if (n->is_LoadStore()) {
         // get the memory projection
-        for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
-          Node *use = n->fast_out(i);
-          if (use->Opcode() == Op_SCMemProj) {
-            n = use;
-            break;
-          }
-        }
+        n = n->find_out_with(Op_SCMemProj);
         assert(n->Opcode() == Op_SCMemProj, "memory projection required");
       }
     }
--- a/hotspot/src/share/vm/opto/ifg.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/ifg.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -535,12 +535,8 @@
       // The method add_input_to_liveout() keeps such nodes alive (put them on liveout list)
       // when it sees SCMemProj node in a block. Unfortunately SCMemProj node could be placed
       // in block in such order that KILL MachProj nodes are processed first.
-      uint cnt = def->outcnt();
-      for (uint i = 0; i < cnt; i++) {
-        Node* proj = def->raw_out(i);
-        if (proj->Opcode() == Op_SCMemProj) {
-          return false;
-        }
+      if (def->has_out_with(Op_SCMemProj)) {
+        return false;
       }
     }
     b->remove_node(location);
--- a/hotspot/src/share/vm/opto/loopTransform.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -2057,10 +2057,9 @@
   }
   Node *main_cmp = main_bol->in(1);
   if( main_cmp->outcnt() > 1 ) { // CmpNode shared?
-    _igvn.hash_delete(main_bol);
     main_cmp = main_cmp->clone();// Clone a private CmpNode
     register_new_node( main_cmp, main_cle->in(0) );
-    main_bol->set_req(1,main_cmp);
+    _igvn.replace_input_of(main_bol, 1, main_cmp);
   }
   // Hack the now-private loop bounds
   _igvn.replace_input_of(main_cmp, 2, main_limit);
--- a/hotspot/src/share/vm/opto/machnode.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/machnode.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -616,6 +616,29 @@
 #endif
 };
 
+// MachMergeNode is similar to a PhiNode in a sense it merges multiple values,
+// however it doesn't have a control input and is more like a MergeMem.
+// It is inserted after the register allocation is done to ensure that nodes use single
+// definition of a multidef lrg in a block.
+class MachMergeNode : public MachIdealNode {
+public:
+  MachMergeNode(Node *n1) {
+    init_class_id(Class_MachMerge);
+    add_req(NULL);
+    add_req(n1);
+  }
+  virtual const RegMask &out_RegMask() const { return in(1)->out_RegMask(); }
+  virtual const RegMask &in_RegMask(uint idx) const { return in(1)->in_RegMask(idx); }
+  virtual const class Type *bottom_type() const { return in(1)->bottom_type(); }
+  virtual uint ideal_reg() const { return bottom_type()->ideal_reg(); }
+  virtual uint oper_input_base() const { return 1; }
+  virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { }
+  virtual uint size(PhaseRegAlloc *ra_) const { return 0; }
+#ifndef PRODUCT
+  virtual const char *Name() const { return "MachMerge"; }
+#endif
+};
+
 //------------------------------MachBranchNode--------------------------------
 // Abstract machine branch Node
 class MachBranchNode : public MachIdealNode {
--- a/hotspot/src/share/vm/opto/macro.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/macro.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -258,14 +258,7 @@
     // Search for CastP2X->Xor->URShift->Cmp path which
     // checks if the store done to a different from the value's region.
     // And replace Cmp with #0 (false) to collapse G1 post barrier.
-    Node* xorx = NULL;
-    for (DUIterator_Fast imax, i = p2x->fast_outs(imax); i < imax; i++) {
-      Node* u = p2x->fast_out(i);
-      if (u->Opcode() == Op_XorX) {
-        xorx = u;
-        break;
-      }
-    }
+    Node* xorx = p2x->find_out_with(Op_XorX);
     assert(xorx != NULL, "missing G1 post barrier");
     Node* shift = xorx->unique_out();
     Node* cmpx = shift->unique_out();
--- a/hotspot/src/share/vm/opto/memnode.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -2609,7 +2609,6 @@
     return false; // if not a distinct instance, there may be aliases of the address
   for (DUIterator_Fast imax, i = adr->fast_outs(imax); i < imax; i++) {
     Node *use = adr->fast_out(i);
-    int opc = use->Opcode();
     if (use->is_Load() || use->is_LoadStore()) {
       return false;
     }
--- a/hotspot/src/share/vm/opto/node.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/node.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -881,6 +881,34 @@
     return (Node*) this;
 }
 
+// Find out of current node that matches opcode.
+Node* Node::find_out_with(int opcode) {
+  for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
+    Node* use = fast_out(i);
+    if (use->Opcode() == opcode) {
+      return use;
+    }
+  }
+  return NULL;
+}
+
+// Return true if the current node has an out that matches opcode.
+bool Node::has_out_with(int opcode) {
+  return (find_out_with(opcode) != NULL);
+}
+
+// Return true if the current node has an out that matches any of the opcodes.
+bool Node::has_out_with(int opcode1, int opcode2, int opcode3, int opcode4) {
+  for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
+      int opcode = fast_out(i)->Opcode();
+      if (opcode == opcode1 || opcode == opcode2 || opcode == opcode3 || opcode == opcode4) {
+        return true;
+      }
+  }
+  return false;
+}
+
+
 //---------------------------uncast_helper-------------------------------------
 Node* Node::uncast_helper(const Node* p) {
 #ifdef ASSERT
--- a/hotspot/src/share/vm/opto/node.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/node.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -98,6 +98,7 @@
 class MachSafePointNode;
 class MachSpillCopyNode;
 class MachTempNode;
+class MachMergeNode;
 class Matcher;
 class MemBarNode;
 class MemBarStoreStoreNode;
@@ -436,6 +437,13 @@
     return (this->uncast() == n->uncast());
   }
 
+  // Find out of current node that matches opcode.
+  Node* find_out_with(int opcode);
+  // Return true if the current node has an out that matches opcode.
+  bool has_out_with(int opcode);
+  // Return true if the current node has an out that matches any of the opcodes.
+  bool has_out_with(int opcode1, int opcode2, int opcode3, int opcode4);
+
 private:
   static Node* uncast_helper(const Node* n);
 
@@ -507,18 +515,25 @@
 
 //----------------- Other Node Properties
 
-  // Generate class id for some ideal nodes to avoid virtual query
-  // methods is_<Node>().
-  // Class id is the set of bits corresponded to the node class and all its
-  // super classes so that queries for super classes are also valid.
-  // Subclasses of the same super class have different assigned bit
-  // (the third parameter in the macro DEFINE_CLASS_ID).
-  // Classes with deeper hierarchy are declared first.
-  // Classes with the same hierarchy depth are sorted by usage frequency.
+  // Generate class IDs for (some) ideal nodes so that it is possible to determine
+  // the type of a node using a non-virtual method call (the method is_<Node>() below).
   //
-  // The query method masks the bits to cut off bits of subclasses
-  // and then compare the result with the class id
-  // (see the macro DEFINE_CLASS_QUERY below).
+  // A class ID of an ideal node is a set of bits. In a class ID, a single bit determines
+  // the type of the node the ID represents; another subset of an ID's bits are reserved
+  // for the superclasses of the node represented by the ID.
+  //
+  // By design, if A is a supertype of B, A.is_B() returns true and B.is_A()
+  // returns false. A.is_A() returns true.
+  //
+  // If two classes, A and B, have the same superclass, a different bit of A's class id
+  // is reserved for A's type than for B's type. That bit is specified by the third
+  // parameter in the macro DEFINE_CLASS_ID.
+  //
+  // By convention, classes with deeper hierarchy are declared first. Moreover,
+  // classes with the same hierarchy depth are sorted by usage frequency.
+  //
+  // The query method masks the bits to cut off bits of subclasses and then compares
+  // the result with the class id (see the macro DEFINE_CLASS_QUERY below).
   //
   //  Class_MachCall=30, ClassMask_MachCall=31
   // 12               8               4               0
@@ -592,6 +607,7 @@
       DEFINE_CLASS_ID(MachTemp,         Mach, 3)
       DEFINE_CLASS_ID(MachConstantBase, Mach, 4)
       DEFINE_CLASS_ID(MachConstant,     Mach, 5)
+      DEFINE_CLASS_ID(MachMerge,        Mach, 6)
 
     DEFINE_CLASS_ID(Type,  Node, 2)
       DEFINE_CLASS_ID(Phi,   Type, 0)
@@ -763,6 +779,7 @@
   DEFINE_CLASS_QUERY(MachSafePoint)
   DEFINE_CLASS_QUERY(MachSpillCopy)
   DEFINE_CLASS_QUERY(MachTemp)
+  DEFINE_CLASS_QUERY(MachMerge)
   DEFINE_CLASS_QUERY(Mem)
   DEFINE_CLASS_QUERY(MemBar)
   DEFINE_CLASS_QUERY(MemBarStoreStore)
--- a/hotspot/src/share/vm/opto/parse1.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/parse1.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -441,7 +441,7 @@
 
   CompileLog* log = C->log();
   if (log != NULL) {
-    log->begin_head("parse method='%d' uses='%g'",
+    log->begin_head("parse method='%d' uses='%f'",
                     log->identify(parse_method), expected_uses);
     if (depth() == 1 && C->is_osr_compilation()) {
       log->print(" osr_bci='%d'", C->entry_bci());
--- a/hotspot/src/share/vm/opto/parse2.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/parse2.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -832,7 +832,7 @@
       sprintf(prob_str_buf, "%g", prob);
       prob_str = prob_str_buf;
     }
-    C->log()->elem("branch target_bci='%d' taken='%d' not_taken='%d' cnt='%g' prob='%s'",
+    C->log()->elem("branch target_bci='%d' taken='%d' not_taken='%d' cnt='%f' prob='%s'",
                    iter().get_dest(), taken, not_taken, cnt, prob_str);
   }
   return prob;
--- a/hotspot/src/share/vm/opto/phase.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/phase.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -110,6 +110,7 @@
     tty->print_cr ("         Compute Liveness:    %7.3f s", timers[_t_computeLive].seconds());
     tty->print_cr ("         Regalloc Split:      %7.3f s", timers[_t_regAllocSplit].seconds());
     tty->print_cr ("         Postalloc Copy Rem:  %7.3f s", timers[_t_postAllocCopyRemoval].seconds());
+    tty->print_cr ("         Merge multidefs:     %7.3f s", timers[_t_mergeMultidefs].seconds());
     tty->print_cr ("         Fixup Spills:        %7.3f s", timers[_t_fixupSpills].seconds());
     tty->print_cr ("         Compact:             %7.3f s", timers[_t_chaitinCompact].seconds());
     tty->print_cr ("         Coalesce 1:          %7.3f s", timers[_t_chaitinCoalesce1].seconds());
@@ -126,6 +127,7 @@
        timers[_t_computeLive].seconds() +
        timers[_t_regAllocSplit].seconds() +
        timers[_t_postAllocCopyRemoval].seconds() +
+       timers[_t_mergeMultidefs].seconds() +
        timers[_t_fixupSpills].seconds() +
        timers[_t_chaitinCompact].seconds() +
        timers[_t_chaitinCoalesce1].seconds() +
--- a/hotspot/src/share/vm/opto/phase.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/phase.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -88,6 +88,7 @@
       _t_computeLive,
       _t_regAllocSplit,
       _t_postAllocCopyRemoval,
+      _t_mergeMultidefs,
       _t_fixupSpills,
       _t_chaitinCompact,
       _t_chaitinCoalesce1,
--- a/hotspot/src/share/vm/opto/postaloc.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/postaloc.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -263,20 +263,6 @@
   // intermediate copies might be illegal, i.e., value is stored down to stack
   // then reloaded BUT survives in a register the whole way.
   Node *val = skip_copies(n->in(k));
-
-  if (val == x && nk_idx != 0 &&
-      regnd[nk_reg] != NULL && regnd[nk_reg] != x &&
-      _lrg_map.live_range_id(x) == _lrg_map.live_range_id(regnd[nk_reg])) {
-    // When rematerialzing nodes and stretching lifetimes, the
-    // allocator will reuse the original def for multidef LRG instead
-    // of the current reaching def because it can't know it's safe to
-    // do so.  After allocation completes if they are in the same LRG
-    // then it should use the current reaching def instead.
-    n->set_req(k, regnd[nk_reg]);
-    blk_adjust += yank_if_dead(val, current_block, &value, &regnd);
-    val = skip_copies(n->in(k));
-  }
-
   if (val == x) return blk_adjust; // No progress?
 
   int n_regs = RegMask::num_registers(val->ideal_reg());
@@ -382,6 +368,94 @@
   return false;
 }
 
+// The algorithms works as follows:
+// We traverse the block top to bottom. possibly_merge_multidef() is invoked for every input edge k
+// of the instruction n. We check to see if the input is a multidef lrg. If it is, we record the fact that we've
+// seen a definition (coming as an input) and add that fact to the reg2defuse array. The array maps registers to their
+// current reaching definitions (we track only multidefs though). With each definition we also associate the first
+// instruction we saw use it. If we encounter the situation when we observe an def (an input) that is a part of the
+// same lrg but is different from the previous seen def we merge the two with a MachMerge node and substitute
+// all the uses that we've seen so far to use the merge. After that we keep replacing the new defs in the same lrg
+// as they get encountered with the merge node and keep adding these defs to the merge inputs.
+void PhaseChaitin::merge_multidefs() {
+  Compile::TracePhase tp("mergeMultidefs", &timers[_t_mergeMultidefs]);
+  ResourceMark rm;
+  // Keep track of the defs seen in registers and collect their uses in the block.
+  RegToDefUseMap reg2defuse(_max_reg, _max_reg, RegDefUse());
+  for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+    Block* block = _cfg.get_block(i);
+    for (uint j = 1; j < block->number_of_nodes(); j++) {
+      Node* n = block->get_node(j);
+      if (n->is_Phi()) continue;
+      for (uint k = 1; k < n->req(); k++) {
+        j += possibly_merge_multidef(n, k, block, reg2defuse);
+      }
+      // Null out the value produced by the instruction itself, since we're only interested in defs
+      // implicitly defined by the uses. We are actually interested in tracking only redefinitions
+      // of the multidef lrgs in the same register. For that matter it's enough to track changes in
+      // the base register only and ignore other effects of multi-register lrgs and fat projections.
+      // It is also ok to ignore defs coming from singledefs. After an implicit overwrite by one of
+      // those our register is guaranteed to be used by another lrg and we won't attempt to merge it.
+      uint lrg = _lrg_map.live_range_id(n);
+      if (lrg > 0 && lrgs(lrg).is_multidef()) {
+        OptoReg::Name reg = lrgs(lrg).reg();
+        reg2defuse.at(reg).clear();
+      }
+    }
+    // Clear reg->def->use tracking for the next block
+    for (int j = 0; j < reg2defuse.length(); j++) {
+      reg2defuse.at(j).clear();
+    }
+  }
+}
+
+int PhaseChaitin::possibly_merge_multidef(Node *n, uint k, Block *block, RegToDefUseMap& reg2defuse) {
+  int blk_adjust = 0;
+
+  uint lrg = _lrg_map.live_range_id(n->in(k));
+  if (lrg > 0 && lrgs(lrg).is_multidef()) {
+    OptoReg::Name reg = lrgs(lrg).reg();
+
+    Node* def = reg2defuse.at(reg).def();
+    if (def != NULL && lrg == _lrg_map.live_range_id(def) && def != n->in(k)) {
+      // Same lrg but different node, we have to merge.
+      MachMergeNode* merge;
+      if (def->is_MachMerge()) { // is it already a merge?
+        merge = def->as_MachMerge();
+      } else {
+        merge = new MachMergeNode(def);
+
+        // Insert the merge node into the block before the first use.
+        uint use_index = block->find_node(reg2defuse.at(reg).first_use());
+        block->insert_node(merge, use_index++);
+
+        // Let the allocator know about the new node, use the same lrg
+        _lrg_map.extend(merge->_idx, lrg);
+        blk_adjust++;
+
+        // Fixup all the uses (there is at least one) that happened between the first
+        // use and before the current one.
+        for (; use_index < block->number_of_nodes(); use_index++) {
+          Node* use = block->get_node(use_index);
+          if (use == n) {
+            break;
+          }
+          use->replace_edge(def, merge);
+        }
+      }
+      if (merge->find_edge(n->in(k)) == -1) {
+        merge->add_req(n->in(k));
+      }
+      n->set_req(k, merge);
+    }
+
+    // update the uses
+    reg2defuse.at(reg).update(n->in(k), n);
+  }
+
+  return blk_adjust;
+}
+
 
 //------------------------------post_allocate_copy_removal---------------------
 // Post-Allocation peephole copy removal.  We do this in 1 pass over the
--- a/hotspot/src/share/vm/opto/stringopts.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/opto/stringopts.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1507,10 +1507,12 @@
       }
       case StringConcat::StringMode: {
         const Type* type = kit.gvn().type(arg);
+        Node* count = NULL;
         if (type == TypePtr::NULL_PTR) {
           // replace the argument with the null checked version
           arg = null_string;
           sc->set_argument(argi, arg);
+          count = kit.load_String_length(kit.control(), arg);
         } else if (!type->higher_equal(TypeInstPtr::NOTNULL)) {
           // s = s != null ? s : "null";
           // length = length + (s.count - s.offset);
@@ -1533,10 +1535,13 @@
           // replace the argument with the null checked version
           arg = phi;
           sc->set_argument(argi, arg);
+          count = kit.load_String_length(kit.control(), arg);
+        } else {
+          // A corresponding nullcheck will be connected during IGVN MemNode::Ideal_common_DU_postCCP
+          // kit.control might be a different test, that can be hoisted above the actual nullcheck
+          // in case, that the control input is not null, Ideal_common_DU_postCCP will not look for a nullcheck.
+          count = kit.load_String_length(NULL, arg);
         }
-
-        Node* count = kit.load_String_length(kit.control(), arg);
-
         length = __ AddI(length, count);
         string_sizes->init_req(argi, NULL);
         break;
--- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -68,11 +68,11 @@
 
   ~JvmtiConstantPoolReconstituter() {
     if (_symmap != NULL) {
-      os::free(_symmap);
+      delete _symmap;
       _symmap = NULL;
     }
     if (_classmap != NULL) {
-      os::free(_classmap);
+      delete _classmap;
       _classmap = NULL;
     }
   }
--- a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1046,10 +1046,16 @@
 {
   assert(str->klass() == SystemDictionary::String_klass(), "not a string");
 
+  typeArrayOop s_value = java_lang_String::value(str);
+
+  // JDK-6584008: the value field may be null if a String instance is
+  // partially constructed.
+  if (s_value == NULL) {
+    return 0;
+  }
   // get the string value and length
   // (string value may be offset from the base)
   int s_len = java_lang_String::length(str);
-  typeArrayOop s_value = java_lang_String::value(str);
   int s_offset = java_lang_String::offset(str);
   jchar* value;
   if (s_len > 0) {
--- a/hotspot/src/share/vm/prims/perf.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/prims/perf.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -100,6 +100,11 @@
 
   PerfWrapper("Perf_Detach");
 
+  if (!UsePerfData) {
+    // With -XX:-UsePerfData, detach is just a NOP
+    return;
+  }
+
   void* address = 0;
   jlong capacity = 0;
 
--- a/hotspot/src/share/vm/prims/unsafe.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/prims/unsafe.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1104,43 +1104,6 @@
 
 
 
-UNSAFE_ENTRY(void, Unsafe_MonitorEnter(JNIEnv *env, jobject unsafe, jobject jobj))
-  UnsafeWrapper("Unsafe_MonitorEnter");
-  {
-    if (jobj == NULL) {
-      THROW(vmSymbols::java_lang_NullPointerException());
-    }
-    Handle obj(thread, JNIHandles::resolve_non_null(jobj));
-    ObjectSynchronizer::jni_enter(obj, CHECK);
-  }
-UNSAFE_END
-
-
-UNSAFE_ENTRY(jboolean, Unsafe_TryMonitorEnter(JNIEnv *env, jobject unsafe, jobject jobj))
-  UnsafeWrapper("Unsafe_TryMonitorEnter");
-  {
-    if (jobj == NULL) {
-      THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);
-    }
-    Handle obj(thread, JNIHandles::resolve_non_null(jobj));
-    bool res = ObjectSynchronizer::jni_try_enter(obj, CHECK_0);
-    return (res ? JNI_TRUE : JNI_FALSE);
-  }
-UNSAFE_END
-
-
-UNSAFE_ENTRY(void, Unsafe_MonitorExit(JNIEnv *env, jobject unsafe, jobject jobj))
-  UnsafeWrapper("Unsafe_MonitorExit");
-  {
-    if (jobj == NULL) {
-      THROW(vmSymbols::java_lang_NullPointerException());
-    }
-    Handle obj(THREAD, JNIHandles::resolve_non_null(jobj));
-    ObjectSynchronizer::jni_exit(obj(), CHECK);
-  }
-UNSAFE_END
-
-
 UNSAFE_ENTRY(void, Unsafe_ThrowException(JNIEnv *env, jobject unsafe, jthrowable thr))
   UnsafeWrapper("Unsafe_ThrowException");
   {
@@ -1365,8 +1328,6 @@
     {CC"defineClass",        CC"("DC0_Args")"CLS,        FN_PTR(Unsafe_DefineClass0)},
     {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
     {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
-    {CC"monitorEnter",       CC"("OBJ")V",               FN_PTR(Unsafe_MonitorEnter)},
-    {CC"monitorExit",        CC"("OBJ")V",               FN_PTR(Unsafe_MonitorExit)},
     {CC"throwException",     CC"("THR")V",               FN_PTR(Unsafe_ThrowException)}
 };
 
@@ -1411,8 +1372,6 @@
     {CC"defineClass",        CC"("DC0_Args")"CLS,        FN_PTR(Unsafe_DefineClass0)},
     {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
     {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
-    {CC"monitorEnter",       CC"("OBJ")V",               FN_PTR(Unsafe_MonitorEnter)},
-    {CC"monitorExit",        CC"("OBJ")V",               FN_PTR(Unsafe_MonitorExit)},
     {CC"throwException",     CC"("THR")V",               FN_PTR(Unsafe_ThrowException)}
 
 };
@@ -1461,8 +1420,6 @@
     {CC"defineClass",        CC"("DC0_Args")"CLS,        FN_PTR(Unsafe_DefineClass0)},
     {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
     {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
-    {CC"monitorEnter",       CC"("OBJ")V",               FN_PTR(Unsafe_MonitorEnter)},
-    {CC"monitorExit",        CC"("OBJ")V",               FN_PTR(Unsafe_MonitorExit)},
     {CC"throwException",     CC"("THR")V",               FN_PTR(Unsafe_ThrowException)},
     {CC"compareAndSwapObject", CC"("OBJ"J"OBJ""OBJ")Z",  FN_PTR(Unsafe_CompareAndSwapObject)},
     {CC"compareAndSwapInt",  CC"("OBJ"J""I""I"")Z",      FN_PTR(Unsafe_CompareAndSwapInt)},
@@ -1515,9 +1472,6 @@
     {CC"defineClass",        CC"("DC0_Args")"CLS,        FN_PTR(Unsafe_DefineClass0)},
     {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
     {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
-    {CC"monitorEnter",       CC"("OBJ")V",               FN_PTR(Unsafe_MonitorEnter)},
-    {CC"monitorExit",        CC"("OBJ")V",               FN_PTR(Unsafe_MonitorExit)},
-    {CC"tryMonitorEnter",    CC"("OBJ")Z",               FN_PTR(Unsafe_TryMonitorEnter)},
     {CC"throwException",     CC"("THR")V",               FN_PTR(Unsafe_ThrowException)},
     {CC"compareAndSwapObject", CC"("OBJ"J"OBJ""OBJ")Z",  FN_PTR(Unsafe_CompareAndSwapObject)},
     {CC"compareAndSwapInt",  CC"("OBJ"J""I""I"")Z",      FN_PTR(Unsafe_CompareAndSwapInt)},
@@ -1571,9 +1525,6 @@
 
     {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
     {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
-    {CC"monitorEnter",       CC"("OBJ")V",               FN_PTR(Unsafe_MonitorEnter)},
-    {CC"monitorExit",        CC"("OBJ")V",               FN_PTR(Unsafe_MonitorExit)},
-    {CC"tryMonitorEnter",    CC"("OBJ")Z",               FN_PTR(Unsafe_TryMonitorEnter)},
     {CC"throwException",     CC"("THR")V",               FN_PTR(Unsafe_ThrowException)},
     {CC"compareAndSwapObject", CC"("OBJ"J"OBJ""OBJ")Z",  FN_PTR(Unsafe_CompareAndSwapObject)},
     {CC"compareAndSwapInt",  CC"("OBJ"J""I""I"")Z",      FN_PTR(Unsafe_CompareAndSwapInt)},
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -155,7 +155,7 @@
   if (mdo != NULL) {
     int i = mdo->invocation_count_delta();
     int b = mdo->backedge_count_delta();
-    return call_predicate_helper<CompLevel_full_profile>(i, b, 1);
+    return call_predicate_helper<CompLevel_full_profile>(i, b, 1, method);
   }
   return false;
 }
@@ -229,32 +229,32 @@
 // Tier?LoadFeedback is basically a coefficient that determines of
 // how many methods per compiler thread can be in the queue before
 // the threshold values double.
-bool AdvancedThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level) {
+bool AdvancedThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level, Method* method) {
   switch(cur_level) {
   case CompLevel_none:
   case CompLevel_limited_profile: {
     double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
-    return loop_predicate_helper<CompLevel_none>(i, b, k);
+    return loop_predicate_helper<CompLevel_none>(i, b, k, method);
   }
   case CompLevel_full_profile: {
     double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
-    return loop_predicate_helper<CompLevel_full_profile>(i, b, k);
+    return loop_predicate_helper<CompLevel_full_profile>(i, b, k, method);
   }
   default:
     return true;
   }
 }
 
-bool AdvancedThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level) {
+bool AdvancedThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level, Method* method) {
   switch(cur_level) {
   case CompLevel_none:
   case CompLevel_limited_profile: {
     double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
-    return call_predicate_helper<CompLevel_none>(i, b, k);
+    return call_predicate_helper<CompLevel_none>(i, b, k, method);
   }
   case CompLevel_full_profile: {
     double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
-    return call_predicate_helper<CompLevel_full_profile>(i, b, k);
+    return call_predicate_helper<CompLevel_full_profile>(i, b, k, method);
   }
   default:
     return true;
@@ -271,7 +271,7 @@
     int i = method->invocation_count();
     int b = method->backedge_count();
     double k = Tier0ProfilingStartPercentage / 100.0;
-    return call_predicate_helper<CompLevel_none>(i, b, k) || loop_predicate_helper<CompLevel_none>(i, b, k);
+    return call_predicate_helper<CompLevel_none>(i, b, k, method) || loop_predicate_helper<CompLevel_none>(i, b, k, method);
   }
   return false;
 }
@@ -348,7 +348,7 @@
       // If we were at full profile level, would we switch to full opt?
       if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) {
         next_level = CompLevel_full_optimization;
-      } else if ((this->*p)(i, b, cur_level)) {
+      } else if ((this->*p)(i, b, cur_level, method)) {
         // C1-generated fully profiled code is about 30% slower than the limited profile
         // code that has only invocation and backedge counters. The observation is that
         // if C2 queue is large enough we can spend too much time in the fully profiled code
@@ -374,7 +374,7 @@
           if (mdo->would_profile()) {
             if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
                                      Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
-                                     (this->*p)(i, b, cur_level))) {
+                                     (this->*p)(i, b, cur_level, method))) {
               next_level = CompLevel_full_profile;
             }
           } else {
@@ -390,7 +390,7 @@
           if (mdo->would_profile()) {
             int mdo_i = mdo->invocation_count_delta();
             int mdo_b = mdo->backedge_count_delta();
-            if ((this->*p)(mdo_i, mdo_b, cur_level)) {
+            if ((this->*p)(mdo_i, mdo_b, cur_level, method)) {
               next_level = CompLevel_full_optimization;
             }
           } else {
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -84,7 +84,7 @@
  *   invocation and backedge notifications. Basically every n-th invocation or backedge a mutator thread
  *   makes a call into the runtime.
  *
- * - Tier?CompileThreshold, Tier?BackEdgeThreshold, Tier?MinInvocationThreshold control
+ * - Tier?InvocationThreshold, Tier?CompileThreshold, Tier?BackEdgeThreshold, Tier?MinInvocationThreshold control
  *   compilation thresholds.
  *   Level 2 thresholds are not used and are provided for option-compatibility and potential future use.
  *   Other thresholds work as follows:
@@ -100,7 +100,9 @@
  *   The same predicate is used to control the transition from level 3 to level 4 (C2). It should be
  *   noted though that the thresholds are relative. Moreover i and b for the 0->3 transition come
  *   from Method* and for 3->4 transition they come from MDO (since profiled invocations are
- *   counted separately).
+ *   counted separately). Finally, if a method does not contain anything worth profiling, a transition
+ *   from level 3 to level 4 occurs without considering thresholds (e.g., with fewer invocations than
+ *   what is specified by Tier4InvocationThreshold).
  *
  *   OSR transitions are controlled simply with b > TierXBackEdgeThreshold * s predicates.
  *
@@ -164,9 +166,9 @@
   // Call and loop predicates determine whether a transition to a higher compilation
   // level should be performed (pointers to predicate functions are passed to common().
   // Predicates also take compiler load into account.
-  typedef bool (AdvancedThresholdPolicy::*Predicate)(int i, int b, CompLevel cur_level);
-  bool call_predicate(int i, int b, CompLevel cur_level);
-  bool loop_predicate(int i, int b, CompLevel cur_level);
+  typedef bool (AdvancedThresholdPolicy::*Predicate)(int i, int b, CompLevel cur_level, Method* method);
+  bool call_predicate(int i, int b, CompLevel cur_level, Method* method);
+  bool loop_predicate(int i, int b, CompLevel cur_level, Method* method);
   // Common transition function. Given a predicate determines if a method should transition to another level.
   CompLevel common(Predicate p, Method* method, CompLevel cur_level, bool disable_feedback = false);
   // Transition functions.
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1126,16 +1126,35 @@
 }
 #endif
 
-// Returns threshold scaled with CompileThresholdScaling
-intx Arguments::get_scaled_compile_threshold(intx threshold) {
-  return (intx)(threshold * CompileThresholdScaling);
+intx Arguments::scaled_compile_threshold(intx threshold, double scale) {
+  if (scale == 1.0 || scale < 0.0) {
+    return threshold;
+  } else {
+    return (intx)(threshold * scale);
+  }
 }
 
 // Returns freq_log scaled with CompileThresholdScaling
-intx Arguments::get_scaled_freq_log(intx freq_log) {
-  intx scaled_freq = get_scaled_compile_threshold((intx)1 << freq_log);
-  if (scaled_freq == 0) {
-    return 0;
+intx Arguments::scaled_freq_log(intx freq_log, double scale) {
+  // Check if scaling is necessary or negative value was specified.
+  if (scale == 1.0 || scale < 0.0) {
+    return freq_log;
+  }
+
+  // Check value to avoid calculating log2 of 0.
+  if (scale == 0.0) {
+    return 1;
+  }
+
+  intx scaled_freq = scaled_compile_threshold((intx)1 << freq_log, scale);
+  // Determine the maximum notification frequency value currently supported.
+  // The largest mask value that the interpreter/C1 can handle is
+  // of length InvocationCounter::number_of_count_bits. Mask values are always
+  // one bit shorter then the value of the notification frequency. Set
+  // max_freq_bits accordingly.
+  intx max_freq_bits = InvocationCounter::number_of_count_bits + 1;
+  if (scaled_freq > nth_bit(max_freq_bits)) {
+    return max_freq_bits;
   } else {
     return log2_intptr(scaled_freq);
   }
@@ -1180,31 +1199,36 @@
     Tier3InvokeNotifyFreqLog = 0;
     Tier4InvocationThreshold = 0;
   }
+
+  if (CompileThresholdScaling < 0) {
+    vm_exit_during_initialization("Negative value specified for CompileThresholdScaling", NULL);
+  }
+
   // Scale tiered compilation thresholds
   if (!FLAG_IS_DEFAULT(CompileThresholdScaling)) {
-    FLAG_SET_ERGO(intx, Tier0InvokeNotifyFreqLog, get_scaled_freq_log(Tier0InvokeNotifyFreqLog));
-    FLAG_SET_ERGO(intx, Tier0BackedgeNotifyFreqLog, get_scaled_freq_log(Tier0BackedgeNotifyFreqLog));
-
-    FLAG_SET_ERGO(intx, Tier3InvocationThreshold, get_scaled_compile_threshold(Tier3InvocationThreshold));
-    FLAG_SET_ERGO(intx, Tier3MinInvocationThreshold, get_scaled_compile_threshold(Tier3MinInvocationThreshold));
-    FLAG_SET_ERGO(intx, Tier3CompileThreshold, get_scaled_compile_threshold(Tier3CompileThreshold));
-    FLAG_SET_ERGO(intx, Tier3BackEdgeThreshold, get_scaled_compile_threshold(Tier3BackEdgeThreshold));
+    FLAG_SET_ERGO(intx, Tier0InvokeNotifyFreqLog, scaled_freq_log(Tier0InvokeNotifyFreqLog));
+    FLAG_SET_ERGO(intx, Tier0BackedgeNotifyFreqLog, scaled_freq_log(Tier0BackedgeNotifyFreqLog));
+
+    FLAG_SET_ERGO(intx, Tier3InvocationThreshold, scaled_compile_threshold(Tier3InvocationThreshold));
+    FLAG_SET_ERGO(intx, Tier3MinInvocationThreshold, scaled_compile_threshold(Tier3MinInvocationThreshold));
+    FLAG_SET_ERGO(intx, Tier3CompileThreshold, scaled_compile_threshold(Tier3CompileThreshold));
+    FLAG_SET_ERGO(intx, Tier3BackEdgeThreshold, scaled_compile_threshold(Tier3BackEdgeThreshold));
 
     // Tier2{Invocation,MinInvocation,Compile,Backedge}Threshold should be scaled here
     // once these thresholds become supported.
 
-    FLAG_SET_ERGO(intx, Tier2InvokeNotifyFreqLog, get_scaled_freq_log(Tier2InvokeNotifyFreqLog));
-    FLAG_SET_ERGO(intx, Tier2BackedgeNotifyFreqLog, get_scaled_freq_log(Tier2BackedgeNotifyFreqLog));
-
-    FLAG_SET_ERGO(intx, Tier3InvokeNotifyFreqLog, get_scaled_freq_log(Tier3InvokeNotifyFreqLog));
-    FLAG_SET_ERGO(intx, Tier3BackedgeNotifyFreqLog, get_scaled_freq_log(Tier3BackedgeNotifyFreqLog));
-
-    FLAG_SET_ERGO(intx, Tier23InlineeNotifyFreqLog, get_scaled_freq_log(Tier23InlineeNotifyFreqLog));
-
-    FLAG_SET_ERGO(intx, Tier4InvocationThreshold, get_scaled_compile_threshold(Tier4InvocationThreshold));
-    FLAG_SET_ERGO(intx, Tier4MinInvocationThreshold, get_scaled_compile_threshold(Tier4MinInvocationThreshold));
-    FLAG_SET_ERGO(intx, Tier4CompileThreshold, get_scaled_compile_threshold(Tier4CompileThreshold));
-    FLAG_SET_ERGO(intx, Tier4BackEdgeThreshold, get_scaled_compile_threshold(Tier4BackEdgeThreshold));
+    FLAG_SET_ERGO(intx, Tier2InvokeNotifyFreqLog, scaled_freq_log(Tier2InvokeNotifyFreqLog));
+    FLAG_SET_ERGO(intx, Tier2BackedgeNotifyFreqLog, scaled_freq_log(Tier2BackedgeNotifyFreqLog));
+
+    FLAG_SET_ERGO(intx, Tier3InvokeNotifyFreqLog, scaled_freq_log(Tier3InvokeNotifyFreqLog));
+    FLAG_SET_ERGO(intx, Tier3BackedgeNotifyFreqLog, scaled_freq_log(Tier3BackedgeNotifyFreqLog));
+
+    FLAG_SET_ERGO(intx, Tier23InlineeNotifyFreqLog, scaled_freq_log(Tier23InlineeNotifyFreqLog));
+
+    FLAG_SET_ERGO(intx, Tier4InvocationThreshold, scaled_compile_threshold(Tier4InvocationThreshold));
+    FLAG_SET_ERGO(intx, Tier4MinInvocationThreshold, scaled_compile_threshold(Tier4MinInvocationThreshold));
+    FLAG_SET_ERGO(intx, Tier4CompileThreshold, scaled_compile_threshold(Tier4CompileThreshold));
+    FLAG_SET_ERGO(intx, Tier4BackEdgeThreshold, scaled_compile_threshold(Tier4BackEdgeThreshold));
   }
 }
 
@@ -3456,7 +3480,7 @@
   }
 
   if ((TieredCompilation && CompileThresholdScaling == 0)
-      || (!TieredCompilation && get_scaled_compile_threshold(CompileThreshold) == 0)) {
+      || (!TieredCompilation && scaled_compile_threshold(CompileThreshold) == 0)) {
     set_mode_flags(_int);
   }
 
@@ -3896,7 +3920,7 @@
     }
     // Scale CompileThreshold
     if (!FLAG_IS_DEFAULT(CompileThresholdScaling)) {
-      FLAG_SET_ERGO(intx, CompileThreshold, get_scaled_compile_threshold(CompileThreshold));
+      FLAG_SET_ERGO(intx, CompileThreshold, scaled_compile_threshold(CompileThreshold));
     }
   }
 
--- a/hotspot/src/share/vm/runtime/arguments.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -328,9 +328,6 @@
   static bool _ClipInlining;
   static bool _CIDynamicCompilePriority;
 
-  // Scale compile thresholds
-  static intx get_scaled_compile_threshold(intx threshold);
-  static intx get_scaled_freq_log(intx freq_log);
   // Tiered
   static void set_tiered_flags();
   static int  get_min_number_of_compiler_threads();
@@ -452,6 +449,18 @@
   static char*  SharedArchivePath;
 
  public:
+  // Scale compile thresholds
+  // Returns threshold scaled with CompileThresholdScaling
+  static intx scaled_compile_threshold(intx threshold, double scale);
+  static intx scaled_compile_threshold(intx threshold) {
+    return scaled_compile_threshold(threshold, CompileThresholdScaling);
+  }
+  // Returns freq_log scaled with CompileThresholdScaling
+  static intx scaled_freq_log(intx freq_log, double scale);
+  static intx scaled_freq_log(intx freq_log) {
+    return scaled_freq_log(freq_log, CompileThresholdScaling);
+  }
+
   // Parses the arguments, first phase
   static jint parse(const JavaVMInitArgs* args);
   // Apply ergonomics
--- a/hotspot/src/share/vm/runtime/globals.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -2477,7 +2477,7 @@
           "Number of compiler threads to run")                              \
                                                                             \
   product(intx, CompilationPolicyChoice, 0,                                 \
-          "which compilation policy (0/1)")                                 \
+          "which compilation policy (0-3)")                                 \
                                                                             \
   develop(bool, UseStackBanging, true,                                      \
           "use stack banging for stack overflow checks (required for "      \
@@ -3528,7 +3528,16 @@
                                                                             \
   product(double, CompileThresholdScaling, 1.0,                             \
           "Factor to control when first compilation happens "               \
-          "(both with and without tiered compilation)")                     \
+          "(both with and without tiered compilation): "                    \
+          "values greater than 1.0 delay counter overflow, "                \
+          "values between 0 and 1.0 rush counter overflow, "                \
+          "value of 1.0 leave compilation thresholds unchanged "            \
+          "value of 0.0 is equivalent to -Xint. "                           \
+          ""                                                                \
+          "Flag can be set as per-method option. "                          \
+          "If a value is specified for a method, compilation thresholds "   \
+          "for that method are scaled by both the value of the global flag "\
+          "and the value of the per-method flag.")                          \
                                                                             \
   product(intx, Tier0InvokeNotifyFreqLog, 7,                                \
           "Interpreter (tier 0) invocation notification frequency")         \
--- a/hotspot/src/share/vm/runtime/os.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/runtime/os.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1401,15 +1401,17 @@
   return (sp > (stack_limit + reserved_area));
 }
 
-size_t os::page_size_for_region(size_t region_size, size_t min_pages) {
+size_t os::page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned) {
   assert(min_pages > 0, "sanity");
   if (UseLargePages) {
     const size_t max_page_size = region_size / min_pages;
 
     for (size_t i = 0; _page_sizes[i] != 0; ++i) {
       const size_t page_size = _page_sizes[i];
-      if (page_size <= max_page_size && is_size_aligned(region_size, page_size)) {
-        return page_size;
+      if (page_size <= max_page_size) {
+        if (!must_be_aligned || is_size_aligned(region_size, page_size)) {
+          return page_size;
+        }
       }
     }
   }
@@ -1417,6 +1419,14 @@
   return vm_page_size();
 }
 
+size_t os::page_size_for_region_aligned(size_t region_size, size_t min_pages) {
+  return page_size_for_region(region_size, min_pages, true);
+}
+
+size_t os::page_size_for_region_unaligned(size_t region_size, size_t min_pages) {
+  return page_size_for_region(region_size, min_pages, false);
+}
+
 #ifndef PRODUCT
 void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count)
 {
@@ -1665,17 +1675,17 @@
 
   static size_t large_page_size() {
     const size_t large_page_size_example = 4 * M;
-    return os::page_size_for_region(large_page_size_example, 1);
+    return os::page_size_for_region_aligned(large_page_size_example, 1);
   }
 
-  static void test_page_size_for_region() {
+  static void test_page_size_for_region_aligned() {
     if (UseLargePages) {
       const size_t small_page = small_page_size();
       const size_t large_page = large_page_size();
 
       if (large_page > small_page) {
         size_t num_small_pages_in_large = large_page / small_page;
-        size_t page = os::page_size_for_region(large_page, num_small_pages_in_large);
+        size_t page = os::page_size_for_region_aligned(large_page, num_small_pages_in_large);
 
         assert_eq(page, small_page);
       }
@@ -1688,21 +1698,53 @@
       const size_t large_page = large_page_size();
       if (large_page > small_page) {
         const size_t unaligned_region = large_page + 17;
-        size_t page = os::page_size_for_region(unaligned_region, 1);
+        size_t page = os::page_size_for_region_aligned(unaligned_region, 1);
         assert_eq(page, small_page);
 
         const size_t num_pages = 5;
         const size_t aligned_region = large_page * num_pages;
-        page = os::page_size_for_region(aligned_region, num_pages);
+        page = os::page_size_for_region_aligned(aligned_region, num_pages);
         assert_eq(page, large_page);
       }
     }
   }
 
+  static void test_page_size_for_region_unaligned() {
+    if (UseLargePages) {
+      // Given exact page size, should return that page size.
+      for (size_t i = 0; os::_page_sizes[i] != 0; i++) {
+        size_t expected = os::_page_sizes[i];
+        size_t actual = os::page_size_for_region_unaligned(expected, 1);
+        assert_eq(expected, actual);
+      }
+
+      // Given slightly larger size than a page size, return the page size.
+      for (size_t i = 0; os::_page_sizes[i] != 0; i++) {
+        size_t expected = os::_page_sizes[i];
+        size_t actual = os::page_size_for_region_unaligned(expected + 17, 1);
+        assert_eq(expected, actual);
+      }
+
+      // Given a slightly smaller size than a page size,
+      // return the next smaller page size.
+      if (os::_page_sizes[1] > os::_page_sizes[0]) {
+        size_t expected = os::_page_sizes[0];
+        size_t actual = os::page_size_for_region_unaligned(os::_page_sizes[1] - 17, 1);
+        assert_eq(actual, expected);
+      }
+
+      // Return small page size for values less than a small page.
+      size_t small_page = small_page_size();
+      size_t actual = os::page_size_for_region_unaligned(small_page - 17, 1);
+      assert_eq(small_page, actual);
+    }
+  }
+
  public:
   static void run_tests() {
-    test_page_size_for_region();
+    test_page_size_for_region_aligned();
     test_page_size_for_region_alignment();
+    test_page_size_for_region_unaligned();
   }
 };
 
--- a/hotspot/src/share/vm/runtime/os.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/runtime/os.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -148,6 +148,7 @@
   static void   pd_free_memory(char *addr, size_t bytes, size_t alignment_hint);
   static void   pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint);
 
+  static size_t page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned);
 
  public:
   static void init(void);                      // Called before command line parsing
@@ -267,8 +268,13 @@
 
   // Returns the page size to use for a region of memory.
   // region_size / min_pages will always be greater than or equal to the
-  // returned value.
-  static size_t page_size_for_region(size_t region_size, size_t min_pages);
+  // returned value. The returned value will divide region_size.
+  static size_t page_size_for_region_aligned(size_t region_size, size_t min_pages);
+
+  // Returns the page size to use for a region of memory.
+  // region_size / min_pages will always be greater than or equal to the
+  // returned value. The returned value might not divide region_size.
+  static size_t page_size_for_region_unaligned(size_t region_size, size_t min_pages);
 
   // Return the largest page size that can be used
   static size_t max_page_size() {
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -257,28 +257,28 @@
 // Call and loop predicates determine whether a transition to a higher
 // compilation level should be performed (pointers to predicate functions
 // are passed to common() transition function).
-bool SimpleThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level) {
+bool SimpleThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level, Method* method) {
   switch(cur_level) {
   case CompLevel_none:
   case CompLevel_limited_profile: {
-    return loop_predicate_helper<CompLevel_none>(i, b, 1.0);
+    return loop_predicate_helper<CompLevel_none>(i, b, 1.0, method);
   }
   case CompLevel_full_profile: {
-    return loop_predicate_helper<CompLevel_full_profile>(i, b, 1.0);
+    return loop_predicate_helper<CompLevel_full_profile>(i, b, 1.0, method);
   }
   default:
     return true;
   }
 }
 
-bool SimpleThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level) {
+bool SimpleThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level, Method* method) {
   switch(cur_level) {
   case CompLevel_none:
   case CompLevel_limited_profile: {
-    return call_predicate_helper<CompLevel_none>(i, b, 1.0);
+    return call_predicate_helper<CompLevel_none>(i, b, 1.0, method);
   }
   case CompLevel_full_profile: {
-    return call_predicate_helper<CompLevel_full_profile>(i, b, 1.0);
+    return call_predicate_helper<CompLevel_full_profile>(i, b, 1.0, method);
   }
   default:
     return true;
@@ -293,8 +293,8 @@
     int i = mdo->invocation_count();
     int b = mdo->backedge_count();
     double k = ProfileMaturityPercentage / 100.0;
-    return call_predicate_helper<CompLevel_full_profile>(i, b, k) ||
-           loop_predicate_helper<CompLevel_full_profile>(i, b, k);
+    return call_predicate_helper<CompLevel_full_profile>(i, b, k, method) ||
+           loop_predicate_helper<CompLevel_full_profile>(i, b, k, method);
   }
   return false;
 }
@@ -313,7 +313,7 @@
       // If we were at full profile level, would we switch to full opt?
       if (common(p, method, CompLevel_full_profile) == CompLevel_full_optimization) {
         next_level = CompLevel_full_optimization;
-      } else if ((this->*p)(i, b, cur_level)) {
+      } else if ((this->*p)(i, b, cur_level, method)) {
         next_level = CompLevel_full_profile;
       }
       break;
@@ -325,7 +325,7 @@
           if (mdo->would_profile()) {
             int mdo_i = mdo->invocation_count_delta();
             int mdo_b = mdo->backedge_count_delta();
-            if ((this->*p)(mdo_i, mdo_b, cur_level)) {
+            if ((this->*p)(mdo_i, mdo_b, cur_level, method)) {
               next_level = CompLevel_full_optimization;
             }
           } else {
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -43,9 +43,9 @@
   // Call and loop predicates determine whether a transition to a higher compilation
   // level should be performed (pointers to predicate functions are passed to common_TF().
   // Predicates also take compiler load into account.
-  typedef bool (SimpleThresholdPolicy::*Predicate)(int i, int b, CompLevel cur_level);
-  bool call_predicate(int i, int b, CompLevel cur_level);
-  bool loop_predicate(int i, int b, CompLevel cur_level);
+  typedef bool (SimpleThresholdPolicy::*Predicate)(int i, int b, CompLevel cur_level, Method* method);
+  bool call_predicate(int i, int b, CompLevel cur_level, Method* method);
+  bool loop_predicate(int i, int b, CompLevel cur_level, Method* method);
   // Common transition function. Given a predicate determines if a method should transition to another level.
   CompLevel common(Predicate p, Method* method, CompLevel cur_level);
   // Transition functions.
@@ -76,8 +76,8 @@
 
   // Predicate helpers are used by .*_predicate() methods as well as others.
   // They check the given counter values, multiplied by the scale against the thresholds.
-  template<CompLevel level> static inline bool call_predicate_helper(int i, int b, double scale);
-  template<CompLevel level> static inline bool loop_predicate_helper(int i, int b, double scale);
+  template<CompLevel level> static inline bool call_predicate_helper(int i, int b, double scale, Method* method);
+  template<CompLevel level> static inline bool loop_predicate_helper(int i, int b, double scale, Method* method);
 
   // Get a compilation level for a given method.
   static CompLevel comp_level(Method* method) {
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -25,8 +25,14 @@
 #ifndef SHARE_VM_RUNTIME_SIMPLETHRESHOLDPOLICY_INLINE_HPP
 #define SHARE_VM_RUNTIME_SIMPLETHRESHOLDPOLICY_INLINE_HPP
 
+#include "compiler/compilerOracle.hpp"
+
 template<CompLevel level>
-bool SimpleThresholdPolicy::call_predicate_helper(int i, int b, double scale) {
+bool SimpleThresholdPolicy::call_predicate_helper(int i, int b, double scale, Method* method) {
+  double threshold_scaling;
+  if (CompilerOracle::has_option_value(method, "CompileThresholdScaling", threshold_scaling)) {
+    scale *= threshold_scaling;
+  }
   switch(level) {
   case CompLevel_none:
   case CompLevel_limited_profile:
@@ -40,7 +46,11 @@
 }
 
 template<CompLevel level>
-bool SimpleThresholdPolicy::loop_predicate_helper(int i, int b, double scale) {
+bool SimpleThresholdPolicy::loop_predicate_helper(int i, int b, double scale, Method* method) {
+  double threshold_scaling;
+  if (CompilerOracle::has_option_value(method, "CompileThresholdScaling", threshold_scaling)) {
+    scale *= threshold_scaling;
+  }
   switch(level) {
   case CompLevel_none:
   case CompLevel_limited_profile:
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -276,18 +276,6 @@
   THREAD->set_current_pending_monitor_is_from_java(true);
 }
 
-// NOTE: must use heavy weight monitor to handle jni monitor enter
-bool ObjectSynchronizer::jni_try_enter(Handle obj, Thread* THREAD) {
-  if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
-    assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
-  }
-
-  ObjectMonitor* monitor = ObjectSynchronizer::inflate_helper(obj());
-  return monitor->try_enter(THREAD);
-}
-
-
 // NOTE: must use heavy weight monitor to handle jni monitor exit
 void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) {
   TEVENT(jni_exit);
--- a/hotspot/src/share/vm/runtime/synchronizer.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/runtime/synchronizer.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -65,7 +65,6 @@
   // Used only to handle jni locks or other unmatched monitor enter/exit
   // Internally they will use heavy weight monitor.
   static void jni_enter(Handle obj, TRAPS);
-  static bool jni_try_enter(Handle obj, Thread* THREAD); // Implements Unsafe.tryMonitorEnter
   static void jni_exit(oop obj, Thread* THREAD);
 
   // Handle all interpreter, compiler and jni cases
--- a/hotspot/src/share/vm/runtime/virtualspace.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/runtime/virtualspace.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -38,7 +38,8 @@
 }
 
 ReservedSpace::ReservedSpace(size_t size) {
-  size_t page_size = os::page_size_for_region(size, 1);
+  // Want to use large pages where possible and pad with small pages.
+  size_t page_size = os::page_size_for_region_unaligned(size, 1);
   bool large_pages = page_size != (size_t)os::vm_page_size();
   // Don't force the alignment to be large page aligned,
   // since that will waste memory.
@@ -617,7 +618,7 @@
 
 
 bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) {
-  const size_t max_commit_granularity = os::page_size_for_region(rs.size(), 1);
+  const size_t max_commit_granularity = os::page_size_for_region_unaligned(rs.size(), 1);
   return initialize_with_granularity(rs, committed_size, max_commit_granularity);
 }
 
@@ -1239,7 +1240,7 @@
     case Disable:
       return vs.initialize_with_granularity(rs, 0, os::vm_page_size());
     case Commit:
-      return vs.initialize_with_granularity(rs, 0, os::page_size_for_region(rs.size(), 1));
+      return vs.initialize_with_granularity(rs, 0, os::page_size_for_region_unaligned(rs.size(), 1));
     }
   }
 
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Wed Jul 05 20:17:28 2017 +0200
@@ -351,11 +351,18 @@
   nonstatic_field(MethodData,           _arg_stack,                                    intx)                                  \
   nonstatic_field(MethodData,           _arg_returned,                                 intx)                                  \
   nonstatic_field(MethodData,           _tenure_traps,                                 uint)                                  \
+  nonstatic_field(MethodData,           _invoke_mask,                                  int)                                   \
+  nonstatic_field(MethodData,           _backedge_mask,                                int)                                   \
   nonstatic_field(DataLayout,           _header._struct._tag,                          u1)                                    \
   nonstatic_field(DataLayout,           _header._struct._flags,                        u1)                                    \
   nonstatic_field(DataLayout,           _header._struct._bci,                          u2)                                    \
   nonstatic_field(DataLayout,           _cells[0],                                     intptr_t)                              \
   nonstatic_field(MethodCounters,       _nmethod_age,                                  int)                                   \
+  nonstatic_field(MethodCounters,       _interpreter_invocation_limit,                 int)                                   \
+  nonstatic_field(MethodCounters,       _interpreter_backward_branch_limit,            int)                                   \
+  nonstatic_field(MethodCounters,       _interpreter_profile_limit,                    int)                                   \
+  nonstatic_field(MethodCounters,       _invoke_mask,                                  int)                                   \
+  nonstatic_field(MethodCounters,       _backedge_mask,                                int)                                   \
   nonstatic_field(MethodCounters,       _interpreter_invocation_count,                 int)                                   \
   nonstatic_field(MethodCounters,       _interpreter_throwout_count,                   u2)                                    \
   nonstatic_field(MethodCounters,       _number_of_breakpoints,                        u2)                                    \
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Wed Jul 05 20:17:28 2017 +0200
@@ -1142,17 +1142,18 @@
   return ((x != NoLongBits) && (mask_long_bits(x, x - 1) == NoLongBits));
 }
 
-//* largest i such that 2^i <= x
-//  A negative value of 'x' will return '31'
+// Returns largest i such that 2^i <= x.
+// If x < 0, the function returns 31 on a 32-bit machine and 63 on a 64-bit machine.
+// If x == 0, the function returns -1.
 inline int log2_intptr(intptr_t x) {
   int i = -1;
-  uintptr_t p =  1;
+  uintptr_t p = 1;
   while (p != 0 && p <= (uintptr_t)x) {
     // p = 2^(i+1) && p <= x (i.e., 2^(i+1) <= x)
     i++; p *= 2;
   }
   // p = 2^(i+1) && x < p (i.e., 2^i <= x < 2^(i+1))
-  // (if p = 0 then overflow occurred and i = 31)
+  // If p = 0, overflow has occurred and i = 31 or i = 63 (depending on the machine word size).
   return i;
 }
 
--- a/hotspot/test/compiler/arguments/CheckCompileThresholdScaling.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/test/compiler/arguments/CheckCompileThresholdScaling.java	Wed Jul 05 20:17:28 2017 +0200
@@ -54,7 +54,7 @@
     //
     // Tier0InvokeNotifyFreqLog, Tier0BackedgeNotifyFreqLog,
     // Tier3InvocationThreshold, Tier3MinInvocationThreshold,
-    // Tier3CompileThreshold, and Tier3BackEdgeThreshold,
+    // Tier3CompileThreshold, Tier3BackEdgeThreshold,
     // Tier2InvokeNotifyFreqLog, Tier2BackedgeNotifyFreqLog,
     // Tier3InvokeNotifyFreqLog, Tier3BackedgeNotifyFreqLog,
     // Tier23InlineeNotifyFreqLog, Tier4InvocationThreshold,
--- a/hotspot/test/compiler/codecache/jmx/PoolsIndependenceTest.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/test/compiler/codecache/jmx/PoolsIndependenceTest.java	Wed Jul 05 20:17:28 2017 +0200
@@ -98,11 +98,13 @@
             return false;
         });
         for (BlobType bt : BlobType.getAvailable()) {
-            int expectedNotificationsAmount = bt.equals(btype) ? 1 : 0;
-            Asserts.assertEQ(counters.get(bt.getMemoryPool().getName()).get(),
-                    expectedNotificationsAmount, String.format("Unexpected "
-                            + "amount of notifications for pool: %s",
-                            bt.getMemoryPool().getName()));
+            if (CodeCacheUtils.isCodeHeapPredictable(bt)) {
+                int expectedNotificationsAmount = bt.equals(btype) ? 1 : 0;
+                Asserts.assertEQ(counters.get(bt.getMemoryPool().getName()).get(),
+                        expectedNotificationsAmount, String.format("Unexpected "
+                                + "amount of notifications for pool: %s",
+                                bt.getMemoryPool().getName()));
+            }
         }
         try {
             ((NotificationEmitter) ManagementFactory.getMemoryMXBean()).
--- a/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java	Wed Jul 05 20:17:28 2017 +0200
@@ -52,7 +52,9 @@
 
     public static void main(String[] args) {
         for (BlobType bt : BlobType.getAvailable()) {
-            new ThresholdNotificationsTest(bt).runTest();
+            if (CodeCacheUtils.isCodeHeapPredictable(bt)) {
+                new ThresholdNotificationsTest(bt).runTest();
+            }
         }
     }
 
--- a/hotspot/test/compiler/loopopts/7052494/Test7052494.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/test/compiler/loopopts/7052494/Test7052494.java	Wed Jul 05 20:17:28 2017 +0200
@@ -25,7 +25,6 @@
 /**
  * @test
  * @bug 7052494
- * @ignore 7154567
  * @summary Eclipse test fails on JDK 7 b142
  *
  * @run main/othervm -Xbatch Test7052494
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/stringopts/TestOptimizeStringConcat.java	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2015 SAP AG.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8068909
+ * @key regression
+ * @summary test that string optimizations produce code, that doesn't lead to a crash.
+ * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestOptimizeStringConcat
+ * @author axel.siebenborn@sap.com
+ */
+public class TestOptimizeStringConcat {
+
+    static boolean checkArgumentSyntax(String value, String allowedchars, String notallowedchars, String logmsg) {
+        String rc = null;
+
+        int maxchar = 99999;
+        int minchar = 1;
+        if ((allowedchars != null && notallowedchars != null) || minchar > maxchar) {
+            rc = "internal error";
+        } else {
+            if (value == null) {
+                rc = "the value null is not allowed, it is missing";
+            } else if (value != null && minchar > 0 && value.trim().equals("")) {
+                rc = "the value must not be empty";
+            } else if (value != null) {
+                if (value.length() < minchar || value.length() > maxchar) {
+                    if (rc == null) {
+                        rc = "the value length must be between +minchar+ and +maxchar";
+                    }
+                }
+                char[] _value = value.toCharArray();
+                boolean dotfound = false;
+                int i = 1;
+                if (_value[i] == '.' && !dotfound) {
+                    dotfound = true;
+                } else if (allowedchars != null && allowedchars.indexOf(_value[i]) == -1) {
+                    if (rc == null) {
+                        rc = "the value contains an illegal character: '" + _value[i] + "', only following characters are allowed: '+allowedchars+'";
+                    } else {
+                        rc += " / the value contains an illegal character: '" + _value[i] + "', only following characters are allowed: '+allowedchars+'";
+                    }
+                } else if (notallowedchars != null && notallowedchars.indexOf(_value[i]) != -1) {
+                    if (rc == null) {
+                        rc = "the value contains an illegal character: '" + _value[i] + "', following characters are not allowed '+notallowedchars+'";
+                    } else {
+                        rc += " / the value contains an illegal character: '" + _value[i] + "', following characters are not allowed '+notallowedchars+'";
+                    }
+                }
+            }
+        }
+
+        if (rc != null) {
+            System.out.println(logmsg + " ==> " + rc);
+            return false;
+        }
+        return true;
+    }
+
+    public static void main(String[] args) {
+        boolean failed = false;
+        for (int i = 0; i < 10000; i++) {
+            failed |= !checkArgumentSyntax("theName", null, "\"<&", "Error consistencyCheck: name in component definition");
+            failed |= !checkArgumentSyntax(null, null, "\"<&", "Error consistencyCheck: name in component definition");
+            failed |= !checkArgumentSyntax("42", "0123456789.", null, "Error consistencyCheck: counter in component definition");
+        }
+        System.out.println(failed);
+    }
+}
--- a/hotspot/test/compiler/testlibrary/rtm/BusyLock.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/test/compiler/testlibrary/rtm/BusyLock.java	Wed Jul 05 20:17:28 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,9 +24,6 @@
 
 package rtm;
 
-import com.oracle.java.testlibrary.Utils;
-import sun.misc.Unsafe;
-
 import java.util.concurrent.BrokenBarrierException;
 import java.util.concurrent.CyclicBarrier;
 
@@ -42,7 +39,6 @@
     // Following field have to be static in order to avoid escape analysis.
     @SuppressWarnings("UnsuedDeclaration")
     private static int field = 0;
-    private static final Unsafe UNSAFE = Utils.getUnsafe();
     protected final Object monitor;
     protected final int timeout;
 
@@ -59,18 +55,9 @@
     @Override
     public void run() {
         try {
-            // wait until forceAbort leave monitor
-            barrier.await();
-            if (UNSAFE.tryMonitorEnter(monitor)) {
-                try {
-                    barrier.await();
-                    Thread.sleep(timeout);
-                } finally {
-                    UNSAFE.monitorExit(monitor);
-                }
-            } else {
-                throw new RuntimeException("Monitor should be entered by " +
-                                           "::run() first.");
+            synchronized (monitor) {
+                barrier.await();
+                Thread.sleep(timeout);
             }
         } catch (InterruptedException | BrokenBarrierException e) {
             throw new RuntimeException("Synchronization error happened.", e);
@@ -79,7 +66,6 @@
 
     public void syncAndTest() {
         try {
-            barrier.await();
             // wait until monitor is locked by a ::run method
             barrier.await();
         } catch (InterruptedException | BrokenBarrierException e) {
--- a/hotspot/test/gc/TestNUMAPageSize.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/test/gc/TestNUMAPageSize.java	Wed Jul 05 20:17:28 2017 +0200
@@ -25,6 +25,7 @@
  * @test TestNUMAPageSize
  * @summary Make sure that start up with NUMA support does not cause problems.
  * @bug 8061467
+ * @requires (vm.opt.AggressiveOpts == null) | (vm.opt.AggressiveOpts == false)
  * @key gc
  * @key regression
  * @run main/othervm -Xmx8M -XX:+UseNUMA TestNUMAPageSize
--- a/hotspot/test/gc/TestSmallHeap.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/test/gc/TestSmallHeap.java	Wed Jul 05 20:17:28 2017 +0200
@@ -25,6 +25,7 @@
  * @test TestSmallHeap
  * @bug 8067438
  * @requires vm.gc=="null"
+ * @requires (vm.opt.AggressiveOpts=="null") | (vm.opt.AggressiveOpts=="false")
  * @summary Verify that starting the VM with a small heap works
  * @library /testlibrary /../../test/lib
  * @build TestSmallHeap
@@ -33,8 +34,9 @@
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xmx2m -XX:+UseSerialGC TestSmallHeap
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xmx2m -XX:+UseG1GC TestSmallHeap
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xmx2m -XX:+UseConcMarkSweepGC TestSmallHeap
- *
- * Note: It would be nice to verify the minimal supported heap size (2m) here,
+ */
+
+/* Note: It would be nice to verify the minimal supported heap size (2m) here,
  * but we align the heap size based on the card table size. And the card table
  * size is aligned based on the minimal pages size provided by the os. This
  * means that on most platforms, where the minimal page size is 4k, we get a
--- a/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java	Wed Jul 05 20:17:28 2017 +0200
@@ -116,7 +116,14 @@
 
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0]));
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
-    output.shouldHaveExitValue(0);
+    try {
+        output.shouldHaveExitValue(0);
+    } catch (RuntimeException e) {
+        // It's ok if there is no client vm in the jdk.
+        if (output.firstMatch("Unrecognized option: -client") == null) {
+            throw e;
+        }
+    }
 
     return output;
   }
--- a/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java	Wed Jul 05 20:17:28 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,7 +44,7 @@
 
     public static void main(String[] args) throws Exception {
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-            "-Xmx64m", "-XX:-TransmitErrorReport", Crasher.class.getName());
+            "-Xmx64m", "-XX:-TransmitErrorReport", "-XX:-CreateMinidumpOnCrash", Crasher.class.getName());
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldNotMatch("error occurred during error reporting \\(printing problematic frame\\)");
     }
--- a/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java	Wed Jul 05 20:17:28 2017 +0200
@@ -25,6 +25,7 @@
  * @test CompilerQueueTest
  * @bug 8054889
  * @library ..
+ * @ignore 8069160
  * @build DcmdUtil CompilerQueueTest
  * @run main CompilerQueueTest
  * @run main/othervm -XX:-TieredCompilation CompilerQueueTest
--- a/jaxp/.hgtags	Thu Jan 29 15:36:21 2015 -0800
+++ b/jaxp/.hgtags	Wed Jul 05 20:17:28 2017 +0200
@@ -290,3 +290,4 @@
 0dab3e848229127c7aca4c58b98e2d90ba70372f jdk9-b45
 74eaf7ad986576c792df4dbff05eed63e5727695 jdk9-b46
 e391de88e69b59d7c618387e3cf91032f6991ce9 jdk9-b47
+833051855168a973780fafeb6fc59e7370bcf400 jdk9-b48
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java	Wed Jul 05 20:17:28 2017 +0200
@@ -270,8 +270,8 @@
         if (Double.isNaN(start))
             return(EMPTYSTRING);
 
-            final int strlen = value.length();
-            int istart = (int)Math.round(start) - 1;
+        final int strlen = value.length();
+        int istart = (int)Math.round(start) - 1;
 
         if (istart > strlen)
             return(EMPTYSTRING);
@@ -292,10 +292,11 @@
     public static String substringF(String value, double start, double length) {
         if (Double.isInfinite(start) ||
             Double.isNaN(start) ||
-            Double.isNaN(length))
+            Double.isNaN(length) ||
+            length < 0)
             return(EMPTYSTRING);
 
-            int istart = (int)Math.round(start) - 1;
+        int istart = (int)Math.round(start) - 1;
         final int isum;
         if (Double.isInfinite(length))
             isum = Integer.MAX_VALUE;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathExpressionImpl.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathExpressionImpl.java	Wed Jul 05 20:17:28 2017 +0200
@@ -1,15 +1,15 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,36 +17,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// $Id: XPathExpressionImpl.java,v 1.3 2005/09/27 09:40:43 sunithareddy Exp $
 
 package com.sun.org.apache.xpath.internal.jaxp;
 
-import com.sun.org.apache.xpath.internal.*;
+import com.sun.org.apache.xalan.internal.utils.FeatureManager;
+import com.sun.org.apache.xpath.internal.objects.XObject;
+import javax.xml.namespace.QName;
 import javax.xml.transform.TransformerException;
-
-import com.sun.org.apache.xpath.internal.objects.XObject;
-import com.sun.org.apache.xml.internal.dtm.DTM;
-import com.sun.org.apache.xml.internal.utils.PrefixResolver;
-import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
-import com.sun.org.apache.xalan.internal.res.XSLMessages;
-import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
-import com.sun.org.apache.xalan.internal.utils.FeatureManager;
-
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.namespace.QName;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathEvaluationResult;
+import javax.xml.xpath.XPathExpression;
 import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathFunctionResolver;
 import javax.xml.xpath.XPathVariableResolver;
-import javax.xml.xpath.XPathConstants;
-
+import org.w3c.dom.Document;
 import org.w3c.dom.Node;
-import org.w3c.dom.Document;
-import org.w3c.dom.DOMImplementation;
-import org.w3c.dom.traversal.NodeIterator;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.DocumentBuilder;
-
 import org.xml.sax.InputSource;
 
 /**
@@ -54,22 +39,10 @@
  *
  * @author  Ramesh Mandava
  */
-public class XPathExpressionImpl  implements javax.xml.xpath.XPathExpression{
+public class XPathExpressionImpl extends XPathImplUtil implements XPathExpression {
 
-    private XPathFunctionResolver functionResolver;
-    private XPathVariableResolver variableResolver;
-    private JAXPPrefixResolver prefixResolver;
     private com.sun.org.apache.xpath.internal.XPath xpath;
 
-    // By default Extension Functions are allowed in XPath Expressions. If
-    // Secure Processing Feature is set on XPathFactory then the invocation of
-    // extensions function need to throw XPathFunctionException
-    private boolean featureSecureProcessing = false;
-
-    private boolean useServicesMechanism = true;
-
-    private final FeatureManager featureManager;
-
     /** Protected constructor to prevent direct instantiation; use compile()
      * from the context.
      */
@@ -81,7 +54,7 @@
     protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath,
             JAXPPrefixResolver prefixResolver,
             XPathFunctionResolver functionResolver,
-            XPathVariableResolver variableResolver ) {
+            XPathVariableResolver variableResolver) {
         this(xpath, prefixResolver, functionResolver, variableResolver,
              false, true, new FeatureManager());
     };
@@ -89,291 +62,108 @@
     protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath,
             JAXPPrefixResolver prefixResolver,XPathFunctionResolver functionResolver,
             XPathVariableResolver variableResolver, boolean featureSecureProcessing,
-            boolean useServicesMechanism, FeatureManager featureManager ) {
+            boolean useServiceMechanism, FeatureManager featureManager) {
         this.xpath = xpath;
         this.prefixResolver = prefixResolver;
         this.functionResolver = functionResolver;
         this.variableResolver = variableResolver;
         this.featureSecureProcessing = featureSecureProcessing;
-        this.useServicesMechanism = useServicesMechanism;
+        this.useServiceMechanism = useServiceMechanism;
         this.featureManager = featureManager;
     };
 
-    public void setXPath (com.sun.org.apache.xpath.internal.XPath xpath ) {
+    public void setXPath (com.sun.org.apache.xpath.internal.XPath xpath) {
         this.xpath = xpath;
     }
 
     public Object eval(Object item, QName returnType)
             throws javax.xml.transform.TransformerException {
-        XObject resultObject = eval ( item );
-        return getResultAsType( resultObject, returnType );
+        XObject resultObject = eval(item, xpath);
+        return getResultAsType(resultObject, returnType);
     }
 
-    private XObject eval ( Object contextItem )
-            throws javax.xml.transform.TransformerException {
-        com.sun.org.apache.xpath.internal.XPathContext xpathSupport = null;
-        if ( functionResolver != null ) {
-            JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
-                    functionResolver, featureSecureProcessing, featureManager );
-            xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext( jep );
-        } else {
-            xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext();
-        }
-
-        xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
-        XObject xobj = null;
-
-        Node contextNode = (Node)contextItem;
-        // We always need to have a ContextNode with Xalan XPath implementation
-        // To allow simple expression evaluation like 1+1 we are setting
-        // dummy Document as Context Node
-
-        if ( contextNode == null )
-            xobj = xpath.execute(xpathSupport, DTM.NULL, prefixResolver);
-        else
-            xobj = xpath.execute(xpathSupport, contextNode, prefixResolver);
-
-        return xobj;
-    }
-
-
-    /**
-     * <p>Evaluate the compiled XPath expression in the specified context and
-     *  return the result as the specified type.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
-     * for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If <code>returnType</code> is not one of the types defined
-     * in {@link XPathConstants},
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
-     *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
-     * If <code>returnType</code> is <code>null</code>, then a
-     * <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param item The starting context (node or node list, for example).
-     * @param returnType The desired return type.
-     *
-     * @return The <code>Object</code> that is the result of evaluating the
-     * expression and converting the result to
-     *   <code>returnType</code>.
-     *
-     * @throws XPathExpressionException If the expression cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one
-     * of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If  <code>returnType</code> is
-     * <code>null</code>.
-     */
+    @Override
     public Object evaluate(Object item, QName returnType)
         throws XPathExpressionException {
-        //Validating parameters to enforce constraints defined by JAXP spec
-        if ( returnType == null ) {
-           //Throwing NullPointerException as defined in spec
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"returnType"} );
-            throw new NullPointerException( fmsg );
-        }
-        // Checking if requested returnType is supported. returnType need to be
-        // defined in XPathConstants
-        if ( !isSupported ( returnType ) ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
-                    new Object[] { returnType.toString() } );
-            throw new IllegalArgumentException ( fmsg );
-        }
+        isSupported(returnType);
         try {
-            return eval( item, returnType);
-        } catch ( java.lang.NullPointerException npe ) {
+            return eval(item, returnType);
+        } catch (java.lang.NullPointerException npe) {
             // If VariableResolver returns null Or if we get
             // NullPointerException at this stage for some other reason
             // then we have to reurn XPathException
-            throw new XPathExpressionException ( npe );
-        } catch ( javax.xml.transform.TransformerException te ) {
+            throw new XPathExpressionException (npe);
+        } catch (javax.xml.transform.TransformerException te) {
             Throwable nestedException = te.getException();
-            if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
+            if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
                 throw (javax.xml.xpath.XPathFunctionException)nestedException;
             } else {
                 // For any other exceptions we need to throw
-                // XPathExpressionException ( as per spec )
-                throw new XPathExpressionException( te);
+                // XPathExpressionException (as per spec)
+                throw new XPathExpressionException(te);
             }
         }
-
-    }
-
-    /**
-     * <p>Evaluate the compiled XPath expression in the specified context and
-     * return the result as a <code>String</code>.</p>
-     *
-     * <p>This method calls {@link #evaluate(Object item, QName returnType)}
-     * with a <code>returnType</code> of
-     * {@link XPathConstants#STRING}.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
-     *  for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
-     *
-     * @param item The starting context (node or node list, for example).
-     *
-     * @return The <code>String</code> that is the result of evaluating the
-     * expression and converting the result to a
-     *   <code>String</code>.
-     *
-     * @throws XPathExpressionException If the expression cannot be evaluated.
-     */
-    public String evaluate(Object item)
-        throws XPathExpressionException {
-        return (String)this.evaluate( item, XPathConstants.STRING );
-    }
-
-
-
-    static DocumentBuilderFactory dbf = null;
-    static DocumentBuilder db = null;
-    static Document d = null;
-
-    /**
-     * <p>Evaluate the compiled XPath expression in the context of the
-     * specified <code>InputSource</code> and return the result as the
-     *  specified type.</p>
-     *
-     * <p>This method builds a data model for the {@link InputSource} and calls
-     * {@link #evaluate(Object item, QName returnType)} on the resulting
-     * document object.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
-     *  for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If <code>returnType</code> is not one of the types defined in
-     * {@link XPathConstants},
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
-     *
-     *<p>If <code>source</code> or <code>returnType</code> is <code>null</code>,
-     * then a <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param source The <code>InputSource</code> of the document to evaluate
-     * over.
-     * @param returnType The desired return type.
-     *
-     * @return The <code>Object</code> that is the result of evaluating the
-     * expression and converting the result to
-     *   <code>returnType</code>.
-     *
-     * @throws XPathExpressionException If the expression cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one
-     * of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If  <code>source</code> or
-     * <code>returnType</code> is <code>null</code>.
-     */
-    public Object evaluate(InputSource source, QName returnType)
-        throws XPathExpressionException {
-        if ( ( source == null ) || ( returnType == null ) ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_SOURCE_RETURN_TYPE_CANNOT_BE_NULL,
-                    null );
-            throw new NullPointerException ( fmsg );
-        }
-        // Checking if requested returnType is supported. returnType need to be
-        // defined in XPathConstants
-        if ( !isSupported ( returnType ) ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
-                    new Object[] { returnType.toString() } );
-            throw new IllegalArgumentException ( fmsg );
-        }
-        try {
-            if ( dbf == null ) {
-                dbf = FactoryImpl.getDOMFactory(useServicesMechanism);
-                dbf.setNamespaceAware( true );
-                dbf.setValidating( false );
-            }
-            db = dbf.newDocumentBuilder();
-            Document document = db.parse( source );
-            return eval(  document, returnType );
-        } catch ( Exception e ) {
-            throw new XPathExpressionException ( e );
-        }
     }
 
-    /**
-     * <p>Evaluate the compiled XPath expression in the context of the specified <code>InputSource</code> and return the result as a
-     * <code>String</code>.</p>
-     *
-     * <p>This method calls {@link #evaluate(InputSource source, QName returnType)} with a <code>returnType</code> of
-     * {@link XPathConstants#STRING}.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
-     * for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If <code>source</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param source The <code>InputSource</code> of the document to evaluate over.
-     *
-     * @return The <code>String</code> that is the result of evaluating the expression and converting the result to a
-     *   <code>String</code>.
-     *
-     * @throws XPathExpressionException If the expression cannot be evaluated.
-     * @throws NullPointerException If  <code>source</code> is <code>null</code>.
-     */
+
+    @Override
+    public String evaluate(Object item)
+        throws XPathExpressionException {
+        return (String)this.evaluate(item, XPathConstants.STRING);
+    }
+
+    @Override
+    public Object evaluate(InputSource source, QName returnType)
+        throws XPathExpressionException {
+        isSupported (returnType);
+        try {
+            Document document = getDocument(source);
+            return eval(document, returnType);
+        } catch (TransformerException e) {
+            throw new XPathExpressionException(e);
+        }
+    }
+
+    @Override
     public String evaluate(InputSource source)
         throws XPathExpressionException {
-        return (String)this.evaluate( source, XPathConstants.STRING );
+        return (String)this.evaluate(source, XPathConstants.STRING);
     }
 
-    private boolean isSupported( QName returnType ) {
-        // XPathConstants.STRING
-        if ( ( returnType.equals( XPathConstants.STRING ) ) ||
-             ( returnType.equals( XPathConstants.NUMBER ) ) ||
-             ( returnType.equals( XPathConstants.BOOLEAN ) ) ||
-             ( returnType.equals( XPathConstants.NODE ) ) ||
-             ( returnType.equals( XPathConstants.NODESET ) )  ) {
+    @Override
+    public <T>T evaluateExpression(Object item, Class<T> type)
+        throws XPathExpressionException {
+        isSupportedClassType(type);
 
-            return true;
+        try {
+            XObject resultObject = eval(item, xpath);
+            if (type.isAssignableFrom(XPathEvaluationResult.class)) {
+                return getXPathResult(resultObject, type);
+            } else {
+                return XPathResultImpl.getValue(resultObject, type);
+            }
+
+        } catch (javax.xml.transform.TransformerException te) {
+            throw new XPathExpressionException(te);
         }
-        return false;
-     }
-
-     private Object getResultAsType( XObject resultObject, QName returnType )
-        throws javax.xml.transform.TransformerException {
-        // XPathConstants.STRING
-        if ( returnType.equals( XPathConstants.STRING ) ) {
-            return resultObject.str();
-        }
-        // XPathConstants.NUMBER
-        if ( returnType.equals( XPathConstants.NUMBER ) ) {
-            return new Double ( resultObject.num());
-        }
-        // XPathConstants.BOOLEAN
-        if ( returnType.equals( XPathConstants.BOOLEAN ) ) {
-            return new Boolean( resultObject.bool());
-        }
-        // XPathConstants.NODESET ---ORdered, UNOrdered???
-        if ( returnType.equals( XPathConstants.NODESET ) ) {
-            return resultObject.nodelist();
-        }
-        // XPathConstants.NODE
-        if ( returnType.equals( XPathConstants.NODE ) ) {
-            NodeIterator ni = resultObject.nodeset();
-            //Return the first node, or null
-            return ni.nextNode();
-        }
-        // If isSupported check is already done then the execution path
-        // shouldn't come here. Being defensive
-        String fmsg = XSLMessages.createXPATHMessage(
-                XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
-                new Object[] { returnType.toString()});
-        throw new IllegalArgumentException ( fmsg );
     }
 
+    @Override
+    public XPathEvaluationResult<?> evaluateExpression(Object item)
+        throws XPathExpressionException {
+        return evaluateExpression(item, XPathEvaluationResult.class);
+    }
+
+    @Override
+    public <T>T  evaluateExpression(InputSource source, Class<T> type)
+            throws XPathExpressionException {
+        Document document = getDocument(source);
+        return evaluateExpression(document, type);
+    }
+
+    @Override
+    public XPathEvaluationResult<?> evaluateExpression(InputSource source)
+        throws XPathExpressionException {
+        return evaluateExpression(source, XPathEvaluationResult.class);
+    }
  }
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java	Wed Jul 05 20:17:28 2017 +0200
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Copyright 1999-2004 The Apache Software Foundation.
@@ -28,55 +27,37 @@
 import javax.xml.xpath.XPathFunctionResolver;
 import javax.xml.xpath.XPathVariableResolver;
 import javax.xml.xpath.XPathExpression;
-
-import com.sun.org.apache.xml.internal.dtm.DTM;
 import com.sun.org.apache.xpath.internal.*;
 import com.sun.org.apache.xpath.internal.objects.XObject;
-import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
-import com.sun.org.apache.xalan.internal.res.XSLMessages;
-import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
 import com.sun.org.apache.xalan.internal.utils.FeatureManager;
-
-import org.w3c.dom.Node;
 import org.w3c.dom.Document;
-import org.w3c.dom.traversal.NodeIterator;
-
 import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import javax.xml.parsers.*;
-
-import java.io.IOException;
+import javax.xml.transform.TransformerException;
+import javax.xml.xpath.XPathEvaluationResult;
 
 /**
  * The XPathImpl class provides implementation for the methods defined  in
- * javax.xml.xpath.XPath interface. This provide simple access to the results
+ * javax.xml.xpath.XPath interface. This provides simple access to the results
  * of an XPath expression.
  *
+ * @author  Ramesh Mandava
  *
- * @author  Ramesh Mandava
+ * Updated 12/04/2014:
+ * New methods: evaluateExpression
+ * Refactored to share code with XPathExpressionImpl.
  */
-public class XPathImpl implements javax.xml.xpath.XPath {
+public class XPathImpl extends XPathImplUtil implements javax.xml.xpath.XPath {
 
     // Private variables
-    private XPathVariableResolver variableResolver;
-    private XPathFunctionResolver functionResolver;
     private XPathVariableResolver origVariableResolver;
     private XPathFunctionResolver origFunctionResolver;
     private NamespaceContext namespaceContext=null;
-    private JAXPPrefixResolver prefixResolver;
-    // By default Extension Functions are allowed in XPath Expressions. If
-    // Secure Processing Feature is set on XPathFactory then the invocation of
-    // extensions function need to throw XPathFunctionException
-    private boolean featureSecureProcessing = false;
-    private boolean useServiceMechanism = true;
-    private final FeatureManager featureManager;
 
-    XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr ) {
+    XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr) {
         this(vr, fr, false, true, new FeatureManager());
     }
 
-    XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr,
+    XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr,
             boolean featureSecureProcessing, boolean useServiceMechanism,
             FeatureManager featureManager) {
         this.origVariableResolver = this.variableResolver = vr;
@@ -86,451 +67,173 @@
         this.featureManager = featureManager;
     }
 
-    /**
-     * <p>Establishes a variable resolver.</p>
-     *
-     * @param resolver Variable Resolver
-     */
+
+    //-Override-
     public void setXPathVariableResolver(XPathVariableResolver resolver) {
-        if ( resolver == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"XPathVariableResolver"} );
-            throw new NullPointerException( fmsg );
-        }
+        requireNonNull(resolver, "XPathVariableResolver");
         this.variableResolver = resolver;
     }
 
-    /**
-     * <p>Returns the current variable resolver.</p>
-     *
-     * @return Current variable resolver
-     */
+    //-Override-
     public XPathVariableResolver getXPathVariableResolver() {
         return variableResolver;
     }
 
-    /**
-     * <p>Establishes a function resolver.</p>
-     *
-     * @param resolver XPath function resolver
-     */
+    //-Override-
     public void setXPathFunctionResolver(XPathFunctionResolver resolver) {
-        if ( resolver == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"XPathFunctionResolver"} );
-            throw new NullPointerException( fmsg );
-        }
+        requireNonNull(resolver, "XPathFunctionResolver");
         this.functionResolver = resolver;
     }
 
-    /**
-     * <p>Returns the current function resolver.</p>
-     *
-     * @return Current function resolver
-     */
+    //-Override-
     public XPathFunctionResolver getXPathFunctionResolver() {
         return functionResolver;
     }
 
-    /**
-     * <p>Establishes a namespace context.</p>
-     *
-     * @param nsContext Namespace context to use
-     */
+    //-Override-
     public void setNamespaceContext(NamespaceContext nsContext) {
-        if ( nsContext == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"NamespaceContext"} );
-            throw new NullPointerException( fmsg );
-        }
+        requireNonNull(nsContext, "NamespaceContext");
         this.namespaceContext = nsContext;
-        this.prefixResolver = new JAXPPrefixResolver ( nsContext );
+        this.prefixResolver = new JAXPPrefixResolver (nsContext);
     }
 
-    /**
-     * <p>Returns the current namespace context.</p>
-     *
-     * @return Current Namespace context
-     */
+    //-Override-
     public NamespaceContext getNamespaceContext() {
         return namespaceContext;
     }
 
-    private static Document d = null;
+    /**
+     * Evaluate an {@code XPath} expression in the specified context.
+     * @param expression The XPath expression.
+     * @param contextItem The starting context.
+     * @return an XObject as the result of evaluating the expression
+     * @throws TransformerException if evaluating fails
+     */
+    private XObject eval(String expression, Object contextItem)
+        throws TransformerException {
+        requireNonNull(expression, "XPath expression");
+        com.sun.org.apache.xpath.internal.XPath xpath = new com.sun.org.apache.xpath.internal.XPath(expression,
+            null, prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT);
 
-    private DocumentBuilder getParser() {
-        try {
-            // we'd really like to cache those DocumentBuilders, but we can't because:
-            // 1. thread safety. parsers are not thread-safe, so at least
-            //    we need one instance per a thread.
-            // 2. parsers are non-reentrant, so now we are looking at having a
-            // pool of parsers.
-            // 3. then the class loading issue. The look-up procedure of
-            //    DocumentBuilderFactory.newInstance() depends on context class loader
-            //    and system properties, which may change during the execution of JVM.
-            //
-            // so we really have to create a fresh DocumentBuilder every time we need one
-            // - KK
-            DocumentBuilderFactory dbf = FactoryImpl.getDOMFactory(useServiceMechanism);
-            dbf.setNamespaceAware( true );
-            dbf.setValidating( false );
-            return dbf.newDocumentBuilder();
-        } catch (ParserConfigurationException e) {
-            // this should never happen with a well-behaving JAXP implementation.
-            throw new Error(e);
-        }
+        return eval(contextItem, xpath);
     }
 
-
-    private XObject eval(String expression, Object contextItem)
-        throws javax.xml.transform.TransformerException {
-        com.sun.org.apache.xpath.internal.XPath xpath = new com.sun.org.apache.xpath.internal.XPath( expression,
-            null, prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT );
-        com.sun.org.apache.xpath.internal.XPathContext xpathSupport = null;
-        if ( functionResolver != null ) {
-            JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
-                    functionResolver, featureSecureProcessing, featureManager );
-            xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext( jep );
-        } else {
-            xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext();
-        }
-
-        XObject xobj = null;
-
-        xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
-
-        // If item is null, then we will create a a Dummy contextNode
-        if ( contextItem instanceof Node ) {
-            xobj = xpath.execute (xpathSupport, (Node)contextItem,
-                    prefixResolver );
-        } else {
-            xobj = xpath.execute ( xpathSupport, DTM.NULL, prefixResolver );
-        }
-
-        return xobj;
-    }
-
-    /**
-     * <p>Evaluate an <code>XPath</code> expression in the specified context and return the result as the specified type.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
-     * for context item evaluation,
-     * variable, function and <code>QName</code> resolution and return type conversion.</p>
-     *
-     * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants} (
-     * {@link XPathConstants#NUMBER NUMBER},
-     * {@link XPathConstants#STRING STRING},
-     * {@link XPathConstants#BOOLEAN BOOLEAN},
-     * {@link XPathConstants#NODE NODE} or
-     * {@link XPathConstants#NODESET NODESET})
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
-     *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
-     * If <code>expression</code> or <code>returnType</code> is <code>null</code>, then a
-     * <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param expression The XPath expression.
-     * @param item The starting context (node or node list, for example).
-     * @param returnType The desired return type.
-     *
-     * @return Result of evaluating an XPath expression as an <code>Object</code> of <code>returnType</code>.
-     *
-     * @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If <code>expression</code> or <code>returnType</code> is <code>null</code>.
-     */
+    //-Override-
     public Object evaluate(String expression, Object item, QName returnType)
             throws XPathExpressionException {
-        if ( expression == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"XPath expression"} );
-            throw new NullPointerException ( fmsg );
-        }
-        if ( returnType == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"returnType"} );
-            throw new NullPointerException ( fmsg );
-        }
-        // Checking if requested returnType is supported. returnType need to
-        // be defined in XPathConstants
-        if ( !isSupported ( returnType ) ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
-                    new Object[] { returnType.toString() } );
-            throw new IllegalArgumentException ( fmsg );
-        }
+        //this check is necessary before calling eval to maintain binary compatibility
+        requireNonNull(expression, "XPath expression");
+        isSupported(returnType);
 
         try {
 
-            XObject resultObject = eval( expression, item );
-            return getResultAsType( resultObject, returnType );
-        } catch ( java.lang.NullPointerException npe ) {
+            XObject resultObject = eval(expression, item);
+            return getResultAsType(resultObject, returnType);
+        } catch (java.lang.NullPointerException npe) {
             // If VariableResolver returns null Or if we get
             // NullPointerException at this stage for some other reason
             // then we have to reurn XPathException
-            throw new XPathExpressionException ( npe );
-        } catch ( javax.xml.transform.TransformerException te ) {
+            throw new XPathExpressionException (npe);
+        } catch (TransformerException te) {
             Throwable nestedException = te.getException();
-            if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
+            if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
                 throw (javax.xml.xpath.XPathFunctionException)nestedException;
             } else {
                 // For any other exceptions we need to throw
-                // XPathExpressionException ( as per spec )
-                throw new XPathExpressionException ( te );
+                // XPathExpressionException (as per spec)
+                throw new XPathExpressionException (te);
             }
         }
 
     }
 
-    private boolean isSupported( QName returnType ) {
-        if ( ( returnType.equals( XPathConstants.STRING ) ) ||
-             ( returnType.equals( XPathConstants.NUMBER ) ) ||
-             ( returnType.equals( XPathConstants.BOOLEAN ) ) ||
-             ( returnType.equals( XPathConstants.NODE ) ) ||
-             ( returnType.equals( XPathConstants.NODESET ) )  ) {
-
-            return true;
-        }
-        return false;
-     }
-
-    private Object getResultAsType( XObject resultObject, QName returnType )
-        throws javax.xml.transform.TransformerException {
-        // XPathConstants.STRING
-        if ( returnType.equals( XPathConstants.STRING ) ) {
-            return resultObject.str();
-        }
-        // XPathConstants.NUMBER
-        if ( returnType.equals( XPathConstants.NUMBER ) ) {
-            return new Double ( resultObject.num());
-        }
-        // XPathConstants.BOOLEAN
-        if ( returnType.equals( XPathConstants.BOOLEAN ) ) {
-            return new Boolean( resultObject.bool());
-        }
-        // XPathConstants.NODESET ---ORdered, UNOrdered???
-        if ( returnType.equals( XPathConstants.NODESET ) ) {
-            return resultObject.nodelist();
-        }
-        // XPathConstants.NODE
-        if ( returnType.equals( XPathConstants.NODE ) ) {
-            NodeIterator ni = resultObject.nodeset();
-            //Return the first node, or null
-            return ni.nextNode();
-        }
-        String fmsg = XSLMessages.createXPATHMessage(
-                XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
-                new Object[] { returnType.toString()});
-        throw new IllegalArgumentException( fmsg );
+    //-Override-
+    public String evaluate(String expression, Object item)
+        throws XPathExpressionException {
+        return (String)this.evaluate(expression, item, XPathConstants.STRING);
     }
 
-
-
-    /**
-     * <p>Evaluate an XPath expression in the specified context and return the result as a <code>String</code>.</p>
-     *
-     * <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a <code>returnType</code> of
-     * {@link XPathConstants#STRING}.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" of JAXP 1.3 spec
-     * for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
-     * If <code>expression</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param expression The XPath expression.
-     * @param item The starting context (node or node list, for example).
-     *
-     * @return The <code>String</code> that is the result of evaluating the expression and
-     *   converting the result to a <code>String</code>.
-     *
-     * @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
-     * @throws NullPointerException If <code>expression</code> is <code>null</code>.
-     */
-    public String evaluate(String expression, Object item)
-        throws XPathExpressionException {
-        return (String)this.evaluate( expression, item, XPathConstants.STRING );
-    }
-
-    /**
-     * <p>Compile an XPath expression for later evaluation.</p>
-     *
-     * <p>If <code>expression</code> contains any {@link XPathFunction}s,
-     * they must be available via the {@link XPathFunctionResolver}.
-     * An {@link XPathExpressionException} will be thrown if the <code>XPathFunction</code>
-     * cannot be resovled with the <code>XPathFunctionResolver</code>.</p>
-     *
-     * <p>If <code>expression</code> is <code>null</code>, a <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param expression The XPath expression.
-     *
-     * @return Compiled XPath expression.
-
-     * @throws XPathExpressionException If <code>expression</code> cannot be compiled.
-     * @throws NullPointerException If <code>expression</code> is <code>null</code>.
-     */
+    //-Override-
     public XPathExpression compile(String expression)
         throws XPathExpressionException {
-        if ( expression == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"XPath expression"} );
-            throw new NullPointerException ( fmsg );
-        }
+        requireNonNull(expression, "XPath expression");
         try {
             com.sun.org.apache.xpath.internal.XPath xpath = new XPath (expression, null,
-                    prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT );
+                    prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT);
             // Can have errorListener
             XPathExpressionImpl ximpl = new XPathExpressionImpl (xpath,
                     prefixResolver, functionResolver, variableResolver,
-                    featureSecureProcessing, useServiceMechanism, featureManager );
+                    featureSecureProcessing, useServiceMechanism, featureManager);
             return ximpl;
-        } catch ( javax.xml.transform.TransformerException te ) {
-            throw new XPathExpressionException ( te ) ;
+        } catch (TransformerException te) {
+            throw new XPathExpressionException (te) ;
         }
     }
 
-
-    /**
-     * <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
-     * and return the result as the specified type.</p>
-     *
-     * <p>This method builds a data model for the {@link InputSource} and calls
-     * {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
-     * for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants},
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
-     *
-     * <p>If <code>expression</code>, <code>source</code> or <code>returnType</code> is <code>null</code>,
-     * then a <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param expression The XPath expression.
-     * @param source The input source of the document to evaluate over.
-     * @param returnType The desired return type.
-     *
-     * @return The <code>Object</code> that encapsulates the result of evaluating the expression.
-     *
-     * @throws XPathExpressionException If expression cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If <code>expression</code>, <code>source</code> or <code>returnType</code>
-     *   is <code>null</code>.
-     */
+    //-Override-
     public Object evaluate(String expression, InputSource source,
             QName returnType) throws XPathExpressionException {
-        // Checking validity of different parameters
-        if( source== null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"source"} );
-            throw new NullPointerException ( fmsg );
-        }
-        if ( expression == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"XPath expression"} );
-            throw new NullPointerException ( fmsg );
-        }
-        if ( returnType == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"returnType"} );
-            throw new NullPointerException ( fmsg );
-        }
-
-        //Checking if requested returnType is supported.
-        //returnType need to be defined in XPathConstants
-        if ( !isSupported ( returnType ) ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
-                    new Object[] { returnType.toString() } );
-            throw new IllegalArgumentException ( fmsg );
-        }
+        isSupported(returnType);
 
         try {
-
-            Document document = getParser().parse( source );
-
-            XObject resultObject = eval( expression, document );
-            return getResultAsType( resultObject, returnType );
-        } catch ( SAXException e ) {
-            throw new XPathExpressionException ( e );
-        } catch( IOException e ) {
-            throw new XPathExpressionException ( e );
-        } catch ( javax.xml.transform.TransformerException te ) {
+            Document document = getDocument(source);
+            XObject resultObject = eval(expression, document);
+            return getResultAsType(resultObject, returnType);
+        } catch (TransformerException te) {
             Throwable nestedException = te.getException();
-            if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
+            if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
                 throw (javax.xml.xpath.XPathFunctionException)nestedException;
             } else {
-                throw new XPathExpressionException ( te );
+                throw new XPathExpressionException (te);
             }
         }
-
     }
 
-
-
-
-    /**
-     * <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
-     * and return the result as a <code>String</code>.</p>
-     *
-     * <p>This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a
-     * <code>returnType</code> of {@link XPathConstants#STRING}.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
-     * for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If <code>expression</code> or <code>source</code> is <code>null</code>,
-     * then a <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param expression The XPath expression.
-     * @param source The <code>InputSource</code> of the document to evaluate over.
-     *
-     * @return The <code>String</code> that is the result of evaluating the expression and
-     *   converting the result to a <code>String</code>.
-     *
-     * @throws XPathExpressionException If expression cannot be evaluated.
-     * @throws NullPointerException If <code>expression</code> or <code>source</code> is <code>null</code>.
-     */
+    //-Override-
     public String evaluate(String expression, InputSource source)
         throws XPathExpressionException {
-        return (String)this.evaluate( expression, source, XPathConstants.STRING );
+        return (String)this.evaluate(expression, source, XPathConstants.STRING);
     }
 
-    /**
-     * <p>Reset this <code>XPath</code> to its original configuration.</p>
-     *
-     * <p><code>XPath</code> is reset to the same state as when it was created with
-     * {@link XPathFactory#newXPath()}.
-     * <code>reset()</code> is designed to allow the reuse of existing <code>XPath</code>s
-     * thus saving resources associated with the creation of new <code>XPath</code>s.</p>
-     *
-     * <p>The reset <code>XPath</code> is not guaranteed to have the same
-     * {@link XPathFunctionResolver}, {@link XPathVariableResolver}
-     * or {@link NamespaceContext} <code>Object</code>s, e.g. {@link Object#equals(Object obj)}.
-     * It is guaranteed to have a functionally equal <code>XPathFunctionResolver</code>,
-     * <code>XPathVariableResolver</code>
-     * and <code>NamespaceContext</code>.</p>
-     */
+    //-Override-
     public void reset() {
         this.variableResolver = this.origVariableResolver;
         this.functionResolver = this.origFunctionResolver;
         this.namespaceContext = null;
     }
 
+    //-Override-
+    public <T> T evaluateExpression(String expression, Object item, Class<T> type)
+            throws XPathExpressionException {
+        isSupportedClassType(type);
+        try {
+            XObject resultObject = eval(expression, item);
+            if (type.isAssignableFrom(XPathEvaluationResult.class)) {
+                return getXPathResult(resultObject, type);
+            } else {
+                return XPathResultImpl.getValue(resultObject, type);
+            }
+        } catch (TransformerException te) {
+            throw new XPathExpressionException (te);
+        }
+    }
+
+    //-Override-
+    public XPathEvaluationResult<?> evaluateExpression(String expression, Object item)
+            throws XPathExpressionException {
+        return evaluateExpression(expression, item, XPathEvaluationResult.class);
+    }
+
+    //-Override-
+    public <T> T evaluateExpression(String expression, InputSource source, Class<T> type)
+            throws XPathExpressionException {
+        Document document = getDocument(source);
+        return evaluateExpression(expression, document, type);
+    }
+
+    //-Override-
+    public XPathEvaluationResult<?> evaluateExpression(String expression, InputSource source)
+            throws XPathExpressionException {
+        return evaluateExpression(expression, source, XPathEvaluationResult.class);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImplUtil.java	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.org.apache.xpath.internal.jaxp;
+
+import com.sun.org.apache.xalan.internal.res.XSLMessages;
+import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
+import com.sun.org.apache.xalan.internal.utils.FeatureManager;
+import com.sun.org.apache.xml.internal.dtm.DTM;
+import com.sun.org.apache.xpath.internal.objects.XObject;
+import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
+import java.io.IOException;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathEvaluationResult;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFunctionResolver;
+import javax.xml.xpath.XPathNodes;
+import javax.xml.xpath.XPathVariableResolver;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.traversal.NodeIterator;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * This class contains several utility methods used by XPathImpl and
+ * XPathExpressionImpl
+ */
+class XPathImplUtil {
+    XPathFunctionResolver functionResolver;
+    XPathVariableResolver variableResolver;
+    JAXPPrefixResolver prefixResolver;
+    boolean useServiceMechanism = true;
+    // By default Extension Functions are allowed in XPath Expressions. If
+    // Secure Processing Feature is set on XPathFactory then the invocation of
+    // extensions function need to throw XPathFunctionException
+    boolean featureSecureProcessing = false;
+    FeatureManager featureManager;
+
+    /**
+     * Evaluate an XPath context using the internal XPath engine
+     * @param contextItem The XPath context
+     * @param xpath The internal XPath engine
+     * @return an XObject
+     * @throws javax.xml.transform.TransformerException If the expression cannot be evaluated.
+     */
+    XObject eval(Object contextItem, com.sun.org.apache.xpath.internal.XPath xpath)
+            throws javax.xml.transform.TransformerException {
+        com.sun.org.apache.xpath.internal.XPathContext xpathSupport;
+        if (functionResolver != null) {
+            JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
+                    functionResolver, featureSecureProcessing, featureManager);
+            xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext(jep);
+        } else {
+            xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext();
+        }
+
+        xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
+        XObject xobj;
+
+        Node contextNode = (Node)contextItem;
+        // We always need to have a ContextNode with Xalan XPath implementation
+        // To allow simple expression evaluation like 1+1 we are setting
+        // dummy Document as Context Node
+        if (contextNode == null) {
+            xobj = xpath.execute(xpathSupport, DTM.NULL, prefixResolver);
+        } else {
+            xobj = xpath.execute(xpathSupport, contextNode, prefixResolver);
+        }
+
+        return xobj;
+    }
+
+    /**
+     * Parse the input source and return a Document.
+     * @param source The {@code InputSource} of the document
+     * @return a DOM Document
+     * @throws XPathExpressionException if there is an error parsing the source.
+     */
+    Document getDocument(InputSource source)
+        throws XPathExpressionException {
+        requireNonNull(source, "Source");
+        try {
+            // we'd really like to cache those DocumentBuilders, but we can't because:
+            // 1. thread safety. parsers are not thread-safe, so at least
+            //    we need one instance per a thread.
+            // 2. parsers are non-reentrant, so now we are looking at having a
+            // pool of parsers.
+            // 3. then the class loading issue. The look-up procedure of
+            //    DocumentBuilderFactory.newInstance() depends on context class loader
+            //    and system properties, which may change during the execution of JVM.
+            //
+            // so we really have to create a fresh DocumentBuilder every time we need one
+            // - KK
+            DocumentBuilderFactory dbf = FactoryImpl.getDOMFactory(useServiceMechanism);
+            dbf.setNamespaceAware(true);
+            dbf.setValidating(false);
+            return dbf.newDocumentBuilder().parse(source);
+        } catch (ParserConfigurationException | SAXException | IOException e) {
+            throw new XPathExpressionException (e);
+        }
+    }
+
+    /**
+     * Get result depending on the QName type defined in XPathConstants
+     * @param resultObject the result of an evaluation
+     * @param returnType the return type
+     * @return result per the return type
+     * @throws TransformerException if the result can not be converted to
+     * the specified return type.
+     */
+    Object getResultAsType(XObject resultObject, QName returnType)
+        throws TransformerException {
+        // XPathConstants.STRING
+        if (returnType.equals(XPathConstants.STRING)) {
+            return resultObject.str();
+        }
+        // XPathConstants.NUMBER
+        if (returnType.equals(XPathConstants.NUMBER)) {
+            return resultObject.num();
+        }
+        // XPathConstants.BOOLEAN
+        if (returnType.equals(XPathConstants.BOOLEAN)) {
+            return resultObject.bool();
+        }
+        // XPathConstants.NODESET ---ORdered, UNOrdered???
+        if (returnType.equals(XPathConstants.NODESET)) {
+            return resultObject.nodelist();
+        }
+        // XPathConstants.NODE
+        if (returnType.equals(XPathConstants.NODE)) {
+            NodeIterator ni = resultObject.nodeset();
+            //Return the first node, or null
+            return ni.nextNode();
+        }
+        // If isSupported check is already done then the execution path
+        // shouldn't come here. Being defensive
+        String fmsg = XSLMessages.createXPATHMessage(
+                XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
+                new Object[] { returnType.toString()});
+        throw new IllegalArgumentException (fmsg);
+    }
+
+    /**
+     * Construct an XPathExpressionResult object based on the result of the
+     * evaluation and cast to the specified class type.
+     * @param <T> The class type
+     * @param resultObject the result of an evaluation
+     * @param type The class type expected to be returned by the XPath expression.
+     * @return an instance of the specified type or null if the XObject returned
+     * an UNKNOWN object type.
+     * @throws TransformerException if there is an error converting the result
+     * to the specified type. It's unlikely to happen. This is mostly needed
+     * by the internal XPath engine.
+     */
+    <T> T getXPathResult(XObject resultObject, Class<T> type)
+            throws TransformerException {
+        int resultType = resultObject.getType();
+
+        switch (resultType) {
+            case XObject.CLASS_BOOLEAN :
+                return type.cast(new XPathResultImpl<>(resultObject, Boolean.class));
+            case XObject.CLASS_NUMBER :
+                return type.cast(new XPathResultImpl<>(resultObject, Double.class));
+            case XObject.CLASS_STRING :
+                return type.cast(new XPathResultImpl<>(resultObject, String.class));
+            case XObject.CLASS_NODESET :
+                return type.cast(new XPathResultImpl<>(resultObject, XPathNodes.class));
+            case XObject.CLASS_RTREEFRAG :  //NODE
+                return type.cast(new XPathResultImpl<>(resultObject, Node.class));
+        }
+
+        return null;
+    }
+
+    /**
+     * Check whether or not the specified type is supported
+     * @param <T> The class type
+     * @param type The type to be checked
+     * @throws IllegalArgumentException if the type is not supported
+     */
+    <T> void isSupportedClassType(Class<T> type) {
+        requireNonNull(type, "The class type");
+        if (type.isAssignableFrom(Boolean.class) ||
+                type.isAssignableFrom(Double.class) ||
+                type.isAssignableFrom(Integer.class) ||
+                type.isAssignableFrom(Long.class) ||
+                type.isAssignableFrom(String.class) ||
+                type.isAssignableFrom(XPathNodes.class) ||
+                type.isAssignableFrom(Node.class) ||
+                type.isAssignableFrom(XPathEvaluationResult.class)) {
+            return;
+        }
+        String fmsg = XSLMessages.createXPATHMessage(
+                XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
+                new Object[] { type.toString() });
+        throw new IllegalArgumentException (fmsg);
+    }
+
+    /**
+     * Check if the requested returnType is supported.
+     * @param returnType the return type
+     * @throws IllegalArgumentException if the return type is not supported
+     */
+    void isSupported(QName returnType) {
+        requireNonNull(returnType, "returnType");
+        if (returnType.equals(XPathConstants.STRING) ||
+                returnType.equals(XPathConstants.NUMBER) ||
+                returnType.equals(XPathConstants.BOOLEAN) ||
+                returnType.equals(XPathConstants.NODE) ||
+                returnType.equals(XPathConstants.NODESET)) {
+            return;
+        }
+        String fmsg = XSLMessages.createXPATHMessage(
+                XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
+                new Object[] { returnType.toString() });
+        throw new IllegalArgumentException (fmsg);
+     }
+
+    /**
+     * Checks that the specified parameter is not {@code null}.
+     *
+     * @param <T> the type of the reference
+     * @param param the parameter to check for nullity
+     * @param paramName the parameter name
+     * @throws NullPointerException if {@code param} is {@code null}
+     */
+    <T> void requireNonNull(T param, String paramName) {
+        if (param == null) {
+            String fmsg = XSLMessages.createXPATHMessage(
+                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+                    new Object[] {paramName});
+            throw new NullPointerException (fmsg);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathNodesImpl.java	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.org.apache.xpath.internal.jaxp;
+
+import java.util.Iterator;
+import javax.xml.xpath.XPathException;
+import javax.xml.xpath.XPathNodes;
+import javax.xml.xpath.XPathEvaluationResult.XPathResultType;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * This class implements XPathNodes that represents a set of nodes selected by
+ * evaluating an expression.
+ */
+public class XPathNodesImpl implements XPathNodes {
+    Class<Node> elementType;
+    NodeList nodeList = null;
+
+    public XPathNodesImpl(NodeList nodeList, Class<Node> elementType) {
+        this.nodeList = nodeList;
+        this.elementType = elementType;
+    }
+
+    @Override
+    public Iterator<Node> iterator() {
+        return new NodeSetIterator<>(elementType);
+    }
+
+    class NodeSetIterator<E> implements Iterator<E> {
+        int currentIndex;
+        Class<E> elementType;
+        NodeSetIterator(Class<E> elementType) {
+            this.elementType = elementType;
+        }
+        public boolean hasNext() {
+            if (nodeList != null) {
+                return currentIndex < nodeList.getLength();
+            }
+
+            return false;
+        }
+
+        public E next() {
+            if (nodeList != null && nodeList.getLength() > 0) {
+                return elementType.cast(nodeList.item(currentIndex++));
+            }
+            return null;
+        }
+    }
+
+    @Override
+    public int size() {
+        if (nodeList != null) {
+            return nodeList.getLength();
+        }
+        return 0;
+    }
+
+    @Override
+    public Node get(int index) throws XPathException {
+        if (index <0 || index >= size()) {
+            throw new IndexOutOfBoundsException("Index " + index + " is out of bounds");
+        }
+        if (nodeList != null) {
+            return nodeList.item(index);
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathResultImpl.java	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.org.apache.xpath.internal.jaxp;
+
+import com.sun.org.apache.xpath.internal.objects.XObject;
+import java.util.Objects;
+import javax.xml.transform.TransformerException;
+import javax.xml.xpath.XPathNodes;
+import javax.xml.xpath.XPathEvaluationResult;
+import javax.xml.xpath.XPathEvaluationResult.XPathResultType;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.traversal.NodeIterator;
+
+
+/**
+ * This is the implementation of XPathEvaluationResult that represents the
+ * result of the evaluation of an XPath expression within the context of a
+ * particular node.
+ */
+class XPathResultImpl<T> implements XPathEvaluationResult<T> {
+
+    XObject resultObject;
+    int resultType;
+    Class<T> type;
+    XPathResultType mapToType;
+    NodeList nodeList = null;
+    int currentIndex;
+    Node currentNode;
+
+    boolean boolValue = false;
+    Node node = null;
+    double numValue;
+    String strValue;
+
+    /**
+     * Construct an XPathEvaluationResult object.
+     *
+     * @param resultObject internal XPath result object
+     * @param type class type
+     * @throws TransformerException if there is an error reading the XPath
+     * result.
+     */
+    public XPathResultImpl(XObject resultObject, Class<T> type)
+            throws TransformerException {
+        this.resultObject = resultObject;
+        resultType = resultObject.getType();
+        this.type = type;
+        getResult(resultObject);
+    }
+
+    /**
+     * Return the result type as an enum specified by {@code XPathResultType}
+     * @return the result type
+     */
+    @Override
+    public XPathResultType type() {
+        return mapToType;
+    }
+
+    /**
+     * Returns the value of the result as the type &lt;T&gt; specified for the class.
+     *
+     * @return The value of the result.
+     */
+    @Override
+    public T value() {
+        Objects.requireNonNull(type);
+        try {
+            return getValue(resultObject, type);
+        } catch (TransformerException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * Read the XObject and set values in accordance with the result type
+     * @param resultObject  internal XPath result object
+     * @throws TransformerException  if there is an error reading the XPath
+     * result.
+     */
+    private void getResult(XObject resultObject) throws TransformerException {
+        switch (resultType) {
+            case XObject.CLASS_BOOLEAN:
+                boolValue = resultObject.bool();
+                mapToType = XPathResultType.BOOLEAN;
+                break;
+            case XObject.CLASS_NUMBER:
+                numValue = resultObject.num();
+                mapToType = XPathResultType.NUMBER;
+                break;
+            case XObject.CLASS_STRING:
+                strValue = resultObject.str();
+                mapToType = XPathResultType.STRING;
+                break;
+            case XObject.CLASS_NODESET:
+                mapToType = XPathResultType.NODESET;
+                nodeList = resultObject.nodelist();
+                break;
+            case XObject.CLASS_RTREEFRAG:  //NODE
+                mapToType = XPathResultType.NODE;
+                NodeIterator ni = resultObject.nodeset();
+                //Return the first node, or null
+                node = ni.nextNode();
+                break;
+        }
+    }
+
+    /**
+     * Read the internal result object and return the value in accordance with
+     * the type specified.
+     *
+     * @param <T> The expected class type.
+     * @param resultObject internal XPath result object
+     * @param type the class type
+     * @return The value of the result, null in case of unexpected type.
+     * @throws TransformerException  if there is an error reading the XPath
+     * result.
+     */
+    static <T> T getValue(XObject resultObject, Class<T> type) throws TransformerException {
+        Objects.requireNonNull(type);
+        if (type.isAssignableFrom(XPathEvaluationResult.class)) {
+            return type.cast(new XPathResultImpl<T>(resultObject, type));
+        }
+        int resultType = classToInternalType(type);
+        switch (resultType) {
+            case XObject.CLASS_BOOLEAN:
+                return type.cast(resultObject.bool());
+            case XObject.CLASS_NUMBER:
+                if (Double.class.isAssignableFrom(type)) {
+                    return type.cast(resultObject.num());
+                } else if (Integer.class.isAssignableFrom(type)) {
+                    return type.cast((int)resultObject.num());
+                } else if (Long.class.isAssignableFrom(type)) {
+                    return type.cast((long)resultObject.num());
+                }
+                /*
+                  This is to suppress warnings. By the current specification,
+                among numeric types, only Double, Integer and Long are supported.
+                */
+                break;
+            case XObject.CLASS_STRING:
+                return type.cast(resultObject.str());
+            case XObject.CLASS_NODESET:
+                XPathNodes nodeSet = new XPathNodesImpl(resultObject.nodelist(),
+                        Node.class);
+                return type.cast(nodeSet);
+            case XObject.CLASS_RTREEFRAG:  //NODE
+                NodeIterator ni = resultObject.nodeset();
+                //Return the first node, or null
+                return type.cast(ni.nextNode());
+        }
+
+        return null;
+    }
+
+    /**
+     * Map the specified class type to the internal result type
+     *
+     * @param <T> The expected class type.
+     * @param type the class type
+     * @return the internal XObject type.
+     */
+    static <T> int classToInternalType(Class<T> type) {
+        if (type.isAssignableFrom(Boolean.class)) {
+            return XObject.CLASS_BOOLEAN;
+        } else if (Number.class.isAssignableFrom(type)) {
+            return XObject.CLASS_NUMBER;
+        } else if (type.isAssignableFrom(String.class)) {
+            return XObject.CLASS_STRING;
+        } else if (type.isAssignableFrom(XPathNodes.class)) {
+            return XObject.CLASS_NODESET;
+        } else if (type.isAssignableFrom(Node.class)) {
+            return XObject.CLASS_RTREEFRAG;
+        }
+        return XObject.CLASS_NULL;
+    }
+}
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPath.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPath.java	Wed Jul 05 20:17:28 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,12 +25,12 @@
 
 package javax.xml.xpath;
 
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
 import org.xml.sax.InputSource;
-import javax.xml.namespace.QName;
-import javax.xml.namespace.NamespaceContext;
 
 /**
- * <p><code>XPath</code> provides access to the XPath evaluation environment and expressions.</p>
+ * {@code XPath} provides access to the XPath evaluation environment and expressions.
  *
  * <a name="XPath-evaluation"/>
  * <table border="1" cellpadding="2">
@@ -39,7 +39,6 @@
  *       <th colspan="2">Evaluation of XPath Expressions.</th>
  *     </tr>
  *   </thead>
- *   <tbody>
  *     <tr>
  *       <td>context</td>
  *       <td>
@@ -55,8 +54,8 @@
  *        If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver}
  *        set with {@link #setXPathVariableResolver(XPathVariableResolver resolver)}.
  *        An {@link XPathExpressionException} is raised if the variable resolver is undefined or
- *        the resolver returns <code>null</code> for the variable.
- *        The value of a variable must be immutable through the course of any single evaluation.</p>
+ *        the resolver returns {@code null} for the variable.
+ *        The value of a variable must be immutable through the course of any single evaluation.
  *      </td>
  *    </tr>
  *    <tr>
@@ -65,7 +64,7 @@
  *        If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver}
  *        set with {@link #setXPathFunctionResolver(XPathFunctionResolver resolver)}.
  *        An {@link XPathExpressionException} is raised if the function resolver is undefined or
- *        the function resolver returns <code>null</code> for the function.</p>
+ *        the function resolver returns {@code null} for the function.
  *      </td>
  *    </tr>
  *    <tr>
@@ -80,7 +79,7 @@
  *      <td>
  *        This result of evaluating an expression is converted to an instance of the desired return type.
  *        Valid return types are defined in {@link XPathConstants}.
- *        Conversion to the return type follows XPath conversion rules.</p>
+ *        Conversion to the return type follows XPath conversion rules.
  *      </td>
  *    </tr>
  * </table>
@@ -88,9 +87,9 @@
  * <p>An XPath object is not thread-safe and not reentrant.
  * In other words, it is the application's responsibility to make
  * sure that one {@link XPath} object is not used from
- * more than one thread at any given time, and while the <code>evaluate</code>
+ * more than one thread at any given time, and while the {@code evaluate}
  * method is invoked, applications may not recursively call
- * the <code>evaluate</code> method.
+ * the {@code evaluate} method.
  * <p>
  *
  * @author  <a href="Norman.Walsh@Sun.com">Norman Walsh</a>
@@ -100,191 +99,189 @@
  */
 public interface XPath {
 
-        /**
-         * <p>Reset this <code>XPath</code> to its original configuration.</p>
-         *
-         * <p><code>XPath</code> is reset to the same state as when it was created with
-         * {@link XPathFactory#newXPath()}.
-         * <code>reset()</code> is designed to allow the reuse of existing <code>XPath</code>s
-         * thus saving resources associated with the creation of new <code>XPath</code>s.</p>
-         *
-         * <p>The reset <code>XPath</code> is not guaranteed to have the same {@link XPathFunctionResolver}, {@link XPathVariableResolver}
-         * or {@link NamespaceContext} <code>Object</code>s, e.g. {@link Object#equals(Object obj)}.
-         * It is guaranteed to have a functionally equal <code>XPathFunctionResolver</code>, <code>XPathVariableResolver</code>
-         * and <code>NamespaceContext</code>.</p>
-         */
-        public void reset();
 
     /**
-     * <p>Establish a variable resolver.</p>
+     * Reset this {@code XPath} to its original configuration.
      *
-     * <p>A <code>NullPointerException</code> is thrown if <code>resolver</code> is <code>null</code>.</p>
+     * <p>{@code XPath} is reset to the same state as when it was created with
+     * {@link XPathFactory#newXPath()}.
+     * {@code reset()} is designed to allow the reuse of existing {@code XPath}s
+     * thus saving resources associated with the creation of new {@code XPath}s.
+     *
+     * <p>The reset {@code XPath} is not guaranteed to have the same
+     * {@link XPathFunctionResolver}, {@link XPathVariableResolver}
+     * or {@link NamespaceContext} {@code Object}s, e.g. {@link Object#equals(Object obj)}.
+     * It is guaranteed to have a functionally equal {@code XPathFunctionResolver},
+     * {@code XPathVariableResolver} and {@code NamespaceContext}.
+     */
+    public void reset();
+
+    /**
+     * Establish a variable resolver.
+     *
+     * <p>A {@code NullPointerException} is thrown if {@code resolver} is {@code null}.
      *
      * @param resolver Variable resolver.
      *
-     *  @throws NullPointerException If <code>resolver</code> is <code>null</code>.
+     * @throws NullPointerException If {@code resolver} is {@code null}.
      */
     public void setXPathVariableResolver(XPathVariableResolver resolver);
 
     /**
-       * <p>Return the current variable resolver.</p>
+       * Return the current variable resolver.
        *
-       * <p><code>null</code> is returned in no variable resolver is in effect.</p>
+       * <p>{@code null} is returned in no variable resolver is in effect.
        *
        * @return Current variable resolver.
        */
     public XPathVariableResolver getXPathVariableResolver();
 
     /**
-       * <p>Establish a function resolver.</p>
+       * Establish a function resolver.
        *
-       * <p>A <code>NullPointerException</code> is thrown if <code>resolver</code> is <code>null</code>.</p>
+       * <p>A {@code NullPointerException} is thrown if {@code resolver} is {@code null}.
        *
        * @param resolver XPath function resolver.
        *
-       * @throws NullPointerException If <code>resolver</code> is <code>null</code>.
+       * @throws NullPointerException If {@code resolver} is {@code null}.
        */
     public void setXPathFunctionResolver(XPathFunctionResolver resolver);
 
     /**
-       * <p>Return the current function resolver.</p>
-       *
-       * <p><code>null</code> is returned in no function resolver is in effect.</p>
+       * Return the current function resolver.
+       * <p>
+       * {@code null} is returned in no function resolver is in effect.
        *
        * @return Current function resolver.
        */
     public XPathFunctionResolver getXPathFunctionResolver();
 
     /**
-       * <p>Establish a namespace context.</p>
+       * Establish a namespace context.
        *
-       * <p>A <code>NullPointerException</code> is thrown if <code>nsContext</code> is <code>null</code>.</p>
+       * <p>A {@code NullPointerException} is thrown if {@code nsContext} is {@code null}.
        *
        * @param nsContext Namespace context to use.
        *
-       * @throws NullPointerException If <code>nsContext</code> is <code>null</code>.
+       * @throws NullPointerException If {@code nsContext} is {@code null}.
        */
     public void setNamespaceContext(NamespaceContext nsContext);
 
     /**
-       * <p>Return the current namespace context.</p>
+       * Return the current namespace context.
        *
-       * <p><code>null</code> is returned in no namespace context is in effect.</p>
+       * <p>{@code null} is returned in no namespace context is in effect.
        *
        * @return Current Namespace context.
        */
     public NamespaceContext getNamespaceContext();
 
     /**
-       * <p>Compile an XPath expression for later evaluation.</p>
+       * Compile an XPath expression for later evaluation.
        *
-       * <p>If <code>expression</code> contains any {@link XPathFunction}s,
+       * <p>If {@code expression} contains any {@link XPathFunction}s,
        * they must be available via the {@link XPathFunctionResolver}.
        * An {@link XPathExpressionException} will be thrown if the
-       * <code>XPathFunction</code>
-       * cannot be resovled with the <code>XPathFunctionResolver</code>.</p>
+       * {@code XPathFunction}
+       * cannot be resovled with the {@code XPathFunctionResolver}.
        *
-       * <p>If <code>expression</code> contains any variables, the
+       * <p>If {@code expression} contains any variables, the
        * {@link XPathVariableResolver} in effect
-       * <strong>at compile time</strong> will be used to resolve them.</p>
-       *
-       * <p>If <code>expression</code> is <code>null</code>, a <code>NullPointerException</code> is thrown.</p>
+       * <strong>at compile time</strong> will be used to resolve them.
        *
        * @param expression The XPath expression.
        *
        * @return Compiled XPath expression.
 
-       * @throws XPathExpressionException If <code>expression</code> cannot be compiled.
-       * @throws NullPointerException If <code>expression</code> is <code>null</code>.
+       * @throws XPathExpressionException If {@code expression} cannot be compiled.
+       * @throws NullPointerException If {@code expression} is {@code null}.
        */
     public XPathExpression compile(String expression)
         throws XPathExpressionException;
 
     /**
-     * <p>Evaluate an <code>XPath</code> expression in the specified context and return the result as the specified type.</p>
+     * Evaluate an {@code XPath} expression in the specified context and
+     * return the result as the specified type.
      *
-     * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
-     * variable, function and <code>QName</code> resolution and return type conversion.</p>
+     * <p>
+     * See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a>
+     * for context item evaluation, variable, function and {@code QName} resolution
+     * and return type conversion.
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
      *
-     * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants} (
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
+     *
+     * @param expression The XPath expression.
+     * @param item The context the XPath expression will be evaluated in.
+     * @param returnType The result type expected to be returned by the XPath expression.
+     *
+     * @return The result of evaluating an XPath expression as an {@code Object} of {@code returnType}.
+     *
+     * @throws XPathExpressionException If {@code expression} cannot be evaluated.
+     * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants} (
      * {@link XPathConstants#NUMBER NUMBER},
      * {@link XPathConstants#STRING STRING},
      * {@link XPathConstants#BOOLEAN BOOLEAN},
      * {@link XPathConstants#NODE NODE} or
-     * {@link XPathConstants#NODESET NODESET})
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
-     *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
-     * If <code>expression</code> or <code>returnType</code> is <code>null</code>, then a
-     * <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param expression The XPath expression.
-     * @param item The starting context (a node, for example).
-     * @param returnType The desired return type.
-     *
-     * @return Result of evaluating an XPath expression as an <code>Object</code> of <code>returnType</code>.
-     *
-     * @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If <code>expression</code> or <code>returnType</code> is <code>null</code>.
+     * {@link XPathConstants#NODESET NODESET}).
+     * @throws NullPointerException If {@code expression or returnType} is {@code null}.
      */
     public Object evaluate(String expression, Object item, QName returnType)
         throws XPathExpressionException;
 
     /**
-     * <p>Evaluate an XPath expression in the specified context and return the result as a <code>String</code>.</p>
+     * Evaluate an XPath expression in the specified context and return the result as a {@code String}.
      *
-     * <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a <code>returnType</code> of
-     * {@link XPathConstants#STRING}.</p>
+     * <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a {@code returnType} of
+     * {@link XPathConstants#STRING}.
      *
      * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
+     * variable, function and QName resolution and return type conversion.
      *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
-     * If <code>expression</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
+     *
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
      *
      * @param expression The XPath expression.
-     * @param item The starting context (a node, for example).
+     * @param item The context the XPath expression will be evaluated in.
      *
-     * @return The <code>String</code> that is the result of evaluating the expression and
-     *   converting the result to a <code>String</code>.
+     * @return The result of evaluating an XPath expression as a {@code String}.
      *
-     * @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
-     * @throws NullPointerException If <code>expression</code> is <code>null</code>.
+     * @throws XPathExpressionException If {@code expression} cannot be evaluated.
+     * @throws NullPointerException If {@code expression} is {@code null}.
      */
     public String evaluate(String expression, Object item)
         throws XPathExpressionException;
 
     /**
-     * <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
-     * and return the result as the specified type.</p>
+     * Evaluate an XPath expression in the context of the specified {@code InputSource}
+     * and return the result as the specified type.
      *
      * <p>This method builds a data model for the {@link InputSource} and calls
-     * {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.</p>
+     * {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.
      *
      * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants},
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
-     *
-     * <p>If <code>expression</code>, <code>source</code> or <code>returnType</code> is <code>null</code>,
-     * then a <code>NullPointerException</code> is thrown.</p>
+     * variable, function and QName resolution and return type conversion.
      *
      * @param expression The XPath expression.
      * @param source The input source of the document to evaluate over.
      * @param returnType The desired return type.
      *
-     * @return The <code>Object</code> that encapsulates the result of evaluating the expression.
+     * @return The {@code Object} that encapsulates the result of evaluating the expression.
      *
      * @throws XPathExpressionException If expression cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If <code>expression</code>, <code>source</code> or <code>returnType</code>
-     *   is <code>null</code>.
+     * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
+     * @throws NullPointerException If {@code expression, source or returnType} is {@code null}.
      */
     public Object evaluate(
         String expression,
@@ -293,27 +290,209 @@
         throws XPathExpressionException;
 
     /**
-     * <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
-     * and return the result as a <code>String</code>.</p>
+     * Evaluate an XPath expression in the context of the specified {@code InputSource}
+     * and return the result as a {@code String}.
      *
      * <p>This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a
-     * <code>returnType</code> of {@link XPathConstants#STRING}.</p>
+     * {@code returnType} of {@link XPathConstants#STRING}.
      *
      * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If <code>expression</code> or <code>source</code> is <code>null</code>,
-     * then a <code>NullPointerException</code> is thrown.</p>
+     * variable, function and QName resolution and return type conversion.
      *
      * @param expression The XPath expression.
-     * @param source The <code>InputSource</code> of the document to evaluate over.
+     * @param source The {@code InputSource} of the document to evaluate over.
      *
-     * @return The <code>String</code> that is the result of evaluating the expression and
-     *   converting the result to a <code>String</code>.
+     * @return The {@code String} that is the result of evaluating the expression and
+     *   converting the result to a {@code String}.
      *
      * @throws XPathExpressionException If expression cannot be evaluated.
-     * @throws NullPointerException If <code>expression</code> or <code>source</code> is <code>null</code>.
+     * @throws NullPointerException If {@code expression or source} is {@code null}.
      */
     public String evaluate(String expression, InputSource source)
         throws XPathExpressionException;
+
+    /**
+     * Evaluate an XPath expression in the specified context and return
+     * the result with the type specified through the {@code class type}
+     *
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
+     *
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+     *     (T)evaluate(expression, item,
+     *           XPathEvaluationResult.XPathResultType.getQNameType(type));
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
+     * XPathEvaluationResult as the type will result in IllegalArgumentException.
+     * Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
+     * this method.
+     *
+     * @param <T> The class type that will be returned by the XPath expression.
+     * @param expression The XPath expression.
+     * @param item The context the XPath expression will be evaluated in.
+     * @param type The class type expected to be returned by the XPath expression.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If {@code type} is not of the types
+     * corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType},
+     * or XPathEvaluationResult is specified as the type but an implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
+     * @throws NullPointerException If {@code expression or type} is {@code null}.
+     *
+     * @since 1.9
+     */
+    default <T>T evaluateExpression(String expression, Object item, Class<T> type)
+        throws XPathExpressionException {
+        return type.cast(evaluate(expression, item,
+                XPathEvaluationResult.XPathResultType.getQNameType(type)));
+    }
+
+    /**
+     * Evaluate an XPath expression in the specified context. This is equivalent to
+     * calling {@link #evaluateExpression(String expression, Object item, Class type)}
+     * with type {@link XPathEvaluationResult}:
+     * <pre> {@code
+     *     evaluateExpression(expression, item, XPathEvaluationResult.class);
+     * }</pre>
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
+     *
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+     *     evaluateExpression(expression, item, XPathEvaluationResult.class);
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY}
+     * type, the default implementation of this method will always throw an
+     * IllegalArgumentException. Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
+     * override this method.
+     *
+     * @param expression The XPath expression.
+     * @param item The context the XPath expression will be evaluated in.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If the implementation of this method
+     * does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
+     * @throws NullPointerException If {@code expression} is {@code null}.
+     *
+     * @since 1.9
+     */
+    default XPathEvaluationResult<?> evaluateExpression(String expression, Object item)
+        throws XPathExpressionException
+    {
+        return evaluateExpression(expression, item, XPathEvaluationResult.class);
+    }
+
+    /**
+     * Evaluate an XPath expression in the context of the specified {@code source}
+     * and return the result as specified.
+     * <p>
+     * This method builds a data model for the {@link InputSource} and calls
+     * {@link #evaluateExpression(String expression, Object item, Class type)}
+     * on the resulting document object. The data model is usually
+     * {@link org.w3c.dom.Document}
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+           (T)evaluate(expression, source,
+                XPathEvaluationResult.XPathResultType.getQNameType(type));
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
+     * XPathEvaluationResult as the type will result in IllegalArgumentException.
+     * Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
+     * this method.
+     *
+     * @param <T> The class type that will be returned by the XPath expression.
+     * @param expression The XPath expression.
+     * @param source The input source of the document to evaluate over.
+     * @param type The class type expected to be returned by the XPath expression.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If {@code type} is not of the types
+     * corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
+     * XPathResultType}, or XPathEvaluationResult is specified as the type but an
+     * implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
+     * @throws NullPointerException If {@code expression, source or type}is {@code null}.
+     *
+     * @since 1.9
+     */
+    default <T>T evaluateExpression(String expression, InputSource source, Class<T> type)
+        throws XPathExpressionException
+    {
+        return type.cast(evaluate(expression, source,
+                XPathEvaluationResult.XPathResultType.getQNameType(type)));
+    }
+
+    /**
+     * Evaluate an XPath expression in the specified context. This is equivalent to
+     * calling {@link #evaluateExpression(String expression, Object item, Class type)}
+     * with type {@link XPathEvaluationResult}:
+     * <pre> {@code
+     *     evaluateExpression(expression, item, XPathEvaluationResult.class);
+     * }</pre>
+     * <p>
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+     *     evaluateExpression(expression, source, XPathEvaluationResult.class);
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY}
+     * type, the default implementation of this method will always throw an
+     * IllegalArgumentException. Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
+     * override this method.
+     *
+     * @param expression The XPath expression.
+     * @param source The input source of the document to evaluate over.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If the implementation of this method
+     * does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
+     * @throws NullPointerException If {@code expression or source} is {@code null}.
+     *
+     * @since 1.9
+     */
+    default XPathEvaluationResult<?> evaluateExpression(String expression, InputSource source)
+        throws XPathExpressionException
+    {
+        return evaluateExpression(expression, source, XPathEvaluationResult.class);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathEvaluationResult.java	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package javax.xml.xpath;
+
+import java.util.Objects;
+import javax.xml.namespace.QName;
+import org.w3c.dom.Node;
+/**
+ * The {@code XPathEvaluationResult} interface represents the result of the
+ * evaluation of an XPath expression within the context of a particular node.
+ * The evaluation of an XPath expression can result in various result types as
+ * defined in XML Path Language (XPath) Version 1.0.
+ * <p>
+ *
+ * @param <T> the object type returned by the XPath evaluation.
+ * @see <a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version
+ * 1.0</a>
+ *
+ * @since 1.9
+ */
+public interface XPathEvaluationResult<T> {
+
+    /**
+     * XPathResultType represents possible return types of an XPath evaluation.
+     * Provided as an enum type, it allows the use of switch statement. At the
+     * same time, a mapping is provided between the original QName types in
+     * {@link XPathConstants} and class types used in the generic methods.
+     */
+    public static enum XPathResultType {
+        /**
+         * Any type that represents any of the 5 other types listed below.
+         * Maps to {@link XPathEvaluationResult}.
+         */
+        ANY(new QName("http://www.w3.org/1999/XSL/Transform", "any"), XPathEvaluationResult.class),
+        /**
+         * The XPath 1.0 boolean data type. Maps to Java {@link Boolean}.
+         */
+        BOOLEAN(XPathConstants.BOOLEAN, Boolean.class),
+        /**
+         * The XPath 1.0 Number data type. Maps to Java {@link Number}. Of the
+         * subtypes of Number, only Double, Integer and Long are required.
+         */
+        NUMBER(XPathConstants.NUMBER, Number.class),
+        /**
+         * The XPath 1.0 String data type. Maps to Java {@link String}.
+         */
+        STRING(XPathConstants.STRING, String.class),
+        /**
+         * The XPath 1.0 NodeSet data type. Maps to {@link org.w3c.dom.NodeList}.
+         */
+        NODESET(XPathConstants.NODESET, XPathNodes.class),
+        /**
+         * The XPath 1.0 NodeSet data type. Maps to {@link org.w3c.dom.Node}.
+         */
+        NODE(XPathConstants.NODE, Node.class);
+
+        final QName qnameType;
+        final Class<?> clsType;
+        XPathResultType(QName qnameType, Class<?> clsType) {
+            this.qnameType = qnameType;
+            this.clsType = clsType;
+        }
+
+        /**
+         * Compares this type to the specified class type.
+         * @param clsType class type
+         * @return true if the argument is not null and is a class type that
+         * matches that this type represents, false otherwise.
+         */
+        private boolean equalsClassType(Class<?> clsType) {
+            Objects.nonNull(clsType);
+            if (clsType.isAssignableFrom(this.clsType)) {
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Returns the QName type as specified in {@link XPathConstants} that
+         * corresponds to the specified class type.
+         * @param clsType a class type that the enum type supports
+         * @return the QName type that matches with the specified class type,
+         * null if there is no match
+         */
+        static public QName getQNameType(Class<?> clsType) {
+            for (XPathResultType type : XPathResultType.values()) {
+                if (type.equalsClassType(clsType)) {
+                    return type.qnameType;
+                }
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Return the result type as an enum specified by {@code XPathResultType}
+     * @return the result type
+     */
+    public XPathResultType type();
+
+    /**
+     * Returns the value of the result as the type &lt;T&gt; specified for the class.
+     *
+     * @return The value of the result.
+     */
+    public T value();
+
+}
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpression.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpression.java	Wed Jul 05 20:17:28 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,11 @@
 
 package javax.xml.xpath;
 
+import javax.xml.namespace.QName;
 import org.xml.sax.InputSource;
-import javax.xml.namespace.QName;
 
 /**
- * <p><code>XPathExpression</code> provides access to compiled XPath expressions.</p>
+ * <p>{@code XPathExpression} provides access to compiled XPath expressions.</p>
  *
  * <a name="XPathExpression-evaluation"/>
  * <table border="1" cellpadding="2">
@@ -53,7 +53,7 @@
  *      <td>
  *        If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver}.
  *        An {@link XPathExpressionException} is raised if the variable resolver is undefined or
- *        the resolver returns <code>null</code> for the variable.
+ *        the resolver returns {@code null} for the variable.
  *        The value of a variable must be immutable through the course of any single evaluation.</p>
  *      </td>
  *    </tr>
@@ -62,7 +62,7 @@
  *      <td>
  *        If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver}.
  *        An {@link XPathExpressionException} is raised if the function resolver is undefined or
- *        the function resolver returns <code>null</code> for the function.</p>
+ *        the function resolver returns {@code null} for the function.</p>
  *      </td>
  *    </tr>
  *    <tr>
@@ -84,9 +84,9 @@
  * <p>An XPath expression is not thread-safe and not reentrant.
  * In other words, it is the application's responsibility to make
  * sure that one {@link XPathExpression} object is not used from
- * more than one thread at any given time, and while the <code>evaluate</code>
+ * more than one thread at any given time, and while the {@code evaluate}
  * method is invoked, applications may not recursively call
- * the <code>evaluate</code> method.
+ * the {@code evaluate} method.
  * <p>
  *
  * @author  <a href="mailto:Norman.Walsh@Sun.com">Norman Walsh</a>
@@ -96,50 +96,56 @@
  */
 public interface XPathExpression {
 
+
     /**
      * <p>Evaluate the compiled XPath expression in the specified context and return the result as the specified type.</p>
      *
      * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
      * variable, function and QName resolution and return type conversion.</p>
      *
-     * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants},
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
      *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
-     * If <code>returnType</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
      *
-     * @param item The starting context (a node, for example).
-     * @param returnType The desired return type.
+     * @param item The context the XPath expression will be evaluated in.
+     * @param returnType The result type expected to be returned by the XPath expression.
      *
-     * @return The <code>Object</code> that is the result of evaluating the expression and converting the result to
-     *   <code>returnType</code>.
+     * @return The {@code Object} that is the result of evaluating the expression and converting the result to
+     *   {@code returnType}.
      *
      * @throws XPathExpressionException If the expression cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If  <code>returnType</code> is <code>null</code>.
+     * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
+     * @throws NullPointerException If {@code returnType} is {@code null}.
      */
     public Object evaluate(Object item, QName returnType)
         throws XPathExpressionException;
 
     /**
-     * <p>Evaluate the compiled XPath expression in the specified context and return the result as a <code>String</code>.</p>
+     * <p>Evaluate the compiled XPath expression in the specified context and return the result as a {@code String}.</p>
      *
-     * <p>This method calls {@link #evaluate(Object item, QName returnType)} with a <code>returnType</code> of
+     * <p>This method calls {@link #evaluate(Object item, QName returnType)} with a {@code returnType} of
      * {@link XPathConstants#STRING}.</p>
      *
      * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
      * variable, function and QName resolution and return type conversion.</p>
      *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
      *
-     * @param item The starting context (a node, for example).
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
      *
-     * @return The <code>String</code> that is the result of evaluating the expression and converting the result to a
-     *   <code>String</code>.
+     * @param item The context the XPath expression will be evaluated in.
+     *
+     * @return The result of evaluating an XPath expression as a {@code String}.
      *
      * @throws XPathExpressionException If the expression cannot be evaluated.
      */
@@ -147,7 +153,7 @@
         throws XPathExpressionException;
 
     /**
-     * <p>Evaluate the compiled XPath expression in the context of the specified <code>InputSource</code> and return the result as the
+     * <p>Evaluate the compiled XPath expression in the context of the specified {@code InputSource} and return the result as the
      * specified type.</p>
      *
      * <p>This method builds a data model for the {@link InputSource} and calls
@@ -156,45 +162,225 @@
      * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
      * variable, function and QName resolution and return type conversion.</p>
      *
-     * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants},
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
+     * <p>If {@code returnType} is not one of the types defined in {@link XPathConstants},
+     * then an {@code IllegalArgumentException} is thrown.</p>
      *
-     * <p>If <code>source</code> or <code>returnType</code> is <code>null</code>,
-     * then a <code>NullPointerException</code> is thrown.</p>
+     * <p>If {@code source} or {@code returnType} is {@code null},
+     * then a {@code NullPointerException} is thrown.</p>
      *
-     * @param source The <code>InputSource</code> of the document to evaluate over.
+     * @param source The {@code InputSource} of the document to evaluate over.
      * @param returnType The desired return type.
      *
-     * @return The <code>Object</code> that is the result of evaluating the expression and converting the result to
-     *   <code>returnType</code>.
+     * @return The {@code Object} that is the result of evaluating the expression and converting the result to
+     *   {@code returnType}.
      *
      * @throws XPathExpressionException If the expression cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If  <code>source</code> or <code>returnType</code> is <code>null</code>.
+     * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
+     * @throws NullPointerException If {@code source or returnType} is {@code null}.
      */
     public Object evaluate(InputSource source, QName returnType)
         throws XPathExpressionException;
 
     /**
-     * <p>Evaluate the compiled XPath expression in the context of the specified <code>InputSource</code> and return the result as a
-     * <code>String</code>.</p>
+     * <p>Evaluate the compiled XPath expression in the context of the specified {@code InputSource} and return the result as a
+     * {@code String}.</p>
      *
-     * <p>This method calls {@link #evaluate(InputSource source, QName returnType)} with a <code>returnType</code> of
+     * <p>This method calls {@link #evaluate(InputSource source, QName returnType)} with a {@code returnType} of
      * {@link XPathConstants#STRING}.</p>
      *
      * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
      * variable, function and QName resolution and return type conversion.</p>
      *
-     * <p>If <code>source</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
+     * <p>If {@code source} is {@code null}, then a {@code NullPointerException} is thrown.</p>
      *
-     * @param source The <code>InputSource</code> of the document to evaluate over.
+     * @param source The {@code InputSource} of the document to evaluate over.
      *
-     * @return The <code>String</code> that is the result of evaluating the expression and converting the result to a
-     *   <code>String</code>.
+     * @return The {@code String} that is the result of evaluating the expression and converting the result to a
+     *   {@code String}.
      *
      * @throws XPathExpressionException If the expression cannot be evaluated.
-     * @throws NullPointerException If  <code>source</code> is <code>null</code>.
+     * @throws NullPointerException If {@code source} is {@code null}.
      */
     public String evaluate(InputSource source)
         throws XPathExpressionException;
+
+    /**
+     * Evaluate the compiled XPath expression in the specified context, and return
+     * the result with the type specified through the {@code class type}.
+     *
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
+     *
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+     *     (T)evaluate(item, XPathEvaluationResult.XPathResultType.getQNameType(type));
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
+     * XPathEvaluationResult as the type will result in IllegalArgumentException.
+     * Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
+     * this method.
+     *
+     * @param <T> The class type that will be returned by the XPath expression.
+     * @param item The context the XPath expression will be evaluated in.
+     * @param type The class type expected to be returned by the XPath expression.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If {@code type} is not of the types
+     * corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
+     * XPathResultType}, or XPathEvaluationResult is specified as the type but an
+     * implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
+     * @throws NullPointerException If {@code type} is {@code null}.
+     *
+     * @since 1.9
+     */
+    default <T>T evaluateExpression(Object item, Class<T> type)
+        throws XPathExpressionException
+    {
+        return type.cast(evaluate(item, XPathEvaluationResult.XPathResultType.getQNameType(type)));
+    }
+
+    /**
+     * Evaluate the compiled XPath expression in the specified context. This is
+     * equivalent to calling {@link #evaluateExpression(Object item, Class type)}
+     * with type {@link XPathEvaluationResult}:
+     * <pre> {@code
+     *     evaluateExpression(item, XPathEvaluationResult.class);
+     * }</pre>
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
+     *
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+     *     evaluateExpression(item, XPathEvaluationResult.class);
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY}
+     * type, the default implementation of this method will always throw an
+     * IllegalArgumentException. Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
+     * override this method.
+     *
+     * @param item The context the XPath expression will be evaluated in.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If the implementation of this method
+     * does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
+     *
+     * @since 1.9
+     */
+    default XPathEvaluationResult<?> evaluateExpression(Object item)
+        throws XPathExpressionException
+    {
+        return evaluateExpression(item, XPathEvaluationResult.class);
+    }
+
+    /**
+     * Evaluate the compiled XPath expression in the specified context,
+     * and return the result with the type specified through the {@code class type}
+     * <p>
+     * This method builds a data model for the {@link InputSource} and calls
+     * {@link #evaluateExpression(Object item, Class type)} on the resulting
+     * document object.
+     * <P>
+     * By default, the JDK's data model is {@link org.w3c.dom.Document}.
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+           (T)evaluate(source, XPathEvaluationResult.XPathResultType.getQNameType(type));
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
+     * XPathEvaluationResult as the type will result in IllegalArgumentException.
+     * Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
+     * this method.
+     *
+     * @param <T> The class type that will be returned by the XPath expression.
+     * @param source The {@code InputSource} of the document to evaluate over.
+     * @param type The class type expected to be returned by the XPath expression.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If {@code type} is not of the types
+     * corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
+     * XPathResultType}, or XPathEvaluationResult is specified as the type but an
+     * implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type
+     * is not available.
+     * @throws NullPointerException If {@code source or type} is {@code null}.
+     *
+     * @since 1.9
+     */
+    default <T>T evaluateExpression(InputSource source, Class<T> type)
+        throws XPathExpressionException
+    {
+        return type.cast(evaluate(source, XPathEvaluationResult.XPathResultType.getQNameType(type)));
+    }
+
+    /**
+     * Evaluate the compiled XPath expression in the specified context. This is
+     * equivalent to calling {@link #evaluateExpression(InputSource source, Class type)}
+     * with type {@link XPathEvaluationResult}:
+     * <pre> {@code
+     *     evaluateExpression(source, XPathEvaluationResult.class);
+     * }</pre>
+     * <p>
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+     *     (XPathEvaluationResult)evaluateExpression(source, XPathEvaluationResult.class);
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY}
+     * type, the default implementation of this method will always throw an
+     * IllegalArgumentException. Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
+     * override this method.
+     *
+     * @param source The {@code InputSource} of the document to evaluate over.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If the implementation of this method
+     * does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
+     * @throws NullPointerException If {@code source} is {@code null}.
+     *
+     * @since 1.9
+     */
+    default XPathEvaluationResult<?> evaluateExpression(InputSource source)
+        throws XPathExpressionException
+    {
+        return evaluateExpression(source, XPathEvaluationResult.class);
+    }
 }
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactory.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactory.java	Wed Jul 05 20:17:28 2017 +0200
@@ -117,7 +117,7 @@
     *     and returns it if it is successfully created.
     *   </li>
     *   <li>
-    *     ${java.home}/conf/jaxp.properties is read and the value associated with the key being the system property above is looked for.
+    *     ${java.home}/lib/jaxp.properties is read and the value associated with the key being the system property above is looked for.
     *     If present, the value is processed just like above.
     *   </li>
     *   <li>
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryFinder.java	Thu Jan 29 15:36:21 2015 -0800
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryFinder.java	Wed Jul 05 20:17:28 2017 +0200
@@ -176,9 +176,9 @@
 
         String javah = ss.getSystemProperty( "java.home" );
         String configFile = javah + File.separator +
-        "conf" + File.separator + "jaxp.properties";
+        "lib" + File.separator + "jaxp.properties";
 
-        // try to read from $java.home/conf/jaxp.properties
+        // try to read from $java.home/lib/jaxp.properties
         try {
             if(firstTime){
                 synchronized(cacheProps){
@@ -193,7 +193,7 @@
                 }
             }
             final String factoryClassName = cacheProps.getProperty(propertyName);
-            debugPrintln("found " + factoryClassName + " in $java.home/conf/jaxp.properties");
+            debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties");
 
             if (factoryClassName != null) {
                 xpathFactory = createInstance(factoryClassName, true);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathNodes.java	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package javax.xml.xpath;
+
+import java.util.Iterator;
+import org.w3c.dom.Node;
+
+/**
+ * XPathNodes represents a set of nodes selected by a location path as specified
+ * in <a href="http://www.w3.org/TR/xpath/#node-sets">XML Path Language (XPath)
+ * Version 1.0, 3.3 Node-sets</a>.
+ *
+ * @since 1.9
+ */
+public interface XPathNodes extends Iterable<Node> {
+
+    /**
+     * Returns an iterator of the Nodes.
+     *
+     * @return an Iterator.
+     */
+    @Override
+    public abstract Iterator<Node> iterator();
+
+    /**
+     * Returns the number of items in the result
+     *
+     * @return The number of items in the result
+     */
+    public abstract int size();
+
+    /**
+     * Returns a Node at the specified position
+     *
+     * @param index Index of the element to return.
+     * @return The Node at the specified position.
+     * @throws javax.xml.xpath.XPathException If the index is out of range
+     * (index &lt; 0 || index &gt;= size())
+     */
+    public abstract Node get(int index)
+            throws XPathException;
+}
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/package.html	Thu Jan 29 15:36:21 2015 -0800
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/package.html	Wed Jul 05 20:17:28 2017 +0200
@@ -1,6 +1,8 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
 <!--
-Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
 This code is free software; you can redistribute it and/or modify it
@@ -23,35 +25,35 @@
 or visit www.oracle.com if you need additional information or have any
 questions. 
 -->
+</head>
+<body bgcolor="white">
 
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<title>javax.xml.xpath</title>
-<meta name="@author" content="mailto:Ben@galbraiths.org" />
-<meta name="@author" content="mailto:Norman.Walsh@Sun.com" />
-<meta name="@author" content="mailto:Jeff.Suttor@Sun.com" />
-<meta name="@see" content="http://www.w3.org/TR/xpath" />
-<meta name="@since" content="1.5" />
-</head>
-
-<body>
-
-<p>This package provides an <em>object-model neutral</em> API for the
+This package provides an <em>object-model neutral</em> API for the
 evaluation of XPath expressions and access to the evaluation
 environment.
-</p>
 
-<p>The following XML standards apply:</p>
-
-<ul>
-<li><a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version 1.0</a></li>
-</ul>
+<p>
+The XPath API supports <a href="http://www.w3.org/TR/xpath">
+    XML Path Language (XPath) Version 1.0</a>
 
 <hr />
 
-<h2>XPath Overview</h2>
+<ul>
+    <li><a href='#XPath.Overview'>1. XPath Overview</a></li>
+    <li><a href='#XPath.Expressions'>2. XPath Expressions</a></li>
+    <li><a href='#XPath.Datatypes'>3. XPath Data Types</a>
+        <ul>
+            <li><a href='#XPath.Datatypes.QName'>3.1 QName Types</a>
+            <li><a href='#XPath.Datatypes.Class'>3.2 Class Types</a>
+            <li><a href='#XPath.Datatypes.Enum'>3.3 Enum Types</a>
+        </ul>    
+    </li>
+    <li><a href='#XPath.Context'>4. XPath Context</a></li>
+    <li><a href='#XPath.Use'>5. Using the XPath API</a></li>
+</ul>
+<p>
+<a name="XPath.Overview"></a>
+<h3>1. XPath Overview</h3>
 
 <p>The XPath language provides a simple, concise syntax for selecting
 nodes from an XML document. XPath also provides rules for converting a
@@ -67,7 +69,8 @@
 replace many lines of DOM API code.
 </p>
 
-<h3>XPath Expressions</h3>
+<a name="XPath.Expressions"></a>
+<h3>2. XPath Expressions</h3>
 
 <p>An XPath <em>expression</em> is composed of a <em>location
 path</em> and one or more optional <em>predicates</em>. Expressions
@@ -76,18 +79,22 @@
 
 <p>The following is an example of a simple XPath expression:</p>
 
+<blockquote>
 <pre>
 /foo/bar
 </pre>
+</blockquote>
 
 <p>This example would select the <code>&lt;bar&gt;</code> element in
 an XML document such as the following:</p>
 
+<blockquote>
 <pre>
 &lt;foo&gt;
-&lt;bar/&gt;
+    &lt;bar/&gt;
 &lt;/foo&gt;
 </pre>
+</blockquote>
 
 <p>The expression <code>/foo/bar</code> is an example of a location
 path. While XPath location paths resemble Unix-style file system
@@ -96,30 +103,36 @@
 <code>&lt;bar&gt;</code> elements in the following document would be
 selected by the <code>/foo/bar</code> expression:</p>
 
+<blockquote>
 <pre>
 &lt;foo&gt;
-&lt;bar/&gt;
-&lt;bar/&gt;
-&lt;bar/&gt;
+    &lt;bar/&gt;
+    &lt;bar/&gt;
+    &lt;bar/&gt;
 &lt;/foo&gt;
 </pre>
+</blockquote>
 
 <p>A special location path operator, <code>//</code>, selects nodes at
 any depth in an XML document. The following example selects all
 <code>&lt;bar&gt;</code> elements regardless of their location in a
 document:</p>
 
+<blockquote>
 <pre>
 //bar
 </pre>
+</blockquote>
 
 <p>A wildcard operator, *, causes all element nodes to be selected.
 The following example selects all children elements of a
-<code>&lt;foo&gt;</code> element:</p>
+<code>&lt;foo&gt;</code> element:
 
+<blockquote>
 <pre>
 /foo/*
 </pre>
+</blockquote>
 
 <p>In addition to element nodes, XPath location paths may also address
 attribute nodes, text nodes, comment nodes, and processing instruction
@@ -166,35 +179,27 @@
 <code>&lt;foo&gt;</code> elements that contain an <code>include</code>
 attribute with the value of <code>true</code>:</p>
 
+<blockquote>
 <pre>
 //foo[@include='true']
 </pre>
+</blockquote>
 
 <p>Predicates may be appended to each other to further refine an
 expression, such as:</p>
 
+<blockquote>
 <pre>
 //foo[@include='true'][@mode='bar']
 </pre>
+</blockquote>
 
-<h3>Using the XPath API</h3>
-
-<p>
-The following example demonstrates using the XPath API to select one
-or more nodes from an XML document:</p>
-
-<pre>
-XPath xpath = XPathFactory.newInstance().newXPath();
-String expression = "/widgets/widget";
-InputSource inputSource = new InputSource("widgets.xml");
-NodeList nodes = (NodeList) xpath.evaluate(expression, inputSource, XPathConstants.NODESET);
-</pre>
-
-<h3>XPath Expressions and Types</h3>
+<a name="XPath.Datatypes"></a>
+<h3>3. XPath Data Types</h3>
 
 <p>While XPath expressions select nodes in the XML document, the XPath
 API allows the selected nodes to be coalesced into one of the
-following other data types:</p>
+following data types:</p>
 
 <ul>
 <li><code>Boolean</code></li>
@@ -202,14 +207,10 @@
 <li><code>String</code></li>
 </ul>
 
-<p>The desired return type is specified by a {@link
-javax.xml.namespace.QName} parameter in method call used to evaluate
-the expression, which is either a call to
-<code>XPathExpression.evalute(...)</code> or to one of the
-<code>XPath.evaluate(...)</code> convenience methods. The allowed
-QName values are specified as constants in the {@link
-javax.xml.xpath.XPathConstants} class; they are:</p>
-
+<a name="XPath.Datatypes.QName"></a>
+<h3>3.1 QName types</h3>
+The XPath API defines the following {@link javax.xml.namespace.QName} types to 
+represent return types of an XPath evaluation:
 <ul>
 <li>{@link javax.xml.xpath.XPathConstants#NODESET}</li>
 <li>{@link javax.xml.xpath.XPathConstants#NODE}</li>
@@ -218,26 +219,71 @@
 <li>{@link javax.xml.xpath.XPathConstants#NUMBER}</li>
 </ul>
 
+<p>The return type is specified by a {@link javax.xml.namespace.QName} parameter 
+in method call used to evaluate the expression, which is either a call to
+<code>XPathExpression.evalute(...)</code> or <code>XPath.evaluate(...)</code> 
+methods. 
+
 <p>When a <code>Boolean</code> return type is requested,
 <code>Boolean.TRUE</code> is returned if one or more nodes were
-selected; otherwise, <code>Boolean.FALSE</code> is returned.</p>
+selected; otherwise, <code>Boolean.FALSE</code> is returned.
 
 <p>The <code>String</code> return type is a convenience for retrieving
 the character data from a text node, attribute node, comment node, or
 processing-instruction node. When used on an element node, the value
 of the child text nodes is returned.
-</p>
 
 <p>The <code>Number</code> return type attempts to coalesce the text
 of a node to a <code>double</code> data type.
-</p>
 
-<h3>XPath Context</h3>
+<a name="XPath.Datatypes.Class"></a>
+<h3>3.2 Class types</h3>
+In addition to the QName types, the XPath API supports the use of Class types
+through the <code>XPathExpression.evaluteExpression(...)</code> or 
+<code>XPath.evaluateExpression(...)</code> methods. 
+
+The XPath data types are mapped to Class types as follows:
+<ul>
+<li><code>Boolean</code> -- <code>Boolean.class</code></li>
+<li><code>Number</code> -- <code>Number.class</code></li>
+<li><code>String</code> -- <code>String.class</code></li>
+<li><code>Nodeset</code> -- <code>XPathNodes.class</code></li>
+<li><code>Node</code> -- <code>Node.class</code></li>
+</ul>
+
+<p>
+Of the subtypes of Number, only Double, Integer and Long are supported.
+         
+<a name="XPath.Datatypes.Enum"></a>
+<h3>3.3 Enum types</h3>
+Enum types are defined in {@link javax.xml.xpath.XPathEvaluationResult.XPathResultType} 
+that provide mappings between the QName and Class types above. The result of 
+evaluating an expression using the <code>XPathExpression.evaluteExpression(...)</code> 
+or <code>XPath.evaluateExpression(...)</code> methods will be of one of these types.
+
+<a name="XPath.Context"></a>
+<h3>4. XPath Context</h3>
 
 <p>XPath location paths may be relative to a particular node in the
-document, known as the <code>context</code>. Consider the following
-XML document:</p>
+document, known as the <code>context</code>. A context consists of:
+<ul>
+    <li>a node (the context node)</li>
+    <li>a pair of non-zero positive integers (the context position and the context size)</li>
+    <li>a set of variable bindings</li>
+    <li>a function library</li>
+    <li>the set of namespace declarations in scope for the expression</li>    
+</ul>
 
+<p>
+It is an XML document tree represented as a hierarchy of nodes, a 
+{@link org.w3c.dom.Node} for example, in the JDK implementation.
+
+<a name="XPath.Use"></a>
+<h3>5. Using the XPath API</h3>
+
+Consider the following XML document:
+<p>
+<blockquote>
 <pre>
 &lt;widgets&gt;
 &lt;widget&gt;
@@ -246,36 +292,88 @@
 &lt;/widget&gt;
 &lt;/widgets&gt;
 </pre>
+</blockquote>
 
-<p>The <code>&lt;widget&gt;</code> element can be selected with the
-following XPath API code:</p>
+<p>
+The <code>&lt;widget&gt;</code> element can be selected with the following process:
 
+<blockquote>
 <pre>
 // parse the XML as a W3C Document
 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
 Document document = builder.parse(new File("/widgets.xml"));
 
+//Get an XPath object and evaluate the expression
 XPath xpath = XPathFactory.newInstance().newXPath();
 String expression = "/widgets/widget";
 Node widgetNode = (Node) xpath.evaluate(expression, document, XPathConstants.NODE);
+
+//or using the evaluateExpression method
+Node widgetNode = xpath.evaluateExpression(expression, document, Node.class);
 </pre>
+</blockquote>
 
 <p>With a reference to the <code>&lt;widget&gt;</code> element, a
-relative XPath expression can now written to select the
+relative XPath expression can be written to select the
 <code>&lt;manufacturer&gt;</code> child element:</p>
 
+<blockquote>
 <pre>
 XPath xpath = XPathFactory.newInstance().newXPath();
 <strong>String expression = "manufacturer";</strong>
 Node manufacturerNode = (Node) xpath.evaluate(expression, <strong>widgetNode</strong>, XPathConstants.NODE);
+
+//or using the evaluateExpression method
+Node manufacturerNode = xpath.evaluateExpression(expression, <strong>widgetNode</strong>, Node.class);
 </pre>
+</blockquote>
 
-<ul>
-<li>Author <a href="mailto:Ben@galbraiths.org">Ben Galbraith</a></li>
-<li>Author <a href="mailto:Norman.Walsh@Sun.com">Norman Walsh</a></li>
-<li>Author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a></li>
-<li>See <a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version 1.0</a></li>
-<li>Since 1.5</li>
-</ul>		
+<p>
+In the above example, the XML file is read into a DOM Document before being passed
+to the XPath API. The following code demonstrates the use of InputSource to 
+leave it to the XPath implementation to process it:
+
+<blockquote>
+<pre>
+XPath xpath = XPathFactory.newInstance().newXPath();
+String expression = "/widgets/widget";
+InputSource inputSource = new InputSource("widgets.xml");
+NodeList nodes = (NodeList) xpath.evaluate(expression, inputSource, XPathConstants.NODESET);
+
+//or using the evaluateExpression method
+XPathNodes nodes = xpath.evaluate(expression, inputSource, XPathNodes.class);
+</pre>
+</blockquote>
+
+<p>
+In the above cases, the type of the expected results are known. In case where
+the result type is unknown or any type, the {@link javax.xml.xpath.XPathEvaluationResult}
+may be used to determine the return type. The following code demonstrates the usage:
+<blockquote>
+<pre>
+XPathEvaluationResult&lt;?&gt; result = xpath.evaluateExpression(expression, document);
+switch (result.type()) {
+    case NODESET:
+        XPathNodes nodes = (XPathNodes)result.value();
+        ...
+        break;
+}
+</pre>
+</blockquote>
+
+<p>
+The XPath 1.0 Number data type is defined as a double. However, the XPath 
+specification also provides functions that returns Integer type. To facilitate
+such operations, the XPath API allows Integer and Long to be used in 
+{@code evaluateExpression} method such as the following code: 
+<p>
+<blockquote>
+<pre>
+int count = xpath.evaluate("count(/widgets/widget)", document, Integer.class);
+</pre>
+</blockquote>
+
+@since 1.5
+
 </body>
 </html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/validation/ptests/SchemaFactoryTest.java	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+package javax.xml.validation.ptests;
+
+import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
+import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertSame;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.SAXParseException;
+
+/*
+ * @summary Class containing the test cases for SchemaFactory
+ */
+@Test(singleThreaded = true)
+public class SchemaFactoryTest {
+
+    @BeforeClass
+    public void setup() throws SAXException, IOException, ParserConfigurationException {
+        sf = newSchemaFactory();
+
+        assertNotNull(sf);
+
+        xsd1 = Files.readAllBytes(Paths.get(XML_DIR + "test.xsd"));
+        xsd2 = Files.readAllBytes(Paths.get(XML_DIR + "test1.xsd"));
+
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        dbf.setNamespaceAware(true);
+        DocumentBuilder db = dbf.newDocumentBuilder();
+        xsdDoc1 = db.parse(newInputStream(xsd1));
+        xsdDoc2 = db.parse(newInputStream(xsd2));
+
+        xml = Files.readAllBytes(Paths.get(XML_DIR + "test.xml"));
+    }
+
+    @Test(expectedExceptions = SAXParseException.class)
+    public void testNewSchemaDefault() throws SAXException, IOException {
+        validate(sf.newSchema());
+    }
+
+    @Test
+    public void testNewSchemaWithFile() throws SAXException, IOException {
+        validate(sf.newSchema(new File(XML_DIR + "test.xsd")));
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testNewSchemaWithNullFile() throws SAXException {
+        sf.newSchema((File) null);
+    }
+
+    @DataProvider(name = "valid-source")
+    public Object[][] getValidSource() {
+        return new Object[][] {
+                { streamSource(xsd1) },
+                { saxSource(xsd1) },
+                { domSource(xsdDoc1) } };
+
+    }
+
+    @Test(dataProvider = "valid-source")
+    public void testNewSchemaWithValidSource(Source schema) throws SAXException, IOException {
+        validate(sf.newSchema(schema));
+    }
+
+    @DataProvider(name = "invalid-source")
+    public Object[][] getInvalidSource() {
+        return new Object[][] {
+                { nullStreamSource() },
+                { nullSaxSource() } };
+    }
+
+    @Test(dataProvider = "invalid-source", expectedExceptions = SAXParseException.class)
+    public void testNewSchemaWithInvalidSource(Source schema) throws SAXException {
+        sf.newSchema(schema);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testNewSchemaWithNullSource() throws SAXException {
+        sf.newSchema((Source)null);
+    }
+
+    @DataProvider(name = "valid-sources")
+    public Object[][] getValidSources() {
+        return new Object[][] {
+                { streamSource(xsd1), streamSource(xsd2) },
+                { saxSource(xsd1), saxSource(xsd2) },
+                { domSource(xsdDoc1), domSource(xsdDoc2) } };
+
+    }
+
+    @Test(dataProvider = "valid-sources")
+    public void testNewSchemaWithValidSourceArray(Source schema1, Source schema2) throws SAXException, IOException {
+        validate(sf.newSchema(new Source[] { schema1, schema2 }));
+    }
+
+    @DataProvider(name = "invalid-sources")
+    public Object[][] getInvalidSources() {
+        return new Object[][] {
+                { streamSource(xsd1), nullStreamSource() },
+                { nullStreamSource(), nullStreamSource() },
+                { saxSource(xsd1), nullSaxSource() },
+                { nullSaxSource(), nullSaxSource() } };
+    }
+
+    @Test(dataProvider = "invalid-sources", expectedExceptions = SAXParseException.class)
+    public void testNewSchemaWithInvalidSourceArray(Source schema1, Source schema2) throws SAXException {
+        sf.newSchema(new Source[] { schema1, schema2 });
+    }
+
+    @DataProvider(name = "null-sources")
+    public Object[][] getNullSources() {
+        return new Object[][] {
+                { new Source[] { domSource(xsdDoc1), null } },
+                { new Source[] { null, null } },
+                { null } };
+
+    }
+
+    @Test(dataProvider = "null-sources", expectedExceptions = NullPointerException.class)
+    public void testNewSchemaWithNullSourceArray(Source[] schemas) throws SAXException {
+        sf.newSchema(schemas);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testNewSchemaWithNullUrl() throws SAXException {
+        sf.newSchema((URL) null);
+    }
+
+
+    @Test
+    public void testErrorHandler() {
+        SchemaFactory sf = newSchemaFactory();
+        assertNull(sf.getErrorHandler(), "When SchemaFactory is created, initially ErrorHandler should not be set.");
+
+        ErrorHandler handler = new MyErrorHandler();
+        sf.setErrorHandler(handler);
+        assertSame(sf.getErrorHandler(), handler);
+
+        sf.setErrorHandler(null);
+        assertNull(sf.getErrorHandler());
+    }
+
+    @Test(expectedExceptions = SAXNotRecognizedException.class)
+    public void testGetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
+        SchemaFactory sf = newSchemaFactory();
+        sf.getProperty(UNRECOGNIZED_NAME);
+
+    }
+
+    @Test(expectedExceptions = SAXNotRecognizedException.class)
+    public void testSetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
+        SchemaFactory sf = newSchemaFactory();
+        sf.setProperty(UNRECOGNIZED_NAME, "test");
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testGetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
+        SchemaFactory sf = newSchemaFactory();
+        assertNotNull(sf);
+        sf.getProperty(null);
+
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testSetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
+        SchemaFactory sf = newSchemaFactory();
+        assertNotNull(sf);
+        sf.setProperty(null, "test");
+    }
+
+    @Test(expectedExceptions = SAXNotRecognizedException.class)
+    public void testGetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
+        SchemaFactory sf = newSchemaFactory();
+        sf.getFeature(UNRECOGNIZED_NAME);
+
+    }
+
+    @Test(expectedExceptions = SAXNotRecognizedException.class)
+    public void testSetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
+        SchemaFactory sf = newSchemaFactory();
+        sf.setFeature(UNRECOGNIZED_NAME, true);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testGetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
+        SchemaFactory sf = newSchemaFactory();
+        assertNotNull(sf);
+        sf.getFeature(null);
+
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testSetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
+        SchemaFactory sf = newSchemaFactory();
+        assertNotNull(sf);
+        sf.setFeature(null, true);
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testInvalidSchemaLanguage() {
+        final String INVALID_SCHEMA_LANGUAGE = "http://relaxng.org/ns/structure/1.0";
+        SchemaFactory.newInstance(INVALID_SCHEMA_LANGUAGE);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testNullSchemaLanguage() {
+        SchemaFactory.newInstance(null);
+    }
+
+    private void validate(Schema schema) throws SAXException, IOException {
+        schema.newValidator().validate(new StreamSource(new ByteArrayInputStream(xml)));
+    }
+    private InputStream newInputStream(byte[] xsd) {
+        return new ByteArrayInputStream(xsd);
+    }
+
+    private Source streamSource(byte[] xsd) {
+        return new StreamSource(newInputStream(xsd));
+    }
+
+    private Source nullStreamSource() {
+        return new StreamSource((InputStream) null);
+    }
+
+    private Source saxSource(byte[] xsd) {
+        return new SAXSource(new InputSource(newInputStream(xsd)));
+    }
+
+    private Source nullSaxSource() {
+        return new SAXSource(new InputSource((InputStream) null));
+    }
+
+    private Source domSource(Document xsdDoc) {
+        return new DOMSource(xsdDoc);
+    }
+
+    private SchemaFactory newSchemaFactory() {
+        return SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
+    }
+
+    private static final String UNRECOGNIZED_NAME = "http://xml.org/sax/features/namespace-prefixes";
+
+    private SchemaFactory sf;
+    private byte[] xsd1;
+    private byte[] xsd2;
+    private Document xsdDoc1;
+    private Document xsdDoc2;
+    private byte[] xml;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/validation/ptests/TypeInfoProviderTest.java	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+package javax.xml.validation.ptests;
+
+import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
+import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
+import static jaxp.library.JAXPTestUtilities.filenameToURL;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.TypeInfoProvider;
+import javax.xml.validation.ValidatorHandler;
+
+import jaxp.library.JAXPFileBaseTest;
+
+import org.testng.annotations.Test;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+/*
+ * @summary test ValidatorHandler.getTypeInfoProvider()
+ */
+public class TypeInfoProviderTest extends JAXPFileBaseTest {
+
+    private ValidatorHandler validatorHandler;
+
+    @Test
+    public void test() throws SAXException, ParserConfigurationException, IOException {
+
+        SchemaFactory sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
+        Schema schema = sf.newSchema(new File(XML_DIR + "shiporder11.xsd"));
+        validatorHandler = schema.newValidatorHandler();
+        MyDefaultHandler myDefaultHandler = new MyDefaultHandler();
+        validatorHandler.setContentHandler(myDefaultHandler);
+
+        InputSource is = new InputSource(filenameToURL(XML_DIR + "shiporder11.xml"));
+
+        SAXParserFactory parserFactory = SAXParserFactory.newInstance();
+        parserFactory.setNamespaceAware(true);
+        XMLReader xmlReader = parserFactory.newSAXParser().getXMLReader();
+        xmlReader.setContentHandler(validatorHandler);
+        xmlReader.parse(is);
+
+    }
+
+    private class MyDefaultHandler extends DefaultHandler {
+
+        public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
+            TypeInfoProvider typeInfoProvider = validatorHandler.getTypeInfoProvider();
+            int index = atts.getIndex("orderid");
+            if (index != -1) {
+                System.out.println(" Index " + index);
+                System.out.println(" ElementType " + typeInfoProvider.getElementTypeInfo().getTypeName());
+                assertEquals(typeInfoProvider.getAttributeTypeInfo(index).getTypeName(), "string");
+                assertTrue(typeInfoProvider.isSpecified(index));
+                assertFalse(typeInfoProvider.isIdAttribute(index));
+            }
+
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/validation/ptests/ValidatorHandlerTest.java	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+package javax.xml.validation.ptests;
+
+import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
+import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.ValidatorHandler;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/*
+ * @summary Class containing the test cases for ValidatorHandler API
+ */
+public class ValidatorHandlerTest {
+    @BeforeClass
+    public void setup() throws SAXException {
+        schema = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI).newSchema(new File(XML_DIR + "test.xsd"));
+
+        assertNotNull(schema);
+    }
+
+    @Test
+    public void testErrorHandler() {
+        ValidatorHandler validatorHandler = getValidatorHandler();
+        assertNull(validatorHandler.getErrorHandler(), "When ValidatorHandler is created, initially ErrorHandler should not be set.");
+
+        ErrorHandler handler = new MyErrorHandler();
+        validatorHandler.setErrorHandler(handler);
+        assertSame(validatorHandler.getErrorHandler(), handler);
+
+    }
+
+    @Test(expectedExceptions = SAXNotRecognizedException.class)
+    public void testGetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
+        ValidatorHandler validatorHandler = getValidatorHandler();
+        validatorHandler.getProperty(FEATURE_NAME);
+
+    }
+
+    @Test(expectedExceptions = SAXNotRecognizedException.class)
+    public void testSetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
+        ValidatorHandler validatorHandler = getValidatorHandler();
+        validatorHandler.setProperty(FEATURE_NAME, "test");
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testGetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
+        ValidatorHandler validatorHandler = getValidatorHandler();
+        assertNotNull(validatorHandler);
+        validatorHandler.getProperty(null);
+
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testSetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
+        ValidatorHandler validatorHandler = getValidatorHandler();
+        assertNotNull(validatorHandler);
+        validatorHandler.setProperty(null, "test");
+    }
+
+    public void testFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
+        ValidatorHandler validatorHandler = getValidatorHandler();
+        assertFalse(validatorHandler.getFeature(FEATURE_NAME), "The feature should be false by default.");
+
+        validatorHandler.setFeature(FEATURE_NAME, true);
+        assertTrue(validatorHandler.getFeature(FEATURE_NAME), "The feature should be false by default.");
+
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testGetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
+        ValidatorHandler validatorHandler = getValidatorHandler();
+        assertNotNull(validatorHandler);
+        validatorHandler.getFeature(null);
+
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testSetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
+        ValidatorHandler validatorHandler = getValidatorHandler();
+        assertNotNull(validatorHandler);
+        validatorHandler.setFeature(null, true);
+    }
+
+    @Test
+    public void testContentHandler() {
+        ValidatorHandler validatorHandler = getValidatorHandler();
+        assertNull(validatorHandler.getContentHandler(), "When ValidatorHandler is created, initially ContentHandler should not be set.");
+
+        ContentHandler handler = new DefaultHandler();
+        validatorHandler.setContentHandler(handler);
+        assertSame(validatorHandler.getContentHandler(), handler);
+
+        validatorHandler.setContentHandler(null);
+        assertNull(validatorHandler.getContentHandler());
+
+    }
+
+    private ValidatorHandler getValidatorHandler() {
+        return schema.newValidatorHandler();
+    }
+
+    private static final String FEATURE_NAME = "http://xml.org/sax/features/namespace-prefixes";
+
+    private Schema schema;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/validation/ptests/ValidatorTest.java	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+package javax.xml.validation.ptests;
+
+import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
+import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
+import static jaxp.library.JAXPTestUtilities.filenameToURL;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertSame;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import jaxp.library.JAXPFileBaseTest;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/*
+ * @summary Class containing the test cases for Validator API
+ */
+public class ValidatorTest extends JAXPFileBaseTest {
+
+    @BeforeClass
+    public void setup() throws SAXException, IOException, ParserConfigurationException {
+        schema = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI).newSchema(new File(XML_DIR + "test.xsd"));
+
+        assertNotNull(schema);
+
+        xmlFileUri = filenameToURL(XML_DIR + "test.xml");
+
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        dbf.setNamespaceAware(true);
+        xmlDoc = dbf.newDocumentBuilder().parse(xmlFileUri);
+    }
+
+    @Test
+    public void testValidateStreamSource() throws SAXException, IOException {
+        Validator validator = getValidator();
+        validator.setErrorHandler(new MyErrorHandler());
+        validator.validate(getStreamSource());
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testValidateNullSource() throws SAXException, IOException {
+        Validator validator = getValidator();
+        assertNotNull(validator);
+        validator.validate(null);
+    }
+
+    @Test
+    public void testErrorHandler() {
+        Validator validator = getValidator();
+        assertNull(validator.getErrorHandler(), "When Validator is created, initially ErrorHandler should not be set.");
+
+        ErrorHandler mh = new MyErrorHandler();
+        validator.setErrorHandler(mh);
+        assertSame(validator.getErrorHandler(), mh);
+
+    }
+
+    @DataProvider(name = "source-result")
+    public Object[][] getSourceAndResult() {
+        return new Object[][] {
+                { getStreamSource(), null },
+                { getSAXSource(), getSAXResult() },
+                { getDOMSource(), getDOMResult() },
+                { getSAXSource(), null },
+                { getDOMSource(), null } };
+    }
+
+    @Test(dataProvider = "source-result")
+    public void testValidateWithResult(Source source, Result result) throws SAXException, IOException {
+        Validator validator = getValidator();
+        validator.validate(source, result);
+    }
+
+    @Test(expectedExceptions = SAXNotRecognizedException.class)
+    public void testGetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
+        Validator validator = getValidator();
+        validator.getProperty(UNRECOGNIZED_NAME);
+
+    }
+
+    @Test(expectedExceptions = SAXNotRecognizedException.class)
+    public void testSetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
+        Validator validator = getValidator();
+        validator.setProperty(UNRECOGNIZED_NAME, "test");
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testGetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
+        Validator validator = getValidator();
+        assertNotNull(validator);
+        validator.getProperty(null);
+
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testSetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
+        Validator validator = getValidator();
+        assertNotNull(validator);
+        validator.setProperty(null, "test");
+    }
+
+    @Test(expectedExceptions = SAXNotRecognizedException.class)
+    public void testGetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
+        Validator validator = getValidator();
+        validator.getFeature(UNRECOGNIZED_NAME);
+
+    }
+
+    @Test(expectedExceptions = SAXNotRecognizedException.class)
+    public void testSetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
+        Validator validator = getValidator();
+        validator.setFeature(UNRECOGNIZED_NAME, true);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testGetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
+        Validator validator = getValidator();
+        assertNotNull(validator);
+        validator.getFeature(null);
+
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testSetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
+        Validator validator = getValidator();
+        assertNotNull(validator);
+        validator.setFeature(null, true);
+    }
+
+    private Validator getValidator() {
+        return schema.newValidator();
+    }
+
+    private Source getStreamSource() {
+        return new StreamSource(xmlFileUri);
+    }
+
+    private Source getSAXSource() {
+        return new SAXSource(new InputSource(xmlFileUri));
+    }
+
+    private Result getSAXResult() {
+        SAXResult saxResult = new SAXResult();
+        saxResult.setHandler(new DefaultHandler());
+        return saxResult;
+    }
+
+    private Source getDOMSource() {
+        return new DOMSource(xmlDoc);
+    }
+
+    private Result getDOMResult() {
+        return new DOMResult();
+    }
+
+    private static final String UNRECOGNIZED_NAME = "http://xml.org/sax/features/namespace-prefixes";
+    private String xmlFileUri;
+    private Schema schema;
+    private Document xmlDoc;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/validation/xmlfiles/shiporder11.xml	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<shiporder orderid="889923"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:noNamespaceSchemaLocation="shiporder.xsd">
+<orderperson>John Smith</orderperson>
+<shipto>
+<name>Ola Nordmann</name>
+<address>Langgt 23</address>
+<city>4000 Stavanger</city>
+<country>Norway</country>
+</shipto>
+<item>
+<title>Empire Burlesque</title>
+<note>Special Edition</note>
+<quantity>1</quantity>
+<price>10.90</price>
+</item>
+<item>
+<title>Hide your heart</title>
+<quantity>1</quantity>
+<price>9.90</price>
+</item>
+</shiporder>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/validation/xmlfiles/shiporder11.xsd	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+<!-- definition of simple elements -->
+<xs:element name="orderperson" type="xs:string"/>
+<xs:element name="name" type="xs:string"/>
+<xs:element name="address" type="xs:string"/>
+<xs:element name="city" type="xs:string"/>
+<xs:element name="country" type="xs:string"/>
+<xs:element name="title" type="xs:string"/>
+<xs:element name="note" type="xs:string"/>
+<xs:element name="quantity" type="xs:positiveInteger"/>
+<xs:element name="price" type="xs:decimal"/>
+
+<!-- definition of attributes -->
+<xs:attribute name="orderid" type="xs:string"/>
+
+<!-- definition of complex elements -->
+<xs:element name="shipto">
+<xs:complexType>
+<xs:sequence>
+<xs:element ref="name"/>
+<xs:element ref="address"/>
+<xs:element ref="city"/>
+<xs:element ref="country"/>
+</xs:sequence>
+</xs:complexType>
+</xs:element>
+<xs:element name="item">
+<xs:complexType>
+<xs:sequence>
+<xs:element ref="title"/>
+<xs:element ref="note" minOccurs="0"/>
+<xs:element ref="quantity"/>
+<xs:element ref="price"/>
+</xs:sequence>
+</xs:complexType>
+</xs:element>
+
+<xs:element name="shiporder">
+<xs:complexType>
+<xs:sequence>
+<xs:element ref="orderperson"/>
+<xs:element ref="shipto"/>
+<xs:element ref="item" maxOccurs="unbounded"/>
+</xs:sequence>
+<xs:attribute ref="orderid" use="required"/>
+</xs:complexType>
+</xs:element>
+
+</xs:schema>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/validation/xmlfiles/shiporder12.xml	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<shiporder orderid="889923"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:noNamespaceSchemaLocation="shiporder.xsd">
+<orderperson>John Smith</orderperson>
+<shipto>
+<name>Ola Nordmann</name>
+<address>Langgt 23</address>
+<city>4000 Stavanger</city>
+<country>Norway</country>
+</shipto>
+<item>
+<title>Empire Burlesque</title>
+<note>Special Edition</note>
+<quantity>1</quantity>
+<price>10.90</price>
+</item>
+<item>
+<title>Hide your heart</title>
+<quantity>1</quantity>
+<price>9.90</price>
+</item>
+</shiporder>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/validation/xmlfiles/shiporder12.xsd	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+<!-- definition of simple elements -->
+<xs:element name="orderperson" type="xs:string"/>
+<xs:element name="name" type="xs:string"/>
+<xs:element name="address" type="xs:string"/>
+<xs:element name="city" type="xs:string"/>
+<xs:element name="country" type="xs:string"/>
+<xs:element name="title" type="xs:string"/>
+<xs:element name="note" type="xs:string"/>
+<xs:element name="quantity" type="xs:positiveInteger"/>
+<xs:element name="price" type="xs:decimal"/>
+
+<!-- definition of attributes -->
+<xs:attribute name="orderid" type="xs:string"/>
+
+<!-- definition of complex elements -->
+<xs:element name="shipto">
+<xs:complexType>
+<xs:sequence>
+<xs:element ref="name"/>
+<xs:element ref="address"/>
+<xs:element ref="city"/>
+<xs:element ref="country"/>
+</xs:sequence>
+</xs:complexType>
+</xs:element>
+<xs:element name="item">
+<xs:complexType>
+<xs:sequence>
+<xs:element ref="title"/>
+<xs:element ref="note" minOccurs="0"/>
+<xs:element ref="quantity"/>
+<xs:element ref="price"/>
+</xs:sequence>
+</xs:complexType>
+</xs:element>
+
+<xs:element name="shiporder">
+<xs:complexType>
+<xs:sequence>
+<xs:element ref="orderperson"/>
+<xs:element ref="shipto"/>
+<xs:element ref="item" maxOccurs="unbounded"/>
+</xs:sequence>
+<xs:attribute ref="orderid" use="required"/>
+</xs:complexType>
+</xs:element>
+
+</xs:schema>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/validation/xmlfiles/test.xml	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+ <contact xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd">
+<name> John </name>
+<phone>444-121-3434</phone>
+</contact>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/validation/xmlfiles/test.xsd	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<xs:element name="contact">
+<xs:complexType>
+<xs:sequence>
+  <xs:element name="name" type="xs:string"/>
+  <xs:element name="phone" type="xs:string"/>
+</xs:sequence>
+</xs:complexType>
+</xs:element>
+</xs:schema>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/validation/xmlfiles/test1.xsd	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<xs:element name="address">
+<xs:complexType>
+<xs:sequence>
+  <xs:element name="street" type="xs:string"/>
+  <xs:element name="city" type="xs:string"/>
+</xs:sequence>
+</xs:complexType>
+</xs:element>
+</xs:schema>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/test/gaptest/Bug4511326.java	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+package test.gaptest;
+
+import java.io.StringReader;
+
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamSource;
+
+import jaxp.library.JAXPBaseTest;
+
+import org.testng.annotations.Test;
+
+/*
+ * @bug 4511326
+ * @summary In forwards-compatible mode the attribute isn't ignored
+ */
+
+public class Bug4511326 extends JAXPBaseTest {
+
+    private static final String XSL = "<xsl:stylesheet version='2.0' "
+                               + "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>"
+                               + "<xsl:template a='1' match='/'>"
+                               + "<H2><xsl:value-of select='//author'/></H2>"
+                               + "<H1><xsl:value-of select='//title'/></H1>"
+                               + "</xsl:template>"
+                               + "</xsl:stylesheet>";
+
+
+    @Test
+    public void ignoreAttTest() throws TransformerConfigurationException {
+        /* Create a TransformFactory instance */
+        TransformerFactory transformerFactory = TransformerFactory.newInstance();
+
+        /* Create and init a StreamSource instance */
+        StreamSource source = new StreamSource(new StringReader(XSL));
+
+        transformerFactory.newTransformer(source);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/test/gaptest/Bug4512806.java	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+package test.gaptest;
+
+import static javax.xml.transform.OutputKeys.ENCODING;
+import static javax.xml.transform.OutputKeys.INDENT;
+import static org.testng.Assert.assertEquals;
+
+import java.io.StringReader;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamSource;
+
+import jaxp.library.JAXPBaseTest;
+
+import org.testng.annotations.Test;
+
+/*
+ * @bug 4512806
+ * @summary test transformer.setOutputProperties(null)
+ */
+public class Bug4512806 extends JAXPBaseTest {
+
+    @Test
+    public void testProperty() throws TransformerConfigurationException {
+        /* Create a transform factory instance */
+        TransformerFactory tfactory = TransformerFactory.newInstance();
+
+        /* Create a StreamSource instance */
+        StreamSource streamSource = new StreamSource(new StringReader(xslData));
+
+        transformer = tfactory.newTransformer(streamSource);
+        transformer.setOutputProperty(INDENT, "no");
+        transformer.setOutputProperty(ENCODING, "UTF-16");
+
+        assertEquals(printPropertyValue(INDENT), "indent=no");
+        assertEquals(printPropertyValue(ENCODING), "encoding=UTF-16");
+
+        transformer.setOutputProperties(null);
+
+        assertEquals(printPropertyValue(INDENT), "indent=yes");
+        assertEquals(printPropertyValue(ENCODING), "encoding=UTF-8");
+
+    }
+
+    private String printPropertyValue(String name) {
+        return name + "=" + transformer.getOutputProperty(name);
+    }
+
+    private Transformer transformer;
+
+    private static final String xslData = "<?xml version='1.0'?>"
+            + "<xsl:stylesheet"
+            + " version='1.0'"
+            + " xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
+            + ">\n"
+            + "   <xsl:output method='xml' indent='yes'"
+            + " encoding='UTF-8'/>\n"
+            + "   <xsl:template match='/'>\n"
+            + "     Hello World! \n"
+            + "   </xsl:template>\n"
+            + "</xsl:stylesheet>";
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/test/gaptest/Bug4515047.java	Wed Jul 05 20:17:28 2017 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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